Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove E_STRICT notice in mysqli extension #4406

Closed
wants to merge 4 commits into from

Conversation

Girgias
Copy link
Member

@Girgias Girgias commented Jul 14, 2019

Split mysqli error conversion from #4401

@Girgias Girgias changed the base branch from master to PHP-7.4 July 14, 2019 19:32
@nikic
Copy link
Member

nikic commented Jul 15, 2019

I'm not sure on this one. I feel it might make more sense to drop the E_STRICT instead. Basically it tries to force you to write

for (; $mysqli->more_results(); $mysqli->next_result()) {
    // ...
}

instead of

do {
    // ...
} while ($mysqli->next_result());

But probably there's a reason why the former version is recommended (something about error handling?), maybe someone with MySQL familiarity can comment. @johannes?

@nikic nikic added the Feature label Jul 15, 2019
@johannes
Copy link
Member

I believe that is consequence of the original developer staying close to C patterns instead of going for PHP patterns.

I am not sure what state the result is in after next_result failed. Whether it still refers to the last result set or is in some form of invalid state.

@Girgias
Copy link
Member Author

Girgias commented Jul 15, 2019

So I'm a bit confused about this code tbh, I've had a look around it trying to understand it but it seems this section calls the mysqlnd driver. I would have thought that the mysqli and mysqlnd extensions/drivers operate independently and that one can use mysqlnd without having mysqli is this the case?

It is true that the E_STRICT notice should probably be dropped. I'm going to commit/push that change and see if it breaks anything on CI.

@cmb69
Copy link
Contributor

cmb69 commented Jul 15, 2019

@Girgias, ext/mysqli works either with the mysqlnd driver, or with libmysqlclient.

@johannes
Copy link
Member

mysqlnd is the "library" providing a C API for other PHP extensions for handling MySQL protocol.

mysqli, pdo_mysql and historically ext/mysql are built on top of it and provide user facing APIs. mysqlnd is built as PHP extension to ease management, while itself it doesn't provide any APIs to PHP users (well, some ini settings etc. but nothing fundamental)

See https://www.php.net/manual/en/mysql.php which has some more details.

Feel free to ping my outside this discussion for question (same username as here @ php.net, just to stay in topic within this item)

@johannes
Copy link
Member

If you drop it, would be good to check what happens if you call result APIs after next_result returned false.

Something like

$m->multi_query("SELECT 1"); // returns only one result set
$m->next_result(); // should return false
$m->store_result(); // now what happens here!?
$m->fetch_assoc(); // and here!?

I am not sure what to expect, I think all those later operations should fail gracefully ... They shouldn't return the first result set. On the other hand if they for whatever reason return the first result set it might be good to enforce the has_more check to prevent bad mistakes (or we have to look for a way to catch that)

(Untested and typed on mobile ...)

@Girgias
Copy link
Member Author

Girgias commented Jul 15, 2019

Thanks for the explanations :)

Will add a test to see if it fails gracefully or not and will report back.

@Girgias
Copy link
Member Author

Girgias commented Jul 15, 2019

Okay added a test, this should work.

I couldn't use fetch_assoc() as this works on a mysli_result class which is provided by mysqli::use_result(), I don't think these functions need to be tested on the result but can always do if it seems necessary.

@Girgias
Copy link
Member Author

Girgias commented Jul 16, 2019

@johannes is the added test sufficient or should I do something more specialised?

@nikic
Copy link
Member

nikic commented Jul 18, 2019

For reference, this is the usage example from the MySQL docs: https://dev.mysql.com/doc/refman/8.0/en/c-api-multiple-queries.html They use a do/while loop on mysql_next_result.

@nikic
Copy link
Member

nikic commented Jul 18, 2019

Looking at the results on your added tests, it seems like @johannes conjecture was right and the first result set is returned, instead of subsequent result set operations failing.

@johannes
Copy link
Member

Now the question is: Is that ok?

The easy answer is "yes, if you ignore the return code it's your fault" as long as it doesn't crash we are fine.

Another answer might be "no, all subsequent result operations should fail"

I'm not sure.

@Girgias
Copy link
Member Author

Girgias commented Jul 18, 2019

Now the question is: Is that ok?

The easy answer is "yes, if you ignore the return code it's your fault" as long as it doesn't crash we are fine.

Another answer might be "no, all subsequent result operations should fail"

I'm not sure.

I mean it was always possible to do that if you ignored the E_STRICT warning so I would say leaving it as if would be the better option. I don't know if this should be changed in PHP 8? So should I replace that by a deprecated notice?

@johannes
Copy link
Member

The difference is: The "old" suggestion is "check using has_more and then switch using next_result without having to check the return value" and now we are going to tell users "use next_result only".

The question is what the livelihood of errors is. i.e. if users issue a CALL to a stored procedure and they misinterpret the result ... will the (slightly) nicer code bring more benefits or will this cause more bugs. I tend to "most ignore E_STRICT anyways, so improvement wins" but I want to everybody to think about it for a moment.

@cmb69
Copy link
Contributor

cmb69 commented Jul 18, 2019

will the (slightly) nicer code bring more benefits or will this cause more bugs

It seems to me that do {} while ($mysqli->more_results() && $mysqli->next_result()) and do {} while ($mysqli->next_result()) produce identical results, so the additional check wouldn't have any benefits. (@nikic's for loop is bogus, since it would skip the last result set.) However, $mysqli->more_results() does not necessarily imply $mysqli->next_result() succeeds, which could be utilized to avoid checking $mysqli->errno.

Anyhow, would the code work the same with libmysqlclient?

@nikic
Copy link
Member

nikic commented Jul 18, 2019

@cmb69 Uh yeah sorry, my code doesn't make sense.

I think in the end the two relevant use cases here are a) you are reading results in a loop, in which case just using next_result() would be preferable and the warning should go away or b) you are reading a specific (known) number of result sets without checking the next_result return value, in which case the warning might help you realize your mistake.

@cmb69
Copy link
Contributor

cmb69 commented Jul 19, 2019

you are reading a specific (known) number of result sets without checking the next_result return value, in which case the warning might help you realize your mistake.

Consider the following:

$conn->multi_query("SELECT 1;SELECT * FROM missing_table");
var_dump($conn->next_result());
var_dump($res = $conn->store_result());
var_dump($res->fetch_array());

This fetches the result of the first query without any warning/notice. I don't think the internal more_results() check triggering a warning/notice is actually that helpful, since users need to check the return value of ::next_result() anyway.

Anyhow, would the code work the same with libmysqlclient?

yes

@Girgias Girgias force-pushed the mysqli-e-strict-conversion branch from bf92341 to 3067187 Compare July 19, 2019 13:05
@Girgias
Copy link
Member Author

Girgias commented Aug 6, 2019

@johannes @cmb69 @nikic is it possible to land this? Or are still some open issues/question that may need to be resolved?

@Girgias Girgias changed the title Convert E_STRICT into E_NOTICE in mysqli extension Remvoe E_STRICT notice in mysqli extension Aug 26, 2019
@Girgias Girgias changed the title Remvoe E_STRICT notice in mysqli extension Remove E_STRICT notice in mysqli extension Aug 26, 2019
Copy link
Member

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consensus seems to be on dropping the E_STRICT notice, so let's do it.

@Girgias
Copy link
Member Author

Girgias commented Aug 31, 2019

Merged in as e895e96

@Girgias Girgias closed this Aug 31, 2019
@Girgias Girgias deleted the mysqli-e-strict-conversion branch August 31, 2019 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants