Skip to content

Instantly share code, notes, and snippets.

@romanitalian
Last active October 31, 2015 15:25
Show Gist options
  • Save romanitalian/2b646ee430e56b70e3e4 to your computer and use it in GitHub Desktop.
Save romanitalian/2b646ee430e56b70e3e4 to your computer and use it in GitHub Desktop.
Use of private methods in PHP - "outside"
<?php
class MyClass
{
private function privateMethod($args) {
return $args;
}
function callPrivate($object, $method, $args) {
$caller = function ($method, $args) {
return call_user_func_array([$this, $method], $args);
};
$caller->bindTo($object, $object);
return $caller($method, $args);
}
}
$privacyViolator = new MyClass();
$t = $privacyViolator->callPrivate(new stdClass(), 'privateMethod', ['world use_Closure_bindTo']);
var_dump($t);
<?php
class MyClass
{
private function privateMethod($args) {
return $args;
}
}
function callPrivateMethod($object, $method, $args) {
$classReflection = new \ReflectionClass(get_class($object));
$methodReflection = $classReflection->getMethod($method);
$methodReflection->setAccessible(true);
$result = $methodReflection->invokeArgs($object, $args);
$methodReflection->setAccessible(false);
return $result;
}
$t = callPrivateMethod(new MyClass(), 'privateMethod', ['world with ReflectionClass']);
var_dump($t);
<?php
class PrivacyViolator
{
public function callPrivateMethod($object, $method, array $args = array()) {
if(!is_object($object)) {
throw new \InvalidArgumentException('The $object param must be object');
}
$className = get_class($object);
$method = new \ReflectionMethod($className, $method);
$method->setAccessible(true);
return $method->invokeArgs($object, $args);
}
}
class MyClass
{
private function hello($name) {
return 'Hello '.$name;
}
}
$myObject = new MyClass();
$privacyViolator = new PrivacyViolator();
$result = $privacyViolator->callPrivateMethod($myObject, 'hello', array('World'));
echo $result;
assert('Hello World' === $result);
<?php
trait DynamicDefinition
{
public function __call($name, $args) {
if(is_callable($this->$name)) {
return call_user_func($this->$name, $args);
} else {
throw new \RuntimeException("Method {$name} does not exist");
}
}
public function __set($name, $value) {
$this->$name = is_callable($value) ?
$value->bindTo($this, $this) :
$value;
}
}
class Foo
{
use DynamicDefinition;
private $privateValue = 'I am private';
}
$foo = new Foo;
$foo->bar = function () {
return $this->privateValue;
};
var_dump($foo->bar()); // 'I am private'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment