php / doc-en

English PHP documentation
501 stars 731 forks source link

Clarifications on settype() behaviour wrt coercion and failure #2677

Open nielsdos opened 1 year ago

nielsdos commented 1 year ago

The following code:

<?php

class Foo {
    public int $value = 123;
}

$foo = new Foo;
$ref = &$foo->value;

var_dump(settype($ref, "string"));
var_dump($ref);
var_dump($foo->value);

Resulted in this output:

bool(true)
int(123)
int(123)

But I expected this output instead:

bool(false)
int(123)
int(123)

Well either bool(false) or a type error, as its supposed to return false when setting the type fails according to the documentation. Although that's probably inaccurate, as the following code:

<?php

class Foo {
    public int $value = 123;
}

$foo = new Foo;
$ref = &$foo->value;

var_dump(settype($ref, "null"));
var_dump($ref);
var_dump($foo->value);

Results in: Fatal error: Uncaught TypeError: Cannot assign null to reference held by property Foo::$value of type int. And the code for settype can only return true as far as I can see.

So there's two documentation issues:

damianwadley commented 1 year ago

Well, yes, the name is a bit of a misnomer: it doesn't literally "set the type of the variable" (which isn't even a thing in this language) but, like the code says, instead does:

// settype($var, $type)
$ptr = $var;
"convert_to_$type"($var);
$var = $ptr;

Which explains why it works with typed properties.

nielsdos commented 1 year ago

Yeah I understand why it works, it just needs better documentation (i.e. the exception, and the coercion) to reduce the "huh?" factor :-)