runkit
runkit copied to clipboard
runkit_method_* doesn't work for internal classes like PDO
Even if flag runkit.internal_override=1. Is it possible to enable it?
Do you have a short reproduce code?
Sure, the code
if (!runkit_method_rename('PDO', 'query', '__query')) {
throw new RuntimeException('Failed to rename PDO::query to PDO::__query');
}
produces an exception and a warning
PHP Warning: runkit_method_rename(): class PDO is not a user-defined class
For example, this is being checked here https://github.com/zenovich/runkit/blob/master/runkit_methods.c#L132. Is it possible to remove this condition and allow to modify any classes?
ptrofimov : did you try to remove the condition ? Did it work ?
I just tried to remove the three conditions on internal method and internal function into this file : and it worked. But it's dangerous ! For now :
- if you
runkit_method_rename('PDO', 'query', '__query')
, don't forget to get it back before the end of your script with arunkit_method_rename('PDO', '__query', 'query')
, or your next executions of the same script will give you beautiful crashes or seg fault. - if your script stops because of errors before your "reverse rename", you'll get the same problem. Or consider using of php as CGI instead of apache MODULE (as CGI php will be clause when the scripts ends, and a real new php will start on the next call of your script. Slower but this is a working patch for this kind of problem).
The commit that does that : https://github.com/baptistepillot/runkit/commit/409e270eed7bd4fc906602bf5e502626bc6d1581 Beware : this is a dangerous classified patch !
Would be great if this could be toggle without patching the source. If there is a way to wrap core classes instead that would help as well. Example: That a
new PDO(...)
returns a custom class instead which can then include logging or other logic.
I'm not sure if it helps anyone, but I'm running into a similar problem that I think this would resolve. We're trying to test Time based functionality, and while runkit can override functions like time()
without problem, it cannot do the same for \DateTime()
. I'm instead using this little hack:
// First, override time() using runkit
$now = new \DateTime();
$now->setTimestamp(time());
This ensures the \DateTime
is set to the mocked time
value.
If there was an easy way to override \DateTime
that'd be marvellous (or an alternative way to address this would be great)?
For the record: that had already been reported as https://bugs.php.net/bug.php?id=57330.