Sorry, accidently sent in the middle of typing that... On Wed, Mar 8, 2017 at 7:42 AM, Ryan Pallas <derokor...@gmail.com> wrote:
> > > On Wed, Mar 8, 2017 at 5:25 AM, Andrey Andreev <n...@devilix.net> wrote: > >> Hi all, >> >> I submitted a GitHub PR* to allow objects implementing __toString() to >> *optionally* pass is_string() validation. More verbose wording of my >> motivation can be seen in the PR description, but here are the main >> points: >> >> - Simpler way to do checks like: is_string($var) || >> method_exists($var, '__toString') >> - Can be used for stricter string parameter validation in >> strict_types=0 mode (otherwise any scalar type is accepted) > > - Can be used for looser string parameter validation in strict_types=1 >> mode (__toString() objects aren't accepted there) >> - Regardless of the last 2 points, it is intentionally not limited to >> parameter types >> > > If I understand correctly, you want the following to work: > > declare(strict_type = 0); function foo(string $bar) { return $bar.'foo'; } class Foo { private $val; public function __construct(string $val) { $this->val = $val; } public function __toString() { return $this->$val; } } echo foo(new Foo('this is ')); // this is foo But what happens if I change the foo function like: function foo(string &$bar) { $bar .= 'foo'; } $foo = new Foo('object'); foo($foo); var_dump($foo); // will this be an instance of Foo, or the string "objectfoo"?? If $foo remains an object in this scope, then the function is not modifying its value. If it becomes a string, it's an unexpected change IMO. It is probably fine in this case, but not in the case of a more complex object. > > > >> >> * https://github.com/php/php-src/pull/2408 >> >> --- >> >> I didn't have time to write this email right after submitting the >> patch, and in the meantime got some feedback from Fleshgrinder on >> GitHub, which I'll quote and address here: >> >> > Thanks for your effort and initiative. >> > >> > However, I strongly believe that this is the wrong approach. Adding a >> flag to a function directly results in the fact that the function violates >> the single responsibility principle. What we actually need to make this >> work is a "stringable" pseudo-type like the iterable type that was >> introduced in PHP 7.1. This "stringable" pseudo-type is the union of the >> scalar primitive string and any class that implements the __toString method. >> > >> > This has the advantage that we are actually able to use it together >> with strict_types, plus we have separate dedicated functions like >> "is_stringable" that adhere to the single responsibility principle. I >> actually wanted to create an RFC for that along with an implementation >> since iterable was accepted, but did not find the time yet. >> > >> > Closing note: these pseudo-types are necessary in PHP because it has no >> coherent type system, and there is nothing we can do about this in short >> term. Hence, adding such pseudo-types is the only short term solution that >> we actually have. >> >> I ultimately wouldn't care if it's a separate function and did in fact >> think of an is_stringable() function, but wasn't happy with the naming >> - who's to say that e.g. integers aren't stringable? Bar >> horribly-verbose names like >> "string_or_objects_implementing__toString", I don't think there's a >> way to avoid that ambiguity. :/ >> If we want a "stringable" type though, I guess we'll have to live with >> that. >> >> I feel that debating the actual type system is way broader than I >> intended this to be, so I'll refrain from going further on that for >> now, as I've got some more radical ideas about it. >> >> --- >> >> Thoughts? >> >> Cheers, >> Andrey. >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> >> >