-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PHP 8.4.0RC4: Zend Observer does not work for PDO query() method when the new PDO connect() is used #16857
Comments
As of PHP 8.4.0, there are now possibly driver specific subclasses (implemented for all PDO extension in php-src; not necessarily for external PDO extensions). Calling That means, that your extension will not only fail for I don't think there is anything to do in php-src. |
I am able to reproduce the issue with a sample PHP extension that overwrites function handlers for pdo_test_php_scripts.zip The results are same as we reported with our extension. Here is the source code and prebuilt extension binary: reprod_source_and_sharedlib.zip. Hope this helps. |
@sjayexec As @cmb69 noted, it's related to the driver-subclasses. Thanks to inheritance, the internal_function is copied onto the class table of the PdoSqlite subclass ( |
Maybe there is, namely to document the details of inheritance (and trait composition). Especially that an inherited function is actually copied, is not necessarily what a programmer might assume who is used to VMTs. |
I think I understand now. So, I might have been thrown off by the fact that even when query() method is being executed from So, we should have to explicitly overwrite the function handlers of all possible PDO driver specific class entries of any given PDO method we want to overwrite. Thanks a lot for your answers and inputs, it is of great help. Appreciate it! :) |
Description
Problem Description
We have a custom PHP extension that registers as an observer for PDO extension's methods like
__construct()
,query()
, etc., and our extension's handler functions get invoked when any of these PDO methods are being executed. This code is pretty generic from our side and is the same for all PDO methods we observe. But starting from PHP 8.4.0, our observer functions/function handlers are not being invoked when PDOquery()
method is being executed (when connect() is used) - the execution directly goes to PDOquery()
method instead of our registered function handlers. There is some crucial, unexplained behavioral difference I want to highlight here considering PHP introducedconnect()
method to create PDO objects. We adapted our code to also register observer & function handler for the newconnect()
method and our function handler is being invoked correctly forconnect()
method but not forquery()
method that is executed after the connect().So:
If
PDO::__construct()
is used by PHP app, our extension's function handlers for__construct()
ANDquery()
are both correctly invoked by the Zend engine.If
PDO::connect()
is used by PHP app, onlyconnect()
function handler in our extension is invoked but not the function handler forquery()
.This is inconsistent behaviour from the Zend engine.
Just to clarify how we use Zend observer API:
During MINIT:
zend_observer_fcall_register()
to register begin and end function handlers.CG()
macro to get class entry object for "PDO" class and overwrite thezend_function->internal_function_handler
with our own function for__construct(), connect(), query()
We verified some aspects during runtime using a debugger :
zend_function->internal_function_handler
for both connect() and query() hold the pointers to our extension's overwritten function handler, not the original PDO methods. 2. InsideZEND_DO_FCALL_SPEC_OBSERVER_HANDLER()
inzend_vm_execute.h
from where these two functions/PDO methods are eventually invoked, we can see that thefbc->internal_function.handler
for duringquery()
execution holds some unresolved address - that is neither pointing tozim_PDO_query()
or our extension's overwritten function handler.Strange thing is, for the PDO
connect()
execution,fbc->internal_function.handler
does point to our extension's function handler. As I said, registering observer and overwriting function handlers for these functions in the CG hashtable is generic and has been working on PHP 8.3.PHP Version
PHP 8.4.0RC4
Operating System
No response
The text was updated successfully, but these errors were encountered: