如何访问不带括号的 php 闭包


How to access php closure without brackets

我有A类应用程序

<?php
namespace App;
class App
{
    private $data = array();
    public function __set($name, $value)
    {
        $this->data[$name] = $value;
    }
    public function __get($name)
    {
        if (array_key_exists($name, $this->data)) {
            return $this->data[$name];
        }
    }

}
?>

还有一个页面索引.php

<?php
require 'vendor/autoload.php';
require 'app/app.php';
use App'App;
use Illuminate'Database'Capsule'Manager as Capsule;
$App = new App;
var_dump($App->db);
$App->db=function (){
return new Capsule;
};
var_dump($App->db);
$App->db->addConnection([
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'ides_new',
    'username'  => 'root',
    'password'  => '',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
]);
?>

现在我想像"$App->db"一样访问该 Capsule 对象我该怎么做。

我创建了一个适用于您的情况的简单示例:

<?php
class App
{
    private $data = array();
    public $otherClass;                 // <-- Create a public variable
}
class OtherClass {
    public function foo() {
        return "bar";
    }
}

$App = new App();
$App->otherClass = new OtherClass();
var_dump($App->otherClass->foo());
?>

然而,这种方式的整个结构有些不正确(也许不方便)。您最有可能使用"依赖注入",而不是直接将其设置为变量。这样的东西在语义上会更正确:

<?php
class App
{
    private $data = array();
    public $otherClass;
    function __construct(OtherClass $otherClass) {
        $this->otherClass = $otherClass;
    }
}
class OtherClass {
    public function foo() {
        return "bar";
    }
}
$otherClass = new OtherClass();
$App = new App($otherClass);
var_dump($App->otherClass->foo());
?>

编辑 我不明白原来的问题。这是一个更新

我在你的类中添加了一个"invokationData"数组。现在所有正常数据都从数据返回,但如果相应的条目是闭包,则首先调用它,结果存储在 invokationData 数组中,然后返回。

<?php
namespace App;
class App
{
    private $data = array();
    private $invokationData = array();
    public function __set($name, $value)
    {
        $this->data[$name] = $value;
       if (is_callable($this->data[$name]) && array_key_exists($name, $this->invokationData) {
            unset($this->invokationData[$name]); //Clear result of old function
       }
    }
    public function __get($name)
    {
        if (array_key_exists($name, $this->data) && is_callable($this->data[$name]) && !array_key_exists($name, $this->invokationData)) {
            $this->invokationData[$name] = call_user_func($this->data[$name];
        }
        if (array_key_exists($name, $this->invokationData)) {
            return $this->invokationData[$name];
        } elseif (array_key_exists($name, $this->data)) {
            return $this->data[$name];
        } 
    }

}

无需再使用闭合

use App'App;
use Illuminate'Database'Capsule'Manager as Capsule;
$App = new App;
var_dump($App->db);
$App->db = function () { return new Capsule; }
var_dump($App->db);
$App->db->addConnection([
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'ides_new',
    'username'  => 'root',
    'password'  => '',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
]);

如果你想访问由闭包调用创建的新对象,你需要这样做:

$App->db->__invoke()->addConnection(...);

请注意,每次调用它时,它都将是一个新对象。我宁愿直接将对象分配给变量。

学分:直接调用分配给对象属性的闭包