Issues

ZF-11973: Zend_Db_Statement execute alters variables

Description

This is tested in a ZF 1.11.10 app on Ubuntu 10.04 LTS (with stock PHP and zend-framework package, not Zend Server/CE)


    public function bugTestAction()
    {
        $this->_helper->layout->disableLayout();
        $this->_helper->viewRenderer->setNoRender();
        header('Content-type: text/plain');
        echo 'Zend Framework version: ' . Zend_Version::VERSION . PHP_EOL;
        $foo = (int)3;
        echo 'Type before stmt: ' . gettype($foo) . PHP_EOL;
        $db = new Application_Model_DbTable_Clients();
        $stmt = $db->getAdapter()->prepare('SELECT * FROM `client` WHERE 3 = :bound');
        $stmt->bindParam(':bound', $foo);
        echo 'Type after bind: '  . gettype($foo) . PHP_EOL;
        $stmt->execute();
        echo 'Type after execute: '  . gettype($foo) . PHP_EOL;
    }

output:
Zend Framework version: 1.11.10
Type before stmt: integer
Type after bind: integer
Type after execute: string

Comments

While I realize it is passed by reference (perhaps to save copying/memory), I'm not sure I understand why the variable needs to be altered, especially to change types.

In the case I ran into this- I have a variable that if you pass in an integer it uses a fixed record id, and if you pass in a string it does a fuzzy search. After doing ->execute and ->fetchAll, if we did a fixed id, we're only going to get one record so rather than return the array of one result, I'd return the one result. To do this I checked again whether the variable was still is_int and of course it no longer was. In practice, I could probably replace is_int with is_numeric, but I'm left curious about the variable being altered.

from the PDO manual "Most parameters are input parameters, that is, parameters that are used in a read-only fashion to build up the query. Some drivers support the invocation of stored procedures that return data as output parameters, and some also as input/output parameters that both send in data and are updated to receive it."

This seems to imply it should be read only as in this case it is not receiving data?

I guess this is a PDO "Bug" noted at least 3 years back. http://php.net/manual/en/…

Even manually specifying the type as int does not help.

public function bugTestAction()
{
    $this->_helper->layout->disableLayout();
    $this->_helper->viewRenderer->setNoRender();
    header('Content-type: text/plain');
    echo 'Zend Framework version: ' . Zend_Version::VERSION . PHP_EOL;
    $foo = (int)3;
    echo 'Type before stmt: ' . gettype($foo) . PHP_EOL;
    $db = new Application_Model_DbTable_Clients();
    $stmt = $db->getAdapter()->prepare('SELECT * FROM `client` WHERE 3 = :bound');
    $stmt->bindParam(':bound', $foo, PDO::PARAM_INT);
    echo 'Type after bind: '  . gettype($foo) . PHP_EOL;
    $stmt->execute(); // $foo becomes string!
    echo 'Type after execute: '  . gettype($foo) . PHP_EOL;
}

Zend Framework version: 1.11.10 Type before stmt: integer Type after bind: integer Type after execute: string