How to deal with monostate pattern?
dereckson opened this issue · 7 comments
According the mysqli_driver class documentation:
The mysqli_driver class is an instance of the monostate pattern, i.e. there is only one driver which can be accessed though an arbitrary amount of mysqli_driver instances.
But here what's happening with psysh:
>>> $driver = new mysqli_driver()
=> mysqli_driver {#2668
+reconnect: false,
+report_mode: 0,
}
>>> $driver->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT;
=> 3
>>> new mysqli_driver
=> mysqli_driver {#2680
+reconnect: false,
+report_mode: 0,
}
At object creation stage, we can see the value for report_mode doesn't respect that monostate pattern.
That can lead to error in diagnostics and debugging.
When we print it, access it, dump it, the object has the correct value:
>>> print_r(new mysqli_driver)
mysqli_driver Object
(
[client_info] => mysqlnd 8.1.2
[client_version] => 80102
[reconnect] =>
[report_mode] => 3
)
I suspect this behavior is correct for the language: the mysqli_driver source code looks a global struct for the value when we access the report_mode variable.
But it's not optimal to print something other than the real value of the property when we'll query it.
I believe the driver doesn't deal with forking very well. Try disabling it in PsySH (add 'usePcntl' => false
to your PsySH config).
Same behavior with usePcntl at false.
Indeed, every var_dump() call reports the current state of the object.
Thanks! I'll see if I can figure out why VarDumper isn't reporting the current state.
cc @nicolas-grekas in case you have any ideas :)
That's an issue for https://github.com/symfony/symfony indeed. Please send a PR with a failing test case and a fix if you can.
Closing this in favor of symfony/symfony#45487. Thanks @dereckson!