Friday, October 24, 2008

PHP, PDO, веселье при наследовании и включенной опции persistent connect

За что я люблю PHP?

За то что это глобально и надежно. Ну какой еще другой язык может мне в пятницу утром сломать мозг.

Этой статьей открою растянутый список статей в которых опишу подводные камни удобно предоставленные PHP нашей команде.

Cюрприз #1

В проекте есть класс DB, отнаследованный от PDO. Было обнаружено неадекватное поведение объектов. 3 часа ломания мозга дали следующий тестовой код воспроизводящий проблему.


КОму интересно, попробуйте угадать результат

ini_set ( 'display_errors', 'on' );
error_reporting ( E_ALL );

class MyDB extends PDO {
public $connectionId = 0;
}

class MyFactory {

protected static $_storage = array ();

static public function get($id) {
if ( isset ( self::$_storage[$id] ))
return self::$_storage[$id];

self::$_storage[$id] = new MyDB ( 'mysql:host=127.0.0.1;dbname=toox2;', 'root', '123', array (PDO::ATTR_PERSISTENT => true ) );
self::$_storage[$id]->connectionId = $id;
return self::$_storage[$id];
}
}

$db1 = MyFactory::get( 1 );
$db2 = MyFactory::get( 2 );

var_dump( $db1 );
var_dump( $db2 );




Ну а для тех кто думал ровно как и я что в результате $dbq->connectionId и $db2->connectionId буду разными привожу код


cd@cd-laptop:~/tmp/php-tests$ php test.php
object(MyDB)#1 (1) {
["connectionId"]=>
int(2)
}
object(MyDB)#2 (1) {
["connectionId"]=>
int(2)
}



Проблема в

array (PDO::ATTR_PERSISTENT => true )


Если его убрать, то поведение становится ожидаемым, но однако, почему persistent connect ломает ооп в пхп :)

А ну и на закуску, хотя из приведенного кода выше это видно

var_dump($db1 === $db2) === false

Кому интересно

cd@cd-laptop:~/tmp/php-tests$ php -v
PHP 5.2.4-2ubuntu5.3 with Suhosin-Patch 0.9.6.2 (cli) (built: Jul 23 2008 06:44:49)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies


На slackware товарищ воспроизводил проблему также.

No comments:

 
Каталог сайтов, Добавить сайт