Closed emenshov closed 3 years ago
@emenshov Could you please update this issue to english?
@emenshov Could you please update this issue to english?
done
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.
@marcovtwout
@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") . "'";
}
@emenshov are you 100% sure that addcslashes()
esapes the input as intended?
@emenshov are you 100% sure that
addcslashes()
esapes the input as intended?
Yes, it works correct on php 7.4 with odbc driver
OK. That seems to be good enough.
@samdark Should I prepare pull request?
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
@emenshov Please check if https://github.com/yiisoft/yii/pull/4352 fixes your problem.
@marcovtwout It works correct
Fixed with https://github.com/yiisoft/yii/pull/4352
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])
, thequoteValue
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