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

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 Support => enabled
Client API version => mysqlnd 5.0.2-dev - 070702 - $Revision: 1.1 $
MysqlI Support => enabled
Client API library version => mysqlnd 5.0.2-dev - 070702 - $Revision: 1.1 $
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.