ID: 39858 Comment by: denis dot podgurskiy at cofelab dot ru Reported By: develar at gmail dot com Status: Assigned Bug Type: PDO related Operating System: Windows XP SP2 PHP Version: 5.2.0 Assigned To: wez New Comment:
Well, some updates. The previous approach doesn't work with transactions at all - see Init method. After long investigation I can say the next: Windows XP SP/2 Apache 1.3/PHP 5.2/MySQL/5.** MySql tables should be in InnoDB (possibly BDB) format - MYISAM doesn't support transactions yet. Class to work with DB: <?php /** * eXtended Management System * * LICENSE * * This source file is subject to the new BSD license that is bundled * with this package in the file LICENSE.txt. * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to [EMAIL PROTECTED] so we can send you a copy immediately. * * * @category Xms * @package Xms_Core * @copyright Copyright (c) 2006 CoFe Lab. (http://www.cofelab.ru) * @license http://www.cofelab.ru/license */ class Xms_Do { /* Begin class */ /** * @var Zend Db factory object. */ public $Db; /** * @var array */ private $_params; /** * @var string. Type of the PDO object. */ private $_config; /** * Construct * @param object. Zend config object. */ public function __construct( $config ) { Zend::loadClass('Zend_Db'); $this -> _config = $config -> database; $this -> _params = array ('host'=> $this -> _config -> host, 'port' => $this -> _config -> port, 'username' => $this -> _config -> username, 'password' => $this -> _config -> password, 'dbname' => $this -> _config -> name, PDO::ATTR_PERSISTENT => true); $this -> Init(); } /** * Init database connection */ public function Init() { if(strstr($_SERVER['SERVER_SOFTWARE'],'Win')){ $this -> Db = new PDO($this -> _config -> odbc, $this -> _config -> username, $this -> _config -> password); } else { $this -> Db = Zend_Db::factory( $this -> _config -> type, $this -> _params); } $this -> Db -> query("SET NAMES '".$this -> _config -> charset."'"); $this -> Db -> query("SET CHARACTER SET '".$this -> _config -> charset."'"); } private function InitOdbc(){ } /** * Execute stored procedure. * @param string. Stored procedure's name. * @param array. DbParameter objects. */ public function ExecuteStoredProcedure($spName, $args) { //echo $spName; $ch = ',?'; $sp_str = ""; if(sizeof($args) > 0) { $arr = array_fill ( 1, sizeof($args),null); $sp_str = 'CALL '.$spName.' (?'.implode($ch, array_values($arr)).')'; } else{ $sp_str = 'CALL '.$spName.'()'; } $command = null; $command = $this -> Db -> prepare( $sp_str ); $count = 1; $var = '@SiteId'; foreach($args as $key => $par ){ if(!is_object($par)) { trigger_error('Wrong parameters type in :'.$spName, E_USER_ERROR); } if($par -> parType == 'OUTPUT'){ $command -> bindParam($count, $var, $par -> type, $par -> size, array( PDO::ATTR_EMULATE_PREPARES => true) ); } else { $command -> bindParam($count, $par -> value, $par -> type, $par -> size, array( PDO::ATTR_EMULATE_PREPARES => true) ); } $count ++; } $command -> execute(); $rows = array(); if($command != null){ $rows = $command -> fetchAll(); $command -> closeCursor(); $command -> nextRowset(); //$this -> Init(); } $command = null; return $rows; } /** * Desturctor. */ public function __destruct() { $this -> Db = null; } /* End class */ } Config file (uses Zend config to read it): <database> <type>Pdo_Mysql</type> <host>localhost</host> <port>3307</port> <username>root</username> <password></password> <name>xms</name> <charset>utf8</charset> <odbc>odbc:DSN=XMS_MySQL;</odbc> </database> Wrapper for DB parameter <?php /** * XMS Framework * * LICENSE * * This source file is subject to the license that is bundled * with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://xms.cofelab.ru/license/ * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to [EMAIL PROTECTED] so we can send you a copy immediately. * * @category Xms * @package Xms_Core * @copyright Copyright (c) 2006 Cofelab Russia. (http://www.cofelab.com) * @license http://xms.cofelab.ru/license/ */ class Xms_Db_Parameter { /** * Presents name of the class. * @staticvar string */ public static $ClassName = "Xms_Db_Parameter"; /** * Presents name of the class. * @staticvar string */ public $name; public $value; public $type; public $size; public $parType; public function __construct($name, $value, $type, $size) { $this -> name = $name; $this -> value = $value; $this -> type = $type; $this -> size = $size; } } An example: try{ $this -> _modDO -> Db -> beginTransaction(); $_siteId = null; $parSiteUrl = new Xms_Db_Parameter('Url', $args -> siteadddomain, PDO::PARAM_STR, 100); $parSiteDesc = new Xms_Db_Parameter('Description', $args -> siteadddescription, PDO::PARAM_STR, 255); $rows = $this -> _modDO -> ExecuteStoredProcedure( Xms_Constants :: $prcSiteAddItem, array('Url'=>$parSiteUrl, 'Description' => $parSiteDesc)); $node ="<siteadddomain><value>".$args -> siteadddomain."</value><error sysmes='siteadddomainerrex' /></siteadddomain>"; $this -> _modDO -> Db -> commit(); } catch(Exception $e) { echo $e -> getMessage(); $this -> _modDO -> Db -> rollBack(); } PS. Not tested under Nix yet - I'll update the topic. Previous Comments: ------------------------------------------------------------------------ [2007-01-29 11:30:35] denis dot podgurskiy at cofelab dot ru Hi there I have had the same problem but as far as I use PHP 5 why do not create your own class to work with PDO. See example - this is a part of class. I just stupidly catch the required error, make re-init of the Zend_Db and run this quesry once again...Really stupidly, but this bug meets on Windows only and for Nix this case wont' work so nothing serious:) Good luck, Denis public function ExecuteStoredProcedure($spName, $args) { $ch = ',:'; $sp_str = ""; if(sizeof($args) > 0) { $sp_str = 'CALL '.$spName.' (:'.implode($ch, array_keys($args)).')'; } else{ $sp_str = 'CALL '.$spName.'()'; } $command = null; $command = $this -> Db -> prepare( $sp_str ); $command -> setFetchMode ( Zend_Db::FETCH_ASSOC ); foreach($args as $key => $par ){ if(!is_object($par)) { trigger_error('Wrong parameters type in :'.$spName, E_USER_ERROR); } $command -> bindParam($par -> name, $par -> value, $par -> type, $par -> size, array( PDO::ATTR_EMULATE_PREPARES => true) ); } try{ $command -> execute(); } catch(PDOException $e) { if($e -> errorInfo[0] == !'HY000' && $e->errorInfo[0] !== '2013'){ echo "www"; throw($e); } else { $command = $this -> Db -> prepare( $sp_str ); $command -> setFetchMode ( Zend_Db::FETCH_ASSOC ); try { $command -> execute(); } catch(PDOException $e) { if($e -> errorInfo[0] == !'HY000' && $e->errorInfo[0] !== '2013'){ throw($e); } $command = null; $this -> Init(); } } } $rows = array(); if($command != null){ $rows = $command -> fetchAll(); $command -> closeCursor(); $this -> Init(); } $command = null; return $rows; } ------------------------------------------------------------------------ [2006-12-18 12:26:21] mike at we11er dot co dot uk Here are two more bug reports on pecl: http://pecl.php.net/bugs/bug.php?id=7976 http://pecl.php.net/bugs/bug.php?id=5827 Again it seems intermittant with some people. I got a SQL error log which showed this: 061213 11:27:36 [Warning] Aborted connection 1 to db: 'test' user: 'test' host: 'localhost' (Got an error reading communication packets) Before anyone asks, I have been rd /s'ing the PHP directory when I try a snapshot to make sure I'm running a clean version of everything. Adding $this->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, TRUE); does not stop the error. nextRowset() isn't implemented so we can't fetch all the results manually. That is all. ------------------------------------------------------------------------ [2006-12-18 12:18:06] mike at we11er dot co dot uk I'm having this issue as well. My bug report here: http://bugs.php.net/bug.php?id=39759 has some more information. To recap: I've tested this with php 5.2 release, as well as various recent snapshots. I've tested with mysql 5.0.22 and 5.0.27. I've tested with the libmysql.dll files that php ships with, as well as the libmysql.dll that mysql ships with - they produce two different errors but the problem is the same. When using PHP's libmysql.dll the error is: SQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query When using MySQL's libmysql.dll the error is: SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. When running through apache I get this error 100% of the time. When running through the PHP command line interface, I get it about 50% of the time, so perhaps there are performance issues here. I'm running on a celeron 2.4GHz with 512 ram. Windows XP. Please fix this! ------------------------------------------------------------------------ [2006-12-18 09:28:00] develar at gmail dot com Почитайте http://phpclub.ru/talk/showthread.php?s=&threadid=92764&rand=10 It always worked normally on linux. My first message: "I read #35333 #35637 #35203, but why the given code fine works in Debian?" Only in windows. ------------------------------------------------------------------------ [2006-12-18 09:20:54] [EMAIL PROTECTED] Works just fine on Linux. Make sure you're really running the snapshot. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/39858 -- Edit this bug report at http://bugs.php.net/?id=39858&edit=1