SQLSTATE[IM001]: Driver does not support this function: driver does not support quoting when using the driver pdo_odbc on php 8.0.1
emenshov opened this issue ยท 24 comments
What steps will reproduce the problem?
The pdo_odbc driver does not support the PDO :: quote method, which follows from the documentation https://www.php.net/manual/ru/pdo.quote.php
It is advised to use prepared queries instead. But, when using the IN construct in QueryBuilder, for example -> where (['in', 'wp.this_url', $ genreUrls])
, the quoteValue
call occurs implicitly, which ultimately results in a driver does not support error call quoting.
I suggest adding a check in quoteValue and quoteValueWithType if the odbc driver does not call PDO :: quote
Additional info
Q | A |
---|---|
Yii version | 1.1.23 |
PHP version | 8.0.1 |
Operating system |
@emenshov Could you please update this issue to english?
I cannot reproduce this issue. Could you post the full input, error message and stack trace?
In theory the implementation looks fine: According to the PHP documentation PDO::quote()
will return false
when the method is not supported by the driver, and CDbConnection::quoteValue()
and quoteValueWithType()
handle this case with a fallback quote mechanism (https://github.com/yiisoft/yii/blob/master/framework/db/CDbConnection.php#L581). No error or exception should be thrown.
@emenshov Thank you for the additional info.
The root cause here seems to be the PDO_ODBC driver. Since quoting isn't supporting for this driver calling PDO::quote() should return false, but that is not happening and a PDOException is thrown instead. Check if your driver is up-to-date and otherwise file a bug with PHP: https://bugs.php.net/
@marcovtwout I started a bug. But they explained to me that in php 8 this is not a bug, but standard behavior
https://bugs.php.net/bug.php?id=80754&edit=2
Can you reopen issue?
Reopened and added additional question to the PHP bug.
@emenshov Could you perhaps check if you encounter the same bug in Yii 2? Its implementation also seems to rely on PDO::quote() to return false if the driver does not support it: https://github.com/yiisoft/yii2/blob/920fda176a4b09e3f1c0b501eb7a9a00e992d35f/framework/db/Schema.php#L463
@marcovtwout Yes, same issue
It seems the error cannot be suppressed because of bug https://bugs.php.net/bug.php?id=71941
I'm not sure if this should be fixed on the PHP side or have a workaround applied on the framework side. I suggest to report this issue in the Yii 2 issue tracker as well. Whatever solution is chosen there, I will consider to apply here.
What kind of workaround would fix it?
@samdark a PHP ODBC specific check, that skips calling pdo::quote() and calls the fallback implementation directly. But personally I would consider this something that should be fixed on the PHP or PHP ODBC Driver side.
I'd apply the fix. It is unlikely to be fixed fast in either PHP or ODBC driver.
@samdark @marcovtwout What do you think about this solution?
Yii1:
if (version_compare(PHP_VERSION, '8.0.0', '>=') && strpos(mb_strtolower($this->connectionString), 'odbc:') !== false) {
return "'" . addcslashes(str_replace("'", "''", $str), "\000\n\r\\\032") . "'";
}
Yii2:
if (version_compare(PHP_VERSION, '8.0.0', '>=') && strpos(mb_strtolower($this->db->dsn), 'odbc:') !== false) {
return "'" . addcslashes(str_replace("'", "''", $str), "\000\n\r\\\032") . "'";
}
OK. That seems to be good enough.
Yes. Please.
@emenshov I don't think the PHP8 condition is actually neccessary. You can check the driver name with https://www.yiiframework.com/doc/api/1.1/CDbConnection#getDriverName-detail instead of doing string matching yourself. Finally you can avoid duplicate fallback code by structuring the whole thing something like this:
if (drivername !== 'obdc')
if ($value = pdo::quote() !== false)
return $value
return addcslashes fallback
@marcovtwout It works correct
Fixed with #4352