Hi,

I just wanted to get a fresh drupal head running with mysqli and encountered varoious problems:

- During the connection attempt if(!$connection) is checked to test for success. This is useless because $connection will exist (from mysqli_init) and thus this error will never get reported!
- The database is changed even though the constructor already selects the correct db.
- The host:port synax is used even though mysqli_real_connect has a parameter for that and will not work backwards compatible.

Those are easy, and I tried to fix with my best knowledge. Now the tricky part:

- The register_shutdown_function attempt to make session data be written before the mysql object is destroyed does not work (for me, php 5.0.5). I do not know why this does not work, maybe it is because mysqli has its own shutdown functions that are called before the custom shutdown functions. See [1] for easy reprocedure.

As mentioned in the documentation the way out of the chicken/hen problem are destructors. Because it is tricky to extend mysqli and then use mysqi_init / mysqli_real_connect I have attempted to fix this using a dummy object.

I have crafted a patch that fixes all those issues for me. I have tested the patch and it seems to work fine for me.

[1] http://bugs.php.net/bug.php?id=34377

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Dries’s picture

Not sure about the dummy object -- sure there isn't an alternative fix. The register_shutdown_function() solution seems more elagant.

Can somone confirm these problems and the proposed solution?

The code for the dummy class seems to be using tabs.

markus_petrux’s picture

You might want to read this comment on the PHP manual. It seems safer to explicitly call session_write_close() at the end of the script, which is, btw, also needed to preserve modified session variables when using header('Location: ...').

Thomas Ilsche’s picture

FileSize
3.81 KB

> Not sure about the dummy object -- sure there isn't an alternative fix. The register_shutdown_function() solution seems more elagant.

While register_shutdown_function() is really more elegant it does not work for php 5.0.5 (it does for 5.1.2). The reason seems to me that php is changing their shutdown behaviour from version to version, see main.c / void php_request_shutdown in the php cvs. The safest solution is calling session_write_close() at the end of index.php, depends what you like more.

> The code for the dummy class seems to be using tabs.
Fixed that.

m3avrck’s picture

Status: Needs review » Needs work

PHP 5.0.5 introduced a bug that prevented register_shutdown functions from working correctly. See my original post/patch here: http://drupal.org/node/36828 ... basically, PHP 5.0.5 *won't* work with MySQLi, either you need to downgrade to 5.0.4 or upgrade to 5.1.x ... because this bug occurs only in a very specific and now outdated version of PHP, I *don't* support that part of the patch.

However, the error checking seems like a valid point, so that would be useful in this patch.

Thomas Ilsche’s picture

FileSize
2.61 KB

Well attached is a patch just for error handling and non-default port (which I consider worst!)

Anyways, PHP Manual sais:

Write and Close handlers are called after destructing objects since PHP 5.0.5. Thus destructors can use sessions but session handler can't use objects. In prior versions, they were called in the opposite order. It is possible to call session_write_close() from the destructor to solve this chicken and egg problem.

This is why I suggest to stick to what the maunal proposes, using __destruct, this should also be safer for future versions.

m3avrck’s picture

Status: Needs work » Needs review
FileSize
2.56 KB

Thomas, I took at the error handling and figured out a better way to test for error conditions using the actuall error number returned by MySQLi. With this new patch, MySQLi will work like MySQL now... if the database server can't be found, you get the appropriate error. If it can be found but the actual database can't be selected, you see that error as well. Working great now, nice find!

Additionally, I put in the port issue, that was another nice find as well.

As for the destructor thing, to the best of my knowledge, register_shutdown_function() would be called at the same time as __destruct() and therefore, works great. However, PHP 5.0.5 has an *explicit* bug with this function, as it isn't called when it should be, hence the problem you ran into. This was fixed in all versions after and before 5.0.5.

If things look and sound good, please set this commit, thanks!

Dries’s picture

Status: Needs review » Fixed

Last patch looks good. Committed to HEAD.

m3avrck’s picture

Status: Fixed » Reviewed & tested by the community
FileSize
1.62 KB

Seems a few issues crept up with error reporting, this new patch catches the errors more broadly, preventing loads of warnings and Apache server crashes.

m3avrck’s picture

FileSize
1.74 KB

Better patch after talking with Thomas.

Thomas Ilsche’s picture

last patch looks good to me.

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to HEAD. Thanks.

Anonymous’s picture

Status: Fixed » Closed (fixed)