首先看Engine::Init方法
    public function init() {
        static $initialized = false;
        $self = $this;
        if ($initialized) {
            // Flight 允许你保存变量,这样就可以在你的应用程序任何地方使用
            $this->vars = array();
            $this->loader->reset();
            $this->dispatcher->reset();
        }
        // 默认的request,response,router,view四个组件
        $this->loader->register('request', '\flight\net\Request');
        $this->loader->register('response', '\flight\net\Response');
        $this->loader->register('router', '\flight\net\Router');
        $this->loader->register('view', '\flight\template\View', array(), function($view) use ($self) {
            $view->path = $self->get('flight.views.path');
        });
        //默认的框架的方法
        $methods = array(
            'start','stop','route','halt','error','notFound',
            'render','redirect','etag','lastModified','json','jsonp'
        );
        foreach ($methods as $name) {
             //实际的方法加了_隐藏
             $this->dispatcher->set($name, array($this, '_'.$name));
        }
        // 默认的框架配置,也是通过vars存储的
        $this->set('flight.base_url', null);
        $this->set('flight.handle_errors', true);
        $this->set('flight.log_errors', false);
        $this->set('flight.views.path', './views');
        $initialized = true;
    },
可以看出engine除了核心方法,其他都是通过注册自定义和扩展的。    
map($name, $callback) // 创建一个自定义框架的方法。
register($name, $class, [$params], [$callback]) // 注册一个类的框架方法。
before($name, $callback) // 在一个框架方法之前添加一个过滤器。
after($name, $callback) // 在一个框架方法之后添加一个过滤器。
path($path) // 添加了一个半自动的类路径。
get($key) // 得到一个变量。
set($key, $value) // 设置一个变量。
has($key) // 检查一个变量是否设置。
clear([$key]) // 清除一个变量。
扩展方法通过魔术方法__call来调用
    public function __call($name, $params) {
        $callback = $this->dispatcher->get($name);
        //如果是函数
        if (is_callable($callback)) {
            return $this->dispatcher->run($name, $params);
        }
        //否则是类的实例
        $shared = (!empty($params)) ? (bool)$params[0] : true;
        return $this->loader->load($name, $shared);
    }
 
通过Loader生成类的实例,实例分两类:单例(共享的)和多例(非共享的)。
    public function load($name, $shared = true) {
        $obj = null;
        if (isset($this->classes[$name])) {
            list($class, $params, $callback) = $this->classes[$name];
            $exists = isset($this->instances[$name]);
            // 判断是否生成单例对象
            if ($shared) {
                $obj = ($exists) ?
                    $this->getInstance($name) :
                    $this->newInstance($class, $params);
                
                if (!$exists) {
                    $this->instances[$name] = $obj;
                }
            }
            else {
                $obj = $this->newInstance($class, $params);
            }
            //对于new的对象需要调用回调函数
            if ($callback && (!$shared || !$exists)) {
                $ref = array(&$obj);
                call_user_func_array($callback, $ref);
            }
        }
        return $obj;
    }
 
	posted on 2015-04-25 11:14 
merlinfang 阅读(405) 
评论(0)  编辑 收藏 引用  所属分类: 
flight