Re: [Discussion] is_string(), string type and objects implementing __toString()
| From: | Andrey Andreev | Date: | Wed, 08 Mar 2017 15:26:32 +0000 |
| Subject: | Re: [Discussion] is_string(), string type and objects implementing __toString() | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-98430@lists.php.net to get a copy of this message | ||
Hi Ryan,
On Wed, Mar 8, 2017 at 5:15 PM, Ryan Pallas <derokorian@gmail.com> wrote:
> Sorry, accidently sent in the middle of typing that...
>
> On Wed, Mar 8, 2017 at 7:42 AM, Ryan Pallas <derokorian@gmail.com> wrote:
>>
>>
>>
>> On Wed, Mar 8, 2017 at 5:25 AM, Andrey Andreev <narf@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.
This already works and while the reference thing is indeed ugly, the
problems I have with it are different:
1) It also accepts every other scalar type.
2) It will not work with strict_types=1.
3) I want to do it mid-runtime, not just on function parameters.
Cheers,
Andrey.