Oci8Pdo Yii 1.1 expansion and bandage of the CLOB/BLOB parameters

来源:互联网 发布:淘宝转化率低怎么办 编辑:程序博客网 时间:2024/05/31 19:39
In my company there is project which is constructed on Yii 1.1 and uses the Oracle 9g database. For work with base the oci8Pdo expansion is used.

Recently there was problem of loading of scans in base in the field of BLOB. Since the author of expansion writes: 
The goal of this PDO class is to simulate of 99% of the PDO functions that you use in an application.
that of the reasons to doubt implementation of this functionality was a little.

We try to load the scan:

<?php    $doc_scan = file_get_contents($file);    $db = Yii::app()->dbOracle;    $stmt = $db->createCommand("update scan_document set DOCUM_SCAN=:doc_xml, DOC_SCAN=:doc_scan where DOCUM_ID=:docum_id");    $stmt->bindParam(':doc_xml', $doc_xml, PDO::PARAM_LOB);    $stmt->bindParam(':doc_scan', $doc_scan, PDO::PARAM_LOB);    $stmt->bindValue(':docum_id', $add->DOCUM_ID);    $stmt->query();?>

But far from it: ORA-01465: invalid hex number.

Began to light up problem and have come across implementation of the bindParam method in the class Oci8PDO_Statement of the above described expansion:

<?phppublic function bindParam(    $parameter,    &$variable,    $data_type = PDO::PARAM_STR,    $length = -1,    $driver_options = null) {//Not checking for $data_type === PDO::PARAM_INT, because this gives problems when inserting/updating integers into a VARCHAR column.    if ($driver_options !== null) {        throw new PDOException('$driver_options is not implemented for Oci8PDO_Statement::bindParam()');    }        if (is_array($variable)) {        return oci_bind_array_by_name(            $this->_sth,            $parameter,            $variable,            count($variable),            $length        );    } else {        if ($length == -1) {            $length = strlen((string)$variable);        }        return oci_bind_by_name($this->_sth, $parameter, $variable, $length);    }}?>

The argument of $data_type is accepted, but is not processed anywhere. And it turns out that CLOB or BLOB to write at us will not leave. There was no place to disappear, it was necessary to dopilivat oci8Pdo.

Have added constants and method to the class Oci8PDO which is inherited from PDO the pulling-out resource of connection to DB:

<?php/**     * Ananalog constant OCI_B_CLOB     *     * @const int     */    const PARAM_CLOB = 112;    /**     * Ananalog constant OCI_B_BLOB     *     * @const int     */    const PARAM_BLOB = 113;    // ..............    /**     * Return the resource connection     *     * @return mixed     */    public function getDbh() {        return $this->_dbh;    }?>

And the bindParam method in the class Oci8PDO_Statement there are some dopilila:

<?phppublic function bindParam(        $parameter,        &$variable,        $data_type = PDO::PARAM_STR,        $length = -1,        $driver_options = null    ) {        // ................    if ($data_type == Oci8PDO::PARAM_BLOB) {            $clob = oci_new_descriptor($this->_pdoOci8->getDbh(), OCI_D_LOB);            $res = oci_bind_by_name($this->_sth, $parameter, $clob, -1, OCI_B_BLOB);            $clob->writeTemporary($variable, OCI_TEMP_BLOB);            return $res;        } else if ($data_type == Oci8PDO::PARAM_CLOB) {            $clob = oci_new_descriptor($this->_pdoOci8->getDbh(), OCI_D_LOB);            $res = oci_bind_by_name($this->_sth, $parameter, $clob, -1, OCI_B_CLOB);            $clob->writeTemporary($variable, OCI_TEMP_CLOB);            return $res;        }        else {            return oci_bind_by_name($this->_sth, $parameter, $variable, $length);        }    }?>

Now processing of CLOB/BLOB takes place successfully:

<?php$doc_scan = file_get_contents($file);$db = Yii::app()->dbOracle;$stmt = $db->createCommand("update scan_document set DOCUM_SCAN=:doc_xml, DOC_SCAN=:doc_scan where DOCUM_ID=:docum_id");$stmt->bindParam(':doc_xml', $doc_xml, Oci8PDO::PARAM_CLOB); // Используем наши константы$stmt->bindParam(':doc_scan', $doc_scan, Oci8PDO::PARAM_BLOB); // Используем наши константы$stmt->bindValue(':docum_id', $add->DOCUM_ID);$stmt->query();?>

Result:

Has drunk up has been organized in pulrekvest and it is sent to the oci8Pdo yjeroen developer. When the problem was googled, many unresolved questions on this subject have been noticed. I hope, my experience will help somebody.

https://github.com/yjeroen/oci8Pdo

http://developers-club.com/posts/267609/

https://habrahabr.ru/post/267609/

Working with LOBs in Oracle and PHP 

http://www.oracle.com/technetwork/articles/fuecks-lobs-095315.html

0 0