php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80705 If you unset a class property, the __get remembers the original type.
Submitted: 2021-02-03 19:31 UTC Modified: 2021-02-03 19:47 UTC
From: vali dot dr at gmail dot com Assigned: nikic (profile)
Status: Not a bug Package: Scripting Engine problem
PHP Version: 8.0.1 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: vali dot dr at gmail dot com
New email:
PHP Version: OS:

 

 [2021-02-03 19:31 UTC] vali dot dr at gmail dot com
Description:
------------
If you unset a property on a class, the __get magic method gets called (good), but it's return must match the original, now unset, property type. (bug?)

There should be a way to fully remove that property, either by reflection or unset (including the return time)

Test script:
---------------
<?php declare(strict_types=1);

class Sample {

    public int $foo = 123;      # Start as in INT
    public function __construct() {
        unset($this->foo);     # Remove the property
    }

    public function __get(string $name) {   # Gets called, since `foo` dies not exist.
        echo "__GET\n";                     # Validate that it's called
        return "string";                    # Cannot return string since foo was an int...
    }

}

$test = new Sample();
echo $test->foo; # Throws error, since __get returns a string instead of an int

Expected result:
----------------
__GET
string

Actual result:
--------------
__GET
PHP Fatal error:  Uncaught TypeError: Cannot assign string to property Sample::$foo of type int in ... .php:18
Stack trace:
#0 {main}
  thrown in ...


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-02-03 19:34 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2021-02-03 19:34 UTC] nikic@php.net
This is not a bug. By design, it is impossible to bypass property types in *any* way, including via __get.

This is also specified at https://wiki.php.net/rfc/typed_properties_v2#overloaded_properties.
 [2021-02-03 19:34 UTC] vali dot dr at gmail dot com
-Status: Closed +Status: Open
 [2021-02-03 19:34 UTC] vali dot dr at gmail dot com
https://wiki.php.net/rfc/typed_properties_v2#overloaded_properties
There should be a way to unset the property or change it's type using reflection.

Useful when arrays get replaced with a class implementing ArrayAccess, Iterator, Countable, JsonSerializable
 [2021-02-03 19:47 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2021-02-03 19:47 UTC] nikic@php.net
Sorry, this will not be supported.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Jul 02 11:01:36 2025 UTC