php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77399 __get and __set defined in traits can't access private variables from class
Submitted: 2019-01-02 15:50 UTC Modified: 2019-01-03 08:22 UTC
From: cfrenette at azorus dot com Assigned:
Status: Duplicate Package: *General Issues
PHP Version: 7.3.0 OS: Windows 10 18305
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: cfrenette at azorus dot com
New email:
PHP Version: OS:

 

 [2019-01-02 15:50 UTC] cfrenette at azorus dot com
Description:
------------
If you have a __get or __set method defined in a trait, they can no longer access private/protected variables defined in the class that implements them.  This worked < 7.3.

I wasn't able to find any information on this breaking change in the PHP 7.3 changelog.

Test script:
---------------
trait T {
  public function __test($name) {
    return $this->$name;
  }
}

class Test {
  use T;

  private $test = 'asdf';
}

$test = new Test();
echo $test->test;


Expected result:
----------------
'asdf' is echoed.

Actual result:
--------------
PHP Warning:  Uncaught Error: Cannot access private property Test::$test in php shell code:1

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-01-02 16:05 UTC] levim@php.net
Example on 3v4l: https://3v4l.org/97X3q
 [2019-01-02 16:10 UTC] mega6382 at mega6382 dot me
Your example doesn't show __get, it shows __test, which can be correctly used like this https://3v4l.org/M8BtH
 [2019-01-02 16:10 UTC] danack@php.net
-Status: Open +Status: Feedback
 [2019-01-02 16:10 UTC] danack@php.net
Hi,

I'm quite confused by your example, in particular:

i) Your code doesn't include __get, which is what I think you were reporting.

ii) The code in your example works the same on 7.3 as previous versions of PHP - https://3v4l.org/97X3q

iii) What I think you're reporting, does work on 7.3: https://3v4l.org/5p6u3

Please can you clarify what you're reporting.
 [2019-01-02 18:59 UTC] cfrenette at azorus dot com
-Status: Feedback +Status: Open
 [2019-01-02 18:59 UTC] cfrenette at azorus dot com
My mistake, I did mistype the code I was using to reproduce this in immediate mode, and using the correct method name does indeed fix it.

However, in my actual code that is using the magic methods, it's not working on 7.3, but is working on 7.2 and 7.1.  You can see a failing build here: https://travis-ci.org/BapCat/Propifier/builds/474430892

Code is here: https://github.com/BapCat/Propifier/blob/master/src/PropifierTrait.php#L206
Failing test is here: https://github.com/BapCat/Propifier/blob/master/tests/PropifierTraitTest.php#L25

The trait takes protected methods (like getXyz() and/or setXyz()) and turns them into strongly-typed properties (like $obj->xyz).

I don't believe it's a bug in the code, since it runs normally on 7.1/7.2 (and was running fine on earlier versions before adding type hints, etc.)
 [2019-01-02 19:05 UTC] corey at narwhunderful dot com
I think it's worth noting that if I change the name of the private variable to something different than the magic method name, it starts working.

e.g.
// This does not work
private $test;

protected function getTest() {
  return $this->test;
}
//

// This DOES work
private $_test;

protected function getTest() {
  return $this->_test;
}
//
 [2019-01-02 19:07 UTC] spam2 at rhsoft dot net
what about provide a tiny *standalone* but *complete* reproducer starting with <?php and ending with ?>
 [2019-01-02 20:31 UTC] cfrenette at azorus dot com
Okay, here we go, found a simple reproduction.

https://3v4l.org/0OAve

Looks like in 7.3, the __set method from the trait isn't being called at all.
 [2019-01-03 08:22 UTC] nikic@php.net
-Status: Open +Status: Duplicate
 [2019-01-03 08:22 UTC] nikic@php.net
Thanks for providing the simplified reproduce case. I tested locally and the code works currently in current 7.3 snapshot -- this bug has been fixed in bug #77291 and will be part of PHP 7.3.1.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Nov 06 20:01:29 2024 UTC