Skip to content

Support asymmetric visibility #182

Closed
@thekid

Description

@thekid

Add support for https://wiki.php.net/rfc/asymmetric-visibility-v2

Example

In a nutshell:

class Person {
  public private(set) string $name= 'Test';
}
 
$person= new Person();
echo $person->name;       // OK
$person->name= 'Changed'; // Visibility error

RFC status: Accepted

Quoting https://externals.io/message/124622#124838:

The final result is 24 Yes, 7 No, for a total of 77.4% in favor.

The RFC has passed. Thanks everyone for your participation and input. Ilija will get the PR merged soonish.

Rewriting

To support this in lower PHP versions, we will need to rewrite this to virtual properties, much like readonly support was implemented in #124, along the lines of the following:

class Person {
  private $_name;
  
  public function __get($name) {
    if ('name' === $name) return $this->_name;
  }

  public function __set($name, $value) {
    if ('name' === $name) {
       $caller= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1];
       $scope= $caller['class'] ?? null;

       // For private, just compare; for protected, use instanceof
       if (__CLASS__ !== $scope) {
         $from= $scope ? 'scope '.$scope : 'global scope';
         throw new Error('Cannot access private '.__CLASS__.'::$'.$name.' from '.$from);
       }

       $this->_name= $value;
    }
  }
}

$person= new Person();
echo $person->name;       // OK, triggers __get('name')
$person->name= 'Changed'; // Visibility error, triggers __set('name', 'Changed') from scope NULL

See also

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions