📜 ⬆️ ⬇️

Expansion Yii 1.1 oci8Pdo and CLOB / BLOB parameters band

In my company there is a project that is built on Yii 1.1 and uses an Oracle 9g database. To work with the base extension is used oci8Pdo .

Recently there was the task of loading scans to the database in the BLOB field. Since The author of the extension writes:
99% of the PDO functions.
there were few reasons to doubt the implementation of this functionality.

Try to download 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 it was not there: ORA-01465: invalid hex number.

They began to smoke the problem and came across the implementation of the bindParam method in the Oci8PDO_Statement class of the above-described extension:

 <?php public 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 $ data_type argument is accepted, but not processed anywhere. So it turns out that CLOB or BLOB will not be recorded. There was nowhere to go, I had to finish the oci8Pdo.

In the class Oci8PDO which is inherited from PDO, constants and a method of pulling out the connection resource to the DB have been added:

 <?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 we finished the bindParam method a bit in the Oci8PDO_Statement class:

 <?php public 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 the CLOB / BLOB processing is successful:

 <?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(); ?> 

Total:

Dopil was organized in a pullwalk and sent to the developer oci8Pdo yjeroen . When the problem was googled, many unresolved issues on this topic were noticed. I hope my experience will help someone.

PS: I will be glad to criticism and constructive comments in the comments.

Source: https://habr.com/ru/post/267609/


All Articles