On 3/18/2016 11:10 PM, Dennis Birkholz wrote: > Hi all, > > Am 16.03.2016 um 21:29 schrieb Fleshgrinder: >> Another more complicated user case would be *mysqli_fetch_object* that >> populates the properties with values from a storage but values that >> should become something specific and strict at some point but are >> initially populated as strings. Type coercion would be a nice thing here >> but with strict checks afterwards. > > I really don't like the special way mysqli and PDO use here. > Both should use the __set_state() magic method as would any userland code. > But that is a discussion for another thread ;-) > > Greets > Dennis >
I think the discussion is important here because the introduction of typed properties as proposed would break exactly this functionality of a few of the most used extensions of all. That being said, I agree and disagree at the same time with you on *__set_state*. I also would prefer it if these methods would call another method because they always require a check: final class A { private $x; private $y; private function __construct(O $x = null, O $y = null) { // mysqli_result::fetch_object // PDOStatement::fetchObject if (isset($this->x)) { $this->x = new O($this->x); $this->y = new O($this->y); } else { assert(isset($x)); assert(isset($y)); $this->x = $x; $this->y = $y; } // Some assertions on $x and $y ... } public static function new($x, $y, ErrorNotifier $n) { // Expensive validation ... return new static($x, $y); } public static function __set_state(array $data) { return new static($data['x'], $data['y']); } } Of course there are other ways to implement this. I just want to illustrate that it is not an ideal situation if we want to keep our code as DRY as possible while using automated type checks without assertions. But back to the *__set_state* problem. *__set_state* expects that the members of the passed array are fully initialized because it is the inverse of *var_export*. The data that is provided by *mysqli_result::fetch_object* and *PDOStatement::fetchObject* are not fully initialized so they are not good candidates to use *__set_state*. Using another magic method would solve the riddle: final class A { private $x; private $y; private function __construct(O $x, O $y) { // Some assertions on $x and $y ... $this->x = $x; $this->y = $y; } public static function new($x, $y, ErrorNotifier $n) { // Expensive validation ... return new static($x, $y); } // mysqli_result::fetch_object // PDOStatement::fetchObject public static function __init_state(array $data) { return new static(new O($data['x']), new O($data['y'])); } public static function __set_state(array $data) { return new static($data['x'], $data['y']); } } Both examples might be bad but they are everything I just could come up with. TL;DR *__set_state* is not the correct method in this case because it is the inverse of *var_export* and expects all members to be fully initialized what is definitely not the case for both *mysqli_result::fetch_object* and *PDOStatement::fetchObject*. -- Richard "Fleshgrinder" Fussenegger
signature.asc
Description: OpenPGP digital signature