php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73080 oci_execute doesn't work properly
Submitted: 2016-09-14 04:21 UTC Modified: 2016-10-13 04:47 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: sergei dot solomonov at gmail dot com Assigned:
Status: Duplicate Package: OCI8 related
PHP Version: 7.1.0RC1 OS: Ubuntu 15.04
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: sergei dot solomonov at gmail dot com
New email:
PHP Version: OS:

 

 [2016-09-14 04:21 UTC] 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)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-14 04:23 UTC] 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-15 15:05 UTC] 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-17 17:57 UTC] lzsiga at freemail dot c3 dot hu
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();
 [2016-10-13 04:47 UTC] sixd@php.net
-Status: Open +Status: Duplicate
 [2016-10-13 04:47 UTC] sixd@php.net
Seems fixed by the patch in bug #71148.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 22:01:28 2024 UTC