2017-07-25 82 views
1

我目前只是搞乱了PHP,我注意到一些有趣的事情,我个人没有注意到。匿名函数似乎不适用于对象内部。为什么?为什么匿名函数似乎被拒绝这个PHP对象

实施例:

$loop = function ($do) { 
    $i = 2; 
    $do((object) [ 
     "i" => $i, 
     "domore" => (function() { 
      echo "hi"; 
     }) 
    ]); 
}; 

$loop(function ($data) { 
    echo $data->i; 
    echo $data->domore(); 
}); 

引发Error:

2<br /> 
<b>Fatal error</b>: Uncaught Error: Call to undefined method stdClass::delay() in [...][...]:16 
Stack trace: 
#0 [...][...](10): {closure}(Object(stdClass)) 
#1 [...][...](17): {closure}(Object(Closure)) 
#2 {main} 
    thrown in <b>[...][...]</b> on line <b>16</b><br /> 

同样地,相同的代码与返回数据作为一个阵列,而不是一个对象:

$loop = function ($do) { 
    $i = 2; 
    $do([ 
     "i" => $i, 
     "domore" => function() { 
      echo "hi"; 
     } 
    ]); 
}; 

$loop(function ($data) { 
    echo $data["i"]; 
    echo $data["domore"](); 
}); 

简单地返回,如预期的那样,2hi。这对我来说似乎很奇怪(来自JavaScript的人),所以我会很感激某种理由。请注意,这些代码并没有真正的生活目的,所以好的或坏的练习在这里没有任何影响。认为教育。

编辑: Laravel不正是我想给我的概念,它是不可能的,但我只是在PHP中正确实现它:

DB::table('users') 
    ->join('contacts', function ($join) { 
     $join->on('users.id', '=', 'contacts.user_id')->orOn(...); 
    })->get(); 

回答

3

匿名函数中的对象正常工作。你会得到这个错误,因为domore不是一种方法,而你正在调用它,它是一个恰好是闭包的属性。为了区分处理财产时,你需要使用括号,如:

$loop(function ($data) { 
    echo $data->i; 
    echo ($data->domore)(); 
}); 

输出:

2hi 

为什么这是必要的,因为方法和属性,生活在不同的符号表,这意味着你可以拥有一个属性和一个同名的方法(请不要这样做)你需要知道哪些是正在处理的。例如: -

$foo = new class 
{ 
    public $func; 

    public function __construct() 
    { 
     $this->func = function() { 
      echo "foo"; 
     }; 
    } 

    public function func() 
    { 
     echo "bar"; 
    } 
}; 

($foo->func)(); 
$foo->func(); 

输出:

foobar 
+0

那么,如何laravel实现更干净的外观? – Shawn31313

+0

'语法错误,意外'(',期待','或';'' - >'回声($ data-> domore)();' – icecub

+0

@icecub更新您的php版本 –

相关问题