Last active
August 29, 2015 14:13
-
-
Save aercolino/b5d34a75bfb2a21d121a to your computer and use it in GitHub Desktop.
Proof of concept for WordPress bug #30891: Unchecked property overloading is detrimental to OOP.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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