daulat
daulat

Reputation: 949

How to access php closure without brackets

I have A class App

<?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];
        }
    }


}
?>

And one more Page index.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'    => '',
]);

?>

Now I want to access that Capsule object like this "$App->db" How can i do this.

Upvotes: 2

Views: 99

Answers (3)

apokryfos
apokryfos

Reputation: 40680

Edit I didn't understand the original question. Here's an update

I've added an "invokationData" array in your class. Now all normal data are returned from data, but if the corresponding entry is a closure it is invoked first and the result is stored in the invokationData array, which is then returned instead.

<?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];
        } 

    }


}

No need to use a closure anymore

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'    => '',
]);

Upvotes: 1

Alessandro
Alessandro

Reputation: 1453

If you want to access the new object created by the call of the closure, you need to do it like this:

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

Beware that it will be a new object each time you call it. I would rather assign directly the object to the variable.

Credits: Calling closure assigned to object property directly

Upvotes: 0

Andrius
Andrius

Reputation: 5939

I have created a simple example that would work in your case:

<?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());

?>

Yet, the whole construction this way is somewhat incorrect (inconvenient, maybe). You should most likely work with 'Dependency Injection' rather than setting it as a variable directly. Something like that would be semantically more correct:

<?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());

?>

Upvotes: 2

Related Questions