views:

351

answers:

5

I'm considering changing some PHP code to use PDO for database access instead of mysqli (because the PDO syntax makes more sense to me and is database-agnostic). To do that, I'd need both methods to work while I'm making the changeover.

My problem is this: so far, either one or the other method will crash Apache.

Right now I'm using XAMPP in Windows XP, and PHP Version 5.2.8. Mysqli works fine, and so does this:

$dbc = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
echo 'Connected to database';
$sql = "SELECT * FROM `employee`";

But this line makes Apache crash:

$dbc->query($sql);

I don't want to redo my entire Apache or XAMPP installation, but I'd like for PDO to work. So I tried updating libmysql.dll from here, as oddvibes recommended here. That made my simple PDO query work, but then mysqli queries crashed Apache.

(I also tried the suggestion after that one, to update php_pdo_mysql.dll and php_pdo.dll, to no effect.)

Test Case

I created this test script to compare PDO vs mysqli. With the old copy of libmysql.dll, it crashes if $use_pdo is true and doesn't if it's false. With the new copy of libmysql.dll, it's the opposite.

if ($use_pdo){
  $dbc = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
  echo 'Connected to database<br />';
  $sql = "SELECT * FROM `employee`";
  $dbc->query($sql);
  foreach ($dbc->query($sql) as $row){
    echo $row['firstname'] . ' ' . $row['lastname'] . "<br>\n";
  }

}
else {
  $dbc = @mysqli_connect($hostname, $username, $password, $dbname) OR die('Could not connect to MySQL: ' . mysqli_connect_error());
  $sql = "SELECT * FROM `employee`";
  $result = @mysqli_query($dbc, $sql) or die(mysqli_error($dbc));

  while ($row = mysqli_fetch_array($result,MYSQLI_ASSOC)) {
    echo $row['firstname'] . ' ' . $row['lastname'] . "<br>\n";
    }
}

What does Apache need in order to support both methods of database query?

+1  A: 

Not a direct answer, but perhaps it can help you in your search for it:

The legacy mysql extension (The function prefixed with mysql_) is a thin wrapper over libmysqlclient. The new mysqli extension is essentially the same, but it implements some functionality that were introduced in later versions of libmysqlclient. PDO also uses libmysqlclient, but doesn't map it as directly as the other extensions do. This all amounts to 3 different php-extensions that all refer to the same native library. If some of them make assumptions about the version of the library, it might cause them to clash.

I would suggest that you install the newest version of libmysqlclient.dll that you can find and try to disable the legacy mysql extension (if you haven't already).

If you have code that uses mysql extension, you can have mysqli bind to those functions and it should work the same.

Also, make sure that you don't have the new mysqlnd driver installed for some reason. mysqlnd is an alternative implementation of libmysqlclient and it really just makes everything even more complicated.

Yes, it's a big mess.

troelskn
Interesting explanation. However, I don't see `libmysqlclient.dll` in either the xampp/php or the xampp/apache/bin directory. I also don't see it in the downloaded php packages.
Nathan Long
Check if it's in `c:\windows` or `c:\windows\system32`. Otherwise it might be statically compiled into the extensions (And then I have no idea about how to proceed).
troelskn
A: 

It seems like all you need is to uncomment the correct extension directives in php.ini, like extension=php_mysqli.dll and extension=php_pdo_mysql.dll.

I never confirmed this with XAMPP, because I got frustrated with it and decided to install Apache, PHP and MySQL individually. In the process, I learned to do the above steps, along with a lot of other things. So I haven't confirmed that this will work with XAMPP, but I don't see why not, unless it doesn't come with the right drivers.

The two drivers (.dll files) in the example directives above are the ones I'm using. I also set extension_dir = "c:/php/ext" in php.ini - you should make sure that path points to the directory where your php extensions are. (Note that one of the nice things about installing these components separately is that I can put PHP in c:\php instead of having it buried several levels deep in c:\xampp.)

If anybody wants to follow along with installing your server components separately, I documented the whole process, with screenshots, on my blog.

Nathan Long
A: 

same as http://stackoverflow.com/questions/1258294/why-does-this-pdomysql-code-crash-on-windows

but dont have the solution for the moment

Crash happens only on "SELECT * FROM xxx" query() and prepare/execute

Tanguy
A: 

The unique solution i found :

Install LibMySQL.DLL FROM 5.0.51a package (working with last 5.1.44 MySQL Version)

http://www.netfulvpc.fr/files/libmysql_dll.zip

Tanguy
A: 

Ok, i have a very bad but working solution :p)

Open ext\php_pdo_mysql.dll with an Hex Editor

Search for "83 C3 50" offset 0x000024d5 (in php 5.2.12 vc6)

Replace by 83 C3 "54"

The problem is a bad structure size... (struct pdo_column_data)

I tried to fix that in libmysql.dll but that crash php_mysqli ;)

Tanguy