Install Joomla with mysqlpdo. Create a query using fetch_assoc().
working query
PHP Fatal error: Call to undefined method PDOStatement::fetch_Assoc()
Joomla 3.4 using pdomysql
php 5.4.3
mysql 5.5.3.8
The pdo.php contains that protected function
protected function fetchAssoc($cursor = null)
{
if (!empty($cursor) && $cursor instanceof PDOStatement)
{
return $cursor->fetch(PDO::FETCH_ASSOC);
}
if ($this->prepared instanceof PDOStatement)
{
return $this->prepared->fetch(PDO::FETCH_ASSOC);
}
}
But if using with database type MySQL (PDO) it produces an error
The mysqlpdo should normally provide nearly the same features as the native pdo. If it is mysqli it even offers prepared statements.
Just but there is a Joomla layer before you get to raw pdo - so that needs testing.
Please can you provide a Gist of PHP code that is failing because of this? I would like to see your example.
Priority | Critical | ⇒ | Medium |
You create a query like:
$q = 'SELECT * FROM #__any_table';
$db->setQuery($q);
if($cursor = $db->execute($q)) {
while($var=$cursor->fetch_Assoc()) {
$q='INSERT into #__another_table….';
$db->setQuery($q);
$db->execute();
}
}
Those queries are quite common for insert, delete, update a.s.o..
I think that with a prepared statement it will produce the same error!
I think this is more likely to be you using unpublished API - as no where in the Joomla Core code do we use ->fetch_Assoc()
Maybe you should use something like:
$q = 'SELECT * FROM #__extensions';
$db->setQuery($q);
$var = $db->loadAssoc(); // Generate an associative array of the first row
var_dump($var);
Which works with pdomysql
doc: https://docs.joomla.org/JDatabase/loadAssoc
You should be interacting with the Joomla API and not trying to bypass that and run PDO commands generically :)
or even loadAssocList
see: https://docs.joomla.org/JDatabase/loadAssocList
which is what I think you really want :)
Working with a cursor is a common way. PDO does not produce such an error doing so. I think only pdomysql produces that problem. The difference between your suggested loadAssocList and the other way is that AssocList does produce memory limit errors on large database tables while the other way does NOT produce memory errors. You produce a query and executing it delivers jAust the values for the cursor. LoadAssocList will load the whole query with all table values. Of code you you can limit the result set but you need more code to achieve the same result. If all database layers allow to use it except of the pdomysql, I would say that pdomysql has a problem.
The error is right in that there isn't a fetch_Assoc
method on the PDOStatement
object. In your code, try replacing the while with this: $var = $cursor->fetch(PDO::FETCH_ASSOC)
.
This is the Joomla project, you are using the Joomla database object - NOT raw PDO.
If you want to use raw PDO commands then you can create a raw pdo connection, but as it is the Joomla Database API provides an interface to the parts of PDO (and other drivers) that it needs to for its own use, and the major user cases.
From what I can see (in bed!) none of the Joomla database drivers give you raw access to fetch_Assoc() functions at all, only though loadAssocList
and loadAssoc
The Joomla Database Driver for PDO does have this function
which doesnt look like its available in any other Joomla Database DriverAlso, FWIW, it seems you should be able to do this using Joomla's PDO wrapper (untested, but just reading code it makes sense).
Instead of your while($var=$cursor->fetch_Assoc()) use while($var = $db->loadNextAssoc())
Admittedly the PDO API isn't one I'm too familiar with right now, but I think this gives you roughly the same features. Of course, I could be wrong and not realize it.
Labels |
Added:
?
|
Thanks mbabker. Just thought it would make sense to keep the pdomysql compatible with the other db layers from joomla. By default, all contain the possibility to use fetchAssoc or fetchObject with cursor.
From what I can tell, none of the drivers allow public access to the fetchAssoc or fetchObject methods (they all are protected) so you'd need to go through one of our public APIs to get to those. Of course with a cursor, it seems you'd be able to bypass our API and use the direct database API for the object (like mysqli_fetch_assoc). At a glance I'm not seeing anything about the PDO based classes that's different from their non-PDO counterparts, but considering the class is derived from the Framework, I guess it's possible there could be a difference we missed somewhere.
Michael, thanks for your patience with me. What I do not understand is that Joomla (for example the mysqli driver) does the following thing:
protected function fetchAssoc($cursor = null)
{
return mysqli_fetch_assoc($cursor ? $cursor : $this->cursor);
}
I understand that with my method I deliver values to return mysqli_fetch_assoc($cursor ? $cursor : $this->cursor); and not to protected function fetchAssoc($cursor = null). It would be more useful, just my humble opinion, to allow to set the cursor to some value, if desired, instead to use null as fixed.
But maybe I tell something wrong.
Since those methods are all protected, the only way you'd really be able to use them right now is to subclass our database classes. I do agree with being able to supply your own data into them (and you can within the right scope), but to do it external to the database classes requires us to make those methods public instead of protected.
Agree with you.
So can this be closed as an issue bug against Joomla now?
I think so. If anything we're looking at a feature proposal/API change (making the fetch* methods public versus protected) at this point.
Status | New | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2015-03-06 17:20:02 |
another myslq pdo issue /me will take a look shortly...