ID:               39858
 Comment by:       mike at we11er dot co dot uk
 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:

Thanks for the help Denis, although I can't personally implement this
workaround...

For the time being I have hacked in lines of code to create a new
database connection before calling certain stored procedures.

Now, PLEASE could a developer or someone RESPOND and acknowledge this
bug, and let us know what is going on!?

I've been stuck with this bug for months and months with no help
whatsoever from the PHP guys.


Previous Comments:
------------------------------------------------------------------------

[2007-02-07 09:25:31] denis dot podgurskiy at cofelab dot ru

It works under Nix as well. So, good luck.

------------------------------------------------------------------------

[2007-02-06 17:13:57] denis dot podgurskiy at cofelab dot ru

One more thing - you need to install MySQL ODBC driver to work with
MySQL in this example: see dsn string. I use named DSN - XMS_MySQL
based on MySQL ODBC 3.51.12 Win driver.

------------------------------------------------------------------------

[2007-02-06 17:11:33] denis dot podgurskiy at cofelab dot ru

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.

------------------------------------------------------------------------

[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.

------------------------------------------------------------------------

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

Reply via email to