Hi guys,
Phalcon is the best Framework I have ever seen, and Zephir surprise me, too. I have read the Zephir documents and explored a DI as Phalcon DI, and test it with phpunit. Amazing! it is easier more to explore php extensions with Zephir, but I still have some questions as bellow.
Q1: unexpected result return when using magic functions to register services. As the test show:
$di = new Dogstar\Di::getInstance();
$di->setName('dogstar');
$this->assertEquals($this->fdi->getName(), 'dogstar');
It FAILED! it returned null not 'dogstar'. I debug it with my code, i found that DI::_$data become empty after I use Setter function. but i don't know why.
Q2: how can I call closure functions?
My DI Zephir Code as below:
//DI.zep
namespace Dogstar;
class Di implements \ArrayAccess
{
protected static _instance = null;
protected _data = [];
public function __construct()
{
}
public static function getInstance()
{
if (typeof self::_instance == "NULL") {
let self::_instance = new Di();
self::_instance->onConstruct();
}
self::_instance->onInitialize();
return self::_instance;
}
public function onConstruct()
{
//TODO
}
public function onInitialize()
{
//TODO
}
public function set(var key, var value)
{
this->_checkKey(key);
let this->_data[key] = value;
}
public function get(key, defaultValue = null, boolean isShare = false)
{
this->_checkKey(key);
var value;
if !(fetch value, this->_data[key]) {
return defaultValue;
}
let value = this->_data[key];
if gettype(value) == "object" && is_callable(value) {
//TODO how to call clourse?
//let value = {value}();
} else {
if is_string(value) && class_exists(value) {
var tmp;
let tmp = create_instance(value);
let value = tmp;
if gettype(value) == "object" && is_callable([value, "onConstruct"]) {
call_user_func([value, "onConstruct"]);
}
let isShare = false;
return value;
} else {
//TODO
//init by array configs
}
}
if !isShare && gettype(value) == "object" && is_callable([value, "onInitialize"]) {
call_user_func([value, "onInitialize"]);
}
let this->_data[key] = value;
return value;
}
protected function _checkKey(var key)
{
if empty(key) || (!is_string(key) && !is_numeric(key)) {
throw new \Exception("Unvalid key(" . gettype(key) . "), expect to string or numeric");
}
}
public function __call(name, params)
{
var prefix;
let prefix = substr(name, 0, 3);
var key;
let key = lcfirst(substr(name, 3, strlen(name)));
var value = null;
fetch value, params[0];
if prefix == "get" {
return this->get(key, value);
}
if prefix == "set" {
this->set(key, value);
return;
}
throw new \Exception("Call to undefined method Di::" . name . "()");
}
public function __set(key, value)
{
this->set(key, value);
}
public function __get(key)
{
return this->get(key, null, true);
}
public function offsetSet(offset, value)
{
this->set(offset, value);
}
public function offsetGet(offset)
{
return this->get(offset);
}
public function offsetUnset($offset)
{
unset(this->_data[offset]);
}
public function offsetExists(offset)
{
var value;
return fetch value, this->_data[offset];
}
}
Could somebody help?