Skip to content

Instantly share code, notes, and snippets.

@aheadley
Created October 30, 2013 22:35
Show Gist options
  • Save aheadley/7241535 to your computer and use it in GitHub Desktop.
Save aheadley/7241535 to your computer and use it in GitHub Desktop.
Example of how PHP's `protected` designation is stupid and broken.
$ php -f unprotector.php
$a->_x = you cant change me
$b->_x = you cant change me
set $b->_x = 'yes i can'
$a->_x = yes i can
<?php
define( 'UNPROTECTOR_PREFIX', 'UNPROTECTED' );
function generateUnprotector( $protectedObject ) {
$unprotectorTemplate = <<<'TPL'
class %s extends %s {
private $_protectedObject = null;
public function __construct( $protectedObject ) {
$this->_protectedObject = $protectedObject;
}
public function __get( $name ) {
return $this->_protectedObject->{$name};
}
public function __set( $name, $value ) {
return $this->_protectedObject->{$name} = $value;
}
public function __call( $name, $args ) {
return call_user_func_array(
array( $this->_protectedObject, $name ),
$args );
}
static public function __callStatic( $name, $args ) {
return $this->__call( $name, $args );
}
}
TPL;
$protectedClass = get_class( $protectedObject );
$unprotectedClass = sprintf( '%s_%s', UNPROTECTOR_PREFIX, $protectedClass );
if( !class_exists( $unprotectedClass ) ) {
eval( sprintf( $unprotectorTemplate,
$unprotectedClass, $protectedClass ) );
}
$unprotectedObject = new $unprotectedClass( $protectedObject );
return $unprotectedObject;
}
class A {
protected $_x = 'you cant change me';
protected function f( $newX ) {
return $this->_x = $newX;
}
public function g() {
return $this->_x;
}
}
$a = new A();
$b = generateUnprotector($a);
?>
$a->_x = <?php echo $a->g() ?>
$b->_x = <?php echo $b->_x ?>
set $b->_x = 'yes i can' <?php $b->_x = 'yes i can' ?>
$a->_x = <?php echo $a->g() ?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment