Skip to content

Instantly share code, notes, and snippets.

@aercolino
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aercolino/b5d34a75bfb2a21d121a to your computer and use it in GitHub Desktop.
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.
// 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