View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0006892 | OXID eShop (all versions) | 4.01. Database handling | public | 2018-08-20 18:29 | 2019-10-15 13:20 |
Reporter | timwetter | Assigned To | |||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | 6.1.0 | ||||
Target Version | 6.2.0-rc.1 | Fixed in Version | 6.2.0-rc.1 | ||
Summary | 0006892: oxDB:: quoteArray & getTableDescription breaks $ADODB_FETCH_MODE | ||||
Description | there are many ways to break db fetch_mode, but one example do this in one function: - on top write $oDb = oxDb::getDb(true); - make a oxlist - call selectString with a wildcard (e.g. "select * from oxarticles limit 55") - after that do something like this in the same function: $rs = $oDb->execute("select oxartnum, oxtitle from oxarticles"); if ($rs != false && $rs->recordCount() > 0) { while (!$rs->EOF) { print_r($rs->fields) // look at the numeric fields -> but they should be assoc } } please have a look @"additional information" to see my fix for this maybe you'll find more of this bullsh* | ||||
Additional Information | /** * Quotes an array. * * @param array $aStrArray array of strings to quote * * @return array */ public function quoteArray( $aStrArray) { global $ADODB_FETCH_MODE; $save = $ADODB_FETCH_MODE; foreach ( $aStrArray as $sKey => $sString ) { $aStrArray[$sKey] = self::getDb()->quote($sString); } // restore fetchmode $ADODB_FETCH_MODE = $save; return $aStrArray; } /** * Extracts and returns table metadata from DB. * * @param string $sTableName Name of table to invest. * * @return array */ public function getTableDescription( $sTableName ) { // simple cache if ( isset( self::$_aTblDescCache[$sTableName] ) ) { return self::$_aTblDescCache[$sTableName]; } global $ADODB_FETCH_MODE; $save = $ADODB_FETCH_MODE; $aFields = self::getDb()->MetaColumns( $sTableName ); // restore fetchmode $ADODB_FETCH_MODE = $save; self::$_aTblDescCache[$sTableName] = $aFields; return $aFields; } | ||||
Tags | No tags attached. | ||||
Theme | Not defined | ||||
Browser | Not defined | ||||
PHP Version | Not defined | ||||
Database Version | Not defined | ||||
|
Script to reproduce (execute it in bin/):<?php echo PHP_EOL . 'fetch mode test.' . PHP_EOL; require_once '../bootstrap.php'; $db = \OxidEsales\Eshop\Core\DatabaseProvider::getDb(); echo 'set fetch mode to assoc (equals string)'; echo PHP_EOL; $db->setFetchMode(\OxidEsales\Eshop\Core\Database\Adapter\DatabaseInterface::FETCH_MODE_ASSOC); $query = 'select oxid from oxuser limit 1'; $a = $db->getAll($query); echo 'get fetch mode: '; echo gettype(key($a[0])); echo PHP_EOL; echo 'execute some native methods... '; echo PHP_EOL; $c = oxNew(\OxidEsales\Eshop\Application\Model\Category::class); $c->load('0f40c6a077b68c21f164767c4a903fd2'); $s = oxNew(\OxidEsales\Eshop\Application\Model\SeoEncoderCategory::class); $s->markRelatedAsExpired($c); $a = $db->getAll($query); echo 'get fetch mode: '; echo gettype(key($a[0])); echo PHP_EOL; echo 'test done.' . PHP_EOL; MK |
|
This bug was fixed in version 6.2, but it is still lives in version 6.1 and for handling that the best solution is using "setFetchMode" method before using "getAll" or "getOne" methods. Therefore fetch_mode will be set before fetching data from database. For example: $c = oxNew(\OxidEsales\Eshop\Application\Model\Category::class); $c->load('0f40c6a077b68c21f164767c4a903fd2'); $s = oxNew(\OxidEsales\Eshop\Application\Model\SeoEncoderCategory::class); $s->markRelatedAsExpired($c); $db->setFetchMode(DatabaseProvider::FETCH_MODE_NUM); $a = $db->getAll($query); In version 6.2, DatabaseProvider was deprecated and replaced by OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface. So there is not this bug anymore. |