Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Proof of concept for WordPress bug #30891: Unchecked property overloading is detrimental to OOP.
// Proof of concept for WordPress bug #30891: Unchecked property overloading is detrimental to OOP.
class CheckedOverloading {
public $legacy_public = 'legacy_public';
protected $legacy_protected = 'legacy_protected';
private $legacy_private = 'legacy_private';
//...
public $fresh_public = 'fresh_public';
protected $fresh_protected = 'fresh_protected';
private $fresh_private = 'fresh_private';
//...
protected $legacy_properties = 'legacy_public legacy_protected legacy_private';
protected function init_legacy_properties() {
$this->legacy_properties = array_fill_keys(explode(' ', $this->legacy_properties), true);
$reflector = new ReflectionClass($this);
foreach ($this->legacy_properties as $name => &$value) {
$property = $reflector->getProperty($name);
$value = $property->isPublic() ? 'public' : ($property->isProtected() ? 'protected' : 'private');
}
}
public function __construct() {
$this->init_legacy_properties();
}
public function __get( $name ) {
if (! array_key_exists($name, $this->legacy_properties)) {
if (property_exists($this, $name)) {
_too_wrong_access('Cannot access non-public property %1$s::$%2$s. (since %3$s)', __CLASS__, $name, '4.2');
}
return $this->$name; // make if fail as expected
}
if ($this->legacy_properties[$name] !== 'public') {
_wrong_access('Public access to %4$s property %1$s::$%2$s is deprecated. (since %3$s)', __CLASS__, $name, '4.2', $this->legacy_properties[$name] );
}
return $this->$name; // make it succeed as expected
}
}
function _wrong_access( $message, $class, $member, $version, $modifier ) {
trigger_error( sprintf( $message, $class, $member, $version, $modifier ), E_USER_NOTICE );
}
function _too_wrong_access( $message, $class, $member, $version ) {
trigger_error( sprintf( $message, $class, $member, $version), E_USER_ERROR );
}
$object = new CheckedOverloading();
echo "$object->legacy_public\n";
echo "$object->legacy_protected\n";
echo "$object->legacy_private\n";
echo "\n";
echo "$object->fresh_public\n";
echo "$object->non_existent\n";
//echo "$object->fresh_protected\n";
echo "$object->fresh_private\n";
// /usr/bin/php /.../checked_overloading.php
// legacy_public
// legacy_protected
// legacy_private
//
// fresh_public
//
// PHP Notice: Public access to protected property CheckedOverloading::$legacy_protected is deprecated. (since 4.2) in /.../checked_overloading.php on line 45
// PHP Stack trace:
// PHP 1. {main}() /.../checked_overloading.php:0
// PHP 2. CheckedOverloading->__get() /.../checked_overloading.php:57
// PHP 3. _wrong_access() /.../checked_overloading.php:38
// PHP 4. trigger_error() /.../checked_overloading.php:45
// PHP Notice: Public access to private property CheckedOverloading::$legacy_private is deprecated. (since 4.2) in /.../checked_overloading.php on line 45
// PHP Stack trace:
// PHP 1. {main}() /.../checked_overloading.php:0
// PHP 2. CheckedOverloading->__get() /.../checked_overloading.php:58
// PHP 3. _wrong_access() /.../checked_overloading.php:38
// PHP 4. trigger_error() /.../checked_overloading.php:45
// PHP Notice: Undefined property: CheckedOverloading::$non_existent in /.../checked_overloading.php on line 35
// PHP Stack trace:
// PHP 1. {main}() /.../checked_overloading.php:0
// PHP 2. CheckedOverloading->__get() /.../checked_overloading.php:62
// PHP Fatal error: Cannot access non-public property CheckedOverloading::$fresh_private. (since 4.2) in /.../checked_overloading.php on line 49
// PHP Stack trace:
// PHP 1. {main}() /.../checked_overloading.php:0
// PHP 2. CheckedOverloading->__get() /.../checked_overloading.php:66
// PHP 3. _too_wrong_access() /.../checked_overloading.php:33
// PHP 4. trigger_error() /.../checked_overloading.php:49
//
// Process finished with exit code 255
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.