Bug #73080 [Com]: oci_execute doesn't work properly

From: Date: Sat, 17 Sep 2016 17:57:14 +0000
Subject: Bug #73080 [Com]: oci_execute doesn't work properly
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-204097@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=73080&edit=1 ID: 73080 Comment by: lzsiga at freemail dot c3 dot hu Reported by: sergei dot solomonov at gmail dot com Summary: oci_execute doesn't work properly Status: Open Type: Bug Package: OCI8 related Operating System: Ubuntu 15.04 PHP Version: 7.1.0RC1 Block user comment: N Private report: N New Comment: I think the core of the problem is that oci_bind_by_name doesn't increment the reference-counter, instead it requires the caller to keep the variable alive: "A bind call tells Oracle which memory address to read data from. For IN binds that address needs to contain valid data when oci_execute() is called. This means that the variable bound must remain in scope until execution. If it doesn't, unexpected results or errors such as "ORA-01460: unimplemented or unreasonable conversion requested" may occur. For OUT binds one symptom is no value being set in the PHP variable." So here is the suggested solution: $stmt = new Statement("SELECT * FROM dual WHERE :p1 = 'xxx'"); $bv_p1= 'xxx'; $params = ['p1' => &$bv_p1]; $stmt->bindParams($params); $stmt->execute(); Previous Comments: ------------------------------------------------------------------------ [2016-09-15 15:05:18] lzsiga at freemail dot c3 dot hu Reproduced the problem; the message comes from zend_operators.c:_convert_to_string (line 547), called by oci8_statement.c:php_oci_bind_in_callback (line 1360) (gdb) bt #0 _convert_to_string (op=0x7ffff3073270, __zend_filename=0xcb6ba8 "/usr/local/src/php-7.0.10/ext/oci8/oci8_statement.c", __zend_lineno=1360) at /usr/local/src/php-7.0.10/Zend/zend_operators.c:547 #1 0x00000000005f6034 in php_oci_bind_in_callback (ictxp=0x7ffff3081280, bindp=0x1230fb8, iter=0, index=0, bufpp=0x1231088, alenp=0x1231144, piecep=0x1231091 "\001", indpp=0x7fffffff47b0) at /usr/local/src/php-7.0.10/ext/oci8/oci8_statement.c:1360 #2 0x00007ffff5d17c39 in ttcGetSendInfo () from /opt/OraHome_Current/lib64/libclntsh.so.11.1 #3 0x00007ffff75a8d85 in ttcacs () from /opt/OraHome_Current/lib64/libclntsh.so.11.1 #4 0x00007ffff7577f34 in ttcdrv () from /opt/OraHome_Current/lib64/libclntsh.so.11.1 #5 0x00007ffff7528251 in nioqwa () from /opt/OraHome_Current/lib64/libclntsh.so.11.1 #6 0x00007ffff75125ce in upirtrc () from /opt/OraHome_Current/lib64/libclntsh.so.11.1 #7 0x00007ffff75182be in kpurcsc () from /opt/OraHome_Current/lib64/libclntsh.so.11.1 #8 0x00007ffff7515bc2 in kpuexec () from /opt/OraHome_Current/lib64/libclntsh.so.11.1 #9 0x00007ffff75130cf in OCIStmtExecute () from /opt/OraHome_Current/lib64/libclntsh.so.11.1 #10 0x00000000005f23cf in php_oci_statement_execute (statement=0x7ffff30811e0, mode=32) at /usr/local/src/php-7.0.10/ext/oci8/oci8_statement.c:540 ------------------------------------------------------------------------ [2016-09-14 04:23:17] sergei dot solomonov at gmail dot com Test script works fine with the such function definition: public function execute(array &$bindParams = []) ... But during my experiments I've got segfaults couple of times. Also works with the following snippet: public function bindParams(array $bindParams = []) { if (count($bindParms)) foreach ($bindParams as $bvName => &$bvValue) ... ------------------------------------------------------------------------ [2016-09-14 04:21:27] sergei dot solomonov at gmail dot com Description: ------------ Tested with 7.09 and 7.1.0RC1 on Ubuntu 15.04 and MacOSX10.11 operating systems. Looks like all 7.* versions affected. Works fine with php v5.5, v5.6. Default php.ini-development config was used. Configure command: './configure' '--enable-zip' '--enable-intl' '--with-oci8' '--enable-dbase' '--disable-cgi' '--with-apxs2=/usr/local/apache/bin/apxs' '--enable-opcache' '--enable-sigchild' '--enable-mbstring' '--with-xsl' '--with-gd' '--with-config-file-scan-dir=/usr/local/apache/conf' '--with-openssl' '--with-curl' '--with-zlib' '--enable-timezonedb' Test script: --------------- <?php class Statement { private $stmt; function __construct($query) { $conn = oci_connect('autotest', '6de9439834c914756974', 'cascade.erkc.ru', 'UTF8'); $this->stmt = oci_parse($conn, $query); } public function execute(array $bindParams = []) { $this->bindParams($bindParams); return oci_execute($this->stmt); // Line 14 } public function bindParams(array $bindParams = []) { foreach ($bindParams as $bvName => &$bvValue) oci_bind_by_name($this->stmt, $bvName, $bvValue); } public function fetch() { return oci_fetch_array($this->stmt, OCI_ASSOC); } } $stmt = new Statement("SELECT * FROM dual WHERE :p1 = 'xxx'"); $params = ['p1' => 'xxx']; $stmt->bindParams($params); $stmt->execute(); var_dump($stmt->fetch()); Expected result: ---------------- array(1) { ["DUMMY"]=> string(1) "X" } Actual result: -------------- PHP Notice: Array to string conversion in /usr/local/apache/htdocs/module/Db/1.php on line 14 bool(false) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=73080&edit=1

« previous php.bugs (#204097) next »