Reputation: 949
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
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
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
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