Ulf Wendel

PHP: mysqlnd checked in to PHP 6 (HEAD)

Recently mysqlnd, the MySQL native driver for PHP, has been checked in to the PHP 6 (HEAD) development tree on cvs.php.net. This blog posting gives a quick overview how you can build PHP 5 and PHP 6 with mysqlnd support.

What mysqlnd is and what not

If you do not know what mysqlnd is or not is, read up the details on http://dev.mysql.com/downloads/connector/php-mysqlnd/. In short: mysqlnd is is a replacement for the libmysql, the MySQL Client Library. It it closely integrated into PHP and it is distributed under the terms of the PHP license. You can now compile ext/mysql and ext/mysqli to use the libmysql – just like in the past – or to use the new mysqlnd driver. Once again, note that mysqlnd is not a new programming API, but an alternative to libmysql which is used “under the hood”, on the C-level, to connect from PHP to the MySQL Server.

As explained earlier in the post PHP: Is mysqlnd stable? the versions of ext/mysql and ext/mysqli checked in to HEAD fail on considerable less test cases than the versions that have been in HEAD before. We encourage all users to try out mysqlnd. However, to be able to try it out, you obviously need to know how to compile it.

Compiling PHP 6 with mysqlnd enabled

Compiling PHP 6 with ext/mysql and ext/mysqli using mysqlnd on Unix is easy.

One of the major benefits of mysqlnd is that it is a library that resides inside PHP on the C-level. mysqlnd provides all functionality that the MySQL extensions need to connect to the MySQL Server. Therefore you do not need to have the MySQL Client Library (libmysql) installed on your build system. All what the extensions need to connect to the MySQL Server is part of PHP 6. Therefore several causes of troubles are no longer there: no linking is required, there is no hassle caused by version issues (mysqlnd can connect to any MySQL Server as of 4.1) and there is no need to install libmysql on your build system…

Well, so much about the theory. We tried hard to come up with a mysqlnd version that compiles on more than 20+ platforms and tested mysqlnd against 20+ MySQL Server versions, but we need community feedback to verify our lab results and to further improve the portability and stability of mysqlnd.

To make a long story short, here is how you compile PHP 6 from cvs.php.net with mysqlnd support.

  1. Check out PHP 6 from cvs.php.net.

    cvs -d :pserver:cvsread@cvs.php.net:/repository checkout php6
    

    See Anonymous CVS Access instructions for details.

  2. Change to the source directory and run buildconf

    cd php6/
    ./buildconf --force
    

  3. Configure command for mysqlnd

    ./configure --with-mysql=mysqlnd --with-mysqli=mysqlnd
    

  4. Build PHP

    make clean
    make
    

If all goes well, it compiles and you will find a PHP binary in sapi/cli/ which supports mysqlnd. There are two ways to check, if a PHP binary supports mysqlnd. One way is to check the list of PHP Modules printed by php -m, if it shows an entry for mysqlnd. Another way is to investigate the output of the phpinfo() function, for example using sapi/cli/php -i | grep -i mysql. A binary that supports mysqlnd will show the mysqld module and print the mysqlnd version at “Client API version” (ext/mysql) resp. “Client API library version” (ext/mysqli).

linux-eu6p:/home/nixnutz/tmp/php6 > sapi/cli/php -i | grep -i mysql
Configure Command =>  './configure'  '--with-mysql=mysqlnd' '--with-mysqli=mysqlnd'
mysql
MySQL Support => enabled
Client API version => mysqlnd 5.0.2-dev - 070702 - $Revision: 1.1 $
[...]
mysqli
MysqlI Support => enabled
Client API library version => mysqlnd 5.0.2-dev - 070702 - $Revision: 1.1 $
[...]
mysqlnd
mysqlnd => enabled
Version => mysqlnd 5.0.2-dev - 070702 - $Revision: 1.1 $

Compiling PHP 6 with libmysql enabled

As ever since you can continue to link ext/mysql and ext/mysqli against libmysql, if you want to. The corresponding configure options did not change. All your build scripts will continue to work as before. The help output of the configure command gives the proof.

linux-eu6p:/home/nixnutz/tmp/php6 > ./configure --help | grep -C1 mysqlnd
  --with-mysql=DIR        Include MySQL support. DIR is the MySQL base directory.
                            If mysqlnd is passed as DIR, the MySQL native driver will be used
  --with-mysql-sock=DIR   MySQL: Location of the MySQL unix socket pointer.
  --with-mysqli=FILE    Include MySQLi support. FILE is the optional pathname to mysql_config mysql_config.
                          If mysqlnd is passed as FILE, the MySQL native driver will be used

What about PHP 5?

UPDATE – 2007/12/28 – Compiling mysqlnd with PHP 5.2/5.3/6.0 – UPDATE

Mysqlnd is also available for PHP 5. To build PHP 5 with mysqlnd you need to fetch the mysqlnd source from the public SVN at MySQL and patch PHP 5. The configure options are the same as for PHP 6. Patching means replacing the ext/mysql resp. ext/mysqli directories, which is easy going. See below for step-by-step instructions.

PHP 5 is the current GA/production version of PHP. Committing a major change and a huge amount of new code into PHP 5 requires great care. A minor PHP 5.2.x Release is not a proper place for any major change. New code, be it mysqlnd or other changes, should wait for a better opportunity to be checked in to PHP. Before one makes major additions to PHP 5, the new code should have not only passed the lab tests, like mysqlnd did, but also be widely tested by the Community. Maybe a 5.3 branch might be a proper place for a check-in. but that remains to be seen…

Allow me this aside-note: how do you get new code tested, if it does not automatically come with PHP… Once again, testing and feedback is most welcome!

Compiling PHP 5 with mysqlnd enabled

  • Check out mysqlnd from the MySQL mysqlnd SVN repository

    nixnutz@linux-eu6p:~/tmp> svn co http://svn.mysql.com/svnpublic/php-mysqlnd
    A    php-mysqlnd/trunk
    [...]
    

  • Get a source distribution of PHP 5.2.x

    Check out the latest version of PHP 5 from CVS. Please note that due to a recent change you cannot use the 5.2.3 Release.

    nixnutz@linux-eu6p:~/tmp> cvs -d :pserver:cvsread@cvs.php.net:/repository checkout -r PHP_5_2 php5
    cvs checkout: Updating php5
    U php5/.cvsignore
    [...]
    

    See Anonymous CVS Access instructions for details.

  • Patch PHP: replace ext/mysql and ext/mysqli

    nixnutz@linux-eu6p:~/tmp> cd php5
    nixnutz@linux-eu6p:~/tmp/php5> rm -rf ext/mysql ext/mysqli
    nixnutz@linux-eu6p:~/tmp/php5> cp -R ../php-mysqlnd/trunk/php5/ext/mysql ext/mysql
    nixnutz@linux-eu6p:~/tmp/php5> cp -R ../php-mysqlnd/trunk/php5/ext/mysqli ext/mysqli
    

    Now, create ext/mysqlnd. We used to have the mysqlnd source in ext/mysqli/mysqlnd before, but Jani thought that ext/mysqlnd would be a better place as mysqlnd is somewhat like an extension without functions, similar to PDO. Therefore, Jani wrote yet another application (if coding can be seen as a job application) and moved the code to ext/mysqlnd.

    nixnutz@linux-eu6p:~/tmp/php5> cp -R ../php-mysqlnd/trunk/mysqlnd ext/mysqlnd
    

    If you are working with the trunk/ development tree (recommended!) and not a tagged version of mysqlnd, you need to do a few additional copy operations. For convenience reasons Georg, Andrey and I are using symlinks in the SVN repository which need to be replaced with actual copies before compiling.

    nixnutz@linux-eu6p:~/tmp/php5> rm ext/mysql/tests
    nixnutz@linux-eu6p:~/tmp/php5> cp -R ../php-mysqlnd/trunk/tests/ext/mysql ext/mysql/tests
    nixnutz@linux-eu6p:~/tmp/php5> rm ext/mysqli/tests
    nixnutz@linux-eu6p:~/tmp/php5> cp -R ../php-mysqlnd/trunk/tests/ext/mysqli ext/mysqli/tests
    

    From now on building goes as for PHP 6 and requires no extra steps.

  • Build the configure script

    nixnutz@linux-eu6p:~/tmp/php5> ./buildconf --force
    Forcing buildconf
    [...]
    

  • Configure command for mysqlnd

    nixnutz@linux-eu6p:~/tmp/php5> ./configure --with-mysql=mysqlnd --with-mysqli=mysqlnd
    checking for egrep... grep -E
    [...]
    

  • Build PHP

    
    

    nixnutz@linux-eu6p:~/tmp/php5> make clean; make
    find . -name \*.gcno -o -name \*.gcda | xargs rm -f
    [...]

Mixing libmysql and mysqlnd

You can “mix” libmysql and mysqlnd in one binary. An extension cannot be compiled with support for libmysql and mysqlnd at the same time. At compile time you configure ext/mysql (ext/mysqli) to use either libmysql or mysqlnd to connect to a MySQL Server. However, you can compile a PHP binary with ext/mysql using libmysql and ext/mysqli using mysqlnd, for example. In this sense you can “mix” libmysql and mysqlnd in one binary and having the extensions using the same or distinct libraries.

7 Comments

  1. Just a short note: Instead of fetching PHP from CVS you can also use the PHP 6 snapshots from htp://snaps.php.net – then you don’t have to run buildconf and therefore don’t need to have autotools and a few other problematic pieces on your box.

  2. If I’m already using PDO for database connections (via PDO_MYSQL from PECL), is there any reason I should switch to mysqlnd? Would it be faster or perhaps more secure (I’m a big fan of the prepared statements in PDO for preventing SQL injections)?

  3. Ian, here is the answer to your question: http://blog.ulf-wendel.de/?p=149

  4. Wow, I could not get this working right. following the directions, I’d get an error from ./configure saying my version of flex (2.5.34) wasn’t supported, so I downloaded the… older? 2.5.4 and installed it, then php5′s configure gave me some errors like “undefined reference to `zend_ptr_stack_init_ex’”

    I did some searches but couldn’t find what I needed to install so back to square one. well, at least mysqli’s working, even if it’s not with mysqlnd :/

  5. forgot to mention I was trying this for php5

  6. The trouble with fex old / flex compat has nothing to do with any PHP extension such as mysqlnd. Its the PHP parser that requires an old version. AFAIK Marcus Boerger is one of the PHP hackers who would would like to upgrade or replace the existing PHP parser given enough resources are available for that task.

    Are you using PHP 5.2.x or PHP 5.3? Looks very much like PHP 5.2.x. Use PHP 5_3.

    PHP 5.3 should work fine out of the box:

    cvs -d :pserver:cvsread@cvs.php.net:/repository checkout -r PHP_5_3 php5
    cd php5/
    ./buildconf –force
    ./configure –help | grep mysql
    ./configure –with-mysql=mysqlnd –with-mysqli=mysqlnd
    make clean; make
    sapi/cli/php -m | grep mysql

    PHP 5.2.5 might need some tweaking:

    [13:41] andrey: Do you know if mysqlnd will compile with PHP 5.2.5?
    [13:41] it will, but not without intervention
    [13:42] you need zend_ptr_stack.h and zend_ptr_stack.c from 5_3
    [13:43] Ok

    Ok, let’s try with PHP 5.2.5 –

    cvs -d :pserver:cvsread@cvs.php.net:/repository checkout -r PHP_5_3 php5
    cd php5/
    ./configure –help | grep mysql

    –enable-embedded-mysqli MYSQLi: Enable embedded support
    –with-mysql=DIR Include MySQL support. DIR is the MySQL base directory
    –with-mysql-sock=DIR MySQL: Location of the MySQL unix socket pointer.
    –with-mysqli=FILE Include MySQLi support. FILE is the optional pathname
    to mysql_config mysql_config
    –with-pdo-mysql=DIR PDO: MySQL support. DIR is the MySQL base directory

    ^ no mysqlnd here!
    ^ you must patch PHP 5.2.x – some might know how
    ^ you are asked not to patch 5.2.x – please use 5.3
    ^ please do not provide patch instructions, patching is not supported

    So, why is PHP 5.2.x not supported? Well, mysqlnd is still (late, late) beta. The development branch of PHP 5 is PHP 5.3 not PHP 5.2. PHP 5.2 is for stable stuff. Therefore mysqlnd is not part of any PHP 5.2.x version and we do not try to make it perfectly compatible. Simply because PHP 5.2.x is not for beta and mysqlnd is (late, late) beta.

    mysqlnd aims at PHP 5.3 and PHP 6.0.

    … and yes, you’re correct I need to update installation instructions.

  7. magnoid, I’ve written a new blog posting with updated compile / install instructions – http://blog.ulf-wendel.de/?p=174 . Thanks for pointing out the need for it!