Reputation: 111829
In PHP manual we can read:
If a trait defines a property then a class can not define a property with the same name unless it is compatible (same visibility and initial value), otherwise a fatal error is issued. Before PHP 7.0.0, defining a property in the class with the same visibility and initial value as in the trait, raised an E_STRICT notice.
There's also an example:
<?php
trait PropertiesTrait {
public $same = true;
public $different = false;
}
class PropertiesExample {
use PropertiesTrait;
public $same = true; // Strict Standards
public $different = true; // Fatal error
}
?>
Let's play around with this and remove $different property and set different value to $same property (everything tested in PHP 7.1).
<?php
trait PropertiesTrait {
public $same = true;
}
class PropertiesExample {
use PropertiesTrait;
public $same = 2;
}
?>
According to the docs it should cause fatal error, but in fact it doesn't. But as soon as we change for example true
to false
it will again cause fatal error.
It seems that it doesn't work exactly as it is described in documentation - it seems that some casts are made before comparison. However it could be very tricky because it could lead to some unexpected behaviour, for example:
trait PropertiesTrait
{
public $same = true;
public function message()
{
if ($this->same === true) {
return "A";
}
return "B";
}
}
class PropertiesExample
{
use PropertiesTrait;
public $same = 2;
}
$example = new PropertiesExample();
echo $example->message();
when analysing trait code, you would expect that message()
method will return A
as according to documentation it's not possible to override this property with different value but it seems because of casts in fact it is.
So the question is - is it a bug or maybe it's desired way it works and where can we read in PHP manual about those casts for traits properties?
Upvotes: 1
Views: 169
Reputation: 111829
It seems to be bug. I've reported it here: https://bugs.php.net/bug.php?id=74269
According to comment added:
The conflict detection logic uses zend_operator's compare_function, which does loose comparisons. The original RFC doesn't say whether to be strict or loose but I think the intention is that it would be strict.
Upvotes: 1