Skip to content

Remove E_STRICT notice in mysqli extension - #4406

Closed
Girgias wants to merge 4 commits into
php:PHP-7.4from
Girgias:mysqli-e-strict-conversion
Closed

Remove E_STRICT notice in mysqli extension#4406
Girgias wants to merge 4 commits into
php:PHP-7.4from
Girgias:mysqli-e-strict-conversion

Conversation

@Girgias

Copy link
Copy Markdown
Member

Split mysqli error conversion from #4401

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

Copy link
Copy Markdown
Member

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?

@johannes

Copy link
Copy Markdown
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.

@GirgiasGirgias mentioned this pull request Jul 15, 2019
@Girgias

Copy link
Copy Markdown
MemberAuthor

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
Copy Markdown
Member

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

@johannes

Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
MemberAuthor

Thanks for the explanations :)

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

@Girgias

Copy link
Copy Markdown
MemberAuthor

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
Copy Markdown
MemberAuthor

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

@nikic

Copy link
Copy Markdown
Member

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.

Comment threadext/mysqli/tests/mysqli_multi_query.phpt Outdated
@nikic

Copy link
Copy Markdown
Member

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
Copy Markdown
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
Copy Markdown
MemberAuthor

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
Copy Markdown
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
Copy Markdown
Member

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
Copy Markdown
Member

@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
Copy Markdown
Member

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
Girgiasforce-pushed the mysqli-e-strict-conversion branch from bf92341 to 3067187CompareJuly 19, 2019 13:05
@Girgias

Copy link
Copy Markdown
MemberAuthor

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

@GirgiasGirgias changed the title Convert E_STRICT into E_NOTICE in mysqli extensionRemvoe E_STRICT notice in mysqli extensionAug 26, 2019
@GirgiasGirgias changed the title Remvoe E_STRICT notice in mysqli extensionRemove E_STRICT notice in mysqli extensionAug 26, 2019

@nikicnikic left a comment

Copy link
Copy Markdown
Member

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
Copy Markdown
MemberAuthor

Merged in as e895e96

@GirgiasGirgias closed this Aug 31, 2019
@Girgias
Girgias deleted the mysqli-e-strict-conversion branch August 31, 2019 21:18
Sign up for freeto 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.

4 participants

@Girgias@nikic@johannes@cmb69