Created
October 30, 2013 22:35
-
-
Save aheadley/7241535 to your computer and use it in GitHub Desktop.
Example of how PHP's `protected` designation is stupid and broken.
This file contains hidden or 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
$ 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 |
This file contains hidden or 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
<?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