Bug #81258 [Com]: Strict mode not working with reflection
| From: | faulknerehman at gmail dot com | Date: | Tue, 25 Jul 2023 06:47:04 +0000 |
| Subject: | Bug #81258 [Com]: Strict mode not working with reflection | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-245025@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=81258&edit=1
ID: 81258
Comment by: faulknerehman at gmail dot com
Reported by: roke22 at gmail dot com
Summary: Strict mode not working with reflection
Status: Open
Type: Bug
Package: Unknown/Other Function
Operating System: Linux
PHP Version: 8.0.8
Block user comment: N
Private report: N
New Comment:
When you use direct assignment like $dt->name = "33"; in PHP, it performs a type check
and throws an error if the type is not compatible with the property declaration. However, when you
use Reflection to set a value, PHP does not perform strict type checking by default. This behavior
is by design and allows you to bypass type checking when using Reflection.
If you want to enforce strict type checking even when using Reflection, you can manually enable it
by calling declare(strict_types=1) inside the method that uses Reflection. Here's how you can
modify the second example to throw an error if the type is not compatible:
declare(strict_types=1);
class MyClassReflection {
public int $name;
}
$dt = new MyClassReflection();
$reflectionClass = new ReflectionClass('MyClassReflection');
$property = $reflectionClass->getProperty('name');
$property->setAccessible(true); // Make the property accessible, as it is not public
$property->setValue($dt, '33'); // Throws TypeError since '33' is a string,
not an int
var_dump($dt);
(https://github.com.php)(https://www.ballsportsgames.com/how-to-choose-pickleball-paddles/)
By using declare(strict_types=1) in the scope where you are working with Reflection, you enforce
strict typing for that part of the code, and setting a value of the wrong type will throw a
TypeError, just like in the first example.
Previous Comments:
------------------------------------------------------------------------
[2021-07-14 14:06:31] roke22 at gmail dot com
excuse my ignorance, could you give a simple example? Maybe using the case of the example script.
------------------------------------------------------------------------
[2021-07-14 13:39:39] nikic@php.net
Property assignments follow the strict_type directive of wherever the assignment is performed from.
In this case, it occurs from the ReflectionProperty::setValue() implementation, which is in
strict_types=0 mode (like all extension code). Thus type coercions are allowed.
A way to perform the assignment with strict type semantics would be by using closure rebinding.
------------------------------------------------------------------------
[2021-07-14 13:27:34] roke22 at gmail dot com
Description:
------------
Hello,
when you try to assign a value to a property of a DTO and it is not of the same type, it fails when
you do it normally.
However this does not happen when you use reflection, in this case try to convert it to the type of
the property making for example a 2 to be true for a bool property.
The expected behavior should be the same. This error throws all libraries about dto like https://github.com/spatie/data-transfer-object
because you can get the DTO with a true or false value in boolean properties where are invalid.
Test script:
---------------
This one fails and works ok
<?php
declare(strict_types=1);
class MyClassReflection {
public int $name;
}
$dt = new MyClassReflection();
$dt->name = "33";
var_dump($dt);
This one don't throw the exception but should throw the exception:
<?php
declare(strict_types=1);
class MyClassReflection {
public int $name;
}
$dt = new MyClassReflection();
$reflectionClass = new ReflectionClass('MyClassReflection');
$reflectionClass->getProperty('name')->setValue($dt, '33');
var_dump($dt);
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81258&edit=1