我創建不是很複雜的測試代碼(在PHP 5.5.12測試):可贖回和倒閉
<?php
class Test
{
private $cached = null;
public function __construct()
{
$this->cached = [];
$this->cached[0] = 12;
}
function wrap($function, $index)
{
if (isset($this->cached[$index])) {
return $this->cached[$index];
}
$result = call_user_func($function);
return $result;
}
}
class B
{
public function run()
{
$x = 6;
$obj = new Test();
$value = $obj->wrap(
function() use ($x) {
return $this->test($x);
},
1
);
echo $value."<br />";
}
protected function test($x)
{
echo "I'm running ";
return $x * $x;
}
}
class C extends B
{
public function run()
{
$x = 6;
$obj = new Test();
$myFunc = function() use ($x) {
return $this->test($x);
};
$value = $obj->wrap($myFunc, 1);
echo $value."<br />";
}
}
class D extends B
{
public function run()
{
$x = 6;
$obj = new Test();
$value = $obj->wrap(array($this, 'test'), 1);
echo $value."<br />";
}
}
$b = new B();
$b->run();
$c = new C();
$c->run();
$d = new D();
$d->run();
大概有代碼的某些部分,你可以說這是可以做到更好,但主點是關閉功能並可調用。這些類以非常簡單的方式模擬緩存系統。如果數據在緩存中,它將從緩存中返回數據,否則將調用獲取數據的函數(當然,這個緩存系統不起作用,因爲它不必 - 它只是一個示例代碼)。
問題:
1)爲什麼要使用對象$d
我得到以下警告時:
call_user_func() expects parameter 1 to be a valid callback, cannot access protected method D::test()
,並有可能從母公司推出的保護方法?當我將此方法從受保護的方法更改爲公共方法時,它可以毫無問題地啓動。
2)正如您可能注意到的,我想使用一些參數作爲函數,我使用call_user_sync
調用。不幸的是,我不知道這些參數,當我呼叫call_user_func
,所以在B類和C類我使用閉包,我可以使用/傳遞額外的參數。我有兩個額外的問題連接到這個:
它是關閉是有用的和常用的方式?
是有可能使用對象
$d
傳遞參數測試方法不使用封閉但不調用call_user_sync
但內部D
類時?
_is有可能從父母啓動受保護的方法嗎?_這不是你正在做的事情。您不會從父級啓動受保護的方法。你正試圖調用'D'實例內'Test'實例的受保護方法。 – hindmost
你確定嗎?在我的代碼中,我看到我試圖調用'B'類的受保護方法'test'(這是'D'類的父類),當我將此方法更改爲public時,此方法正在啓動 –
您可以使用'array ($ this,'method')'只有在相同的上下文中使用私有/受保護的方法。當你在函數內部創建對象'$ obj'並將回調'數組($ this,'test')'傳遞給這個對象函數時,它會在沒有上下文的情況下傳遞。在'Test :: wrap'函數內部,回調被稱爲'$ objectOfClassD-> test(1)',而不是'$ this-> test(1)'和方法'D :: test()'被保護。當你將'D :: test()'公開時,它可以從任何上下文訪問,並且不會產生警告。 – piotrekkr