资讯专栏INFORMATION COLUMN

php微框架 flight源码阅读——2.框架初始化、Loader、Dispatcher

U2FsdGVkX1x / 2275人阅读

摘要:当调用时,会触发当前类的魔术方法,通过判断属性中索引是否存在,不存在抛出异常,存在就通过去实例化初始化时设置的,这里是工厂模式,接下来的路由文章会详细分析。在操作中,会将前置操作设置到类的属性中。微框架源码阅读系列

在自动加载实现完成后,接着new flightEngine()自动加载的方式实例化了下框架的核心类Engine,这个类名翻译过来就是引擎发动机的意思,是flight的引擎发动机,很有想象力吧。

public static function app() {
    static $initialized = false;

    if (!$initialized) {
        require_once __DIR__."/autoload.php";

        self::$engine = new flightEngine();

        $initialized = true;
    }

    return self::$engine;
}

在实例化Engine这个类的时候,当前类的构造方法进行了对框架的初始化工作。

public function __construct() {
    $this->vars = array();

    $this->loader = new Loader();
    $this->dispatcher = new Dispatcher();

    $this->init();
}

接着来看init方法都做了什么,将初始化状态标记为静态变量static $initialized,判断如果为true,将$this->vars以及$this->loader$this->dispatcher中保存的属性重置为默认状态。

static $initialized = false;
$self = $this;

if ($initialized) {
    $this->vars = array();
    $this->loader->reset();
    $this->dispatcher->reset();
}

接下来将框架的Request、Response、Router、View类的命定空间地址register(设置)到Loader类的classes属性中。

// Register default components
$this->loader->register("request", "flight
etRequest");
$this->loader->register("response", "flight
etResponse");
$this->loader->register("router", "flight
etRouter");
$this->loader->register("view", "flight	emplateView", array(), function($view) use ($self) {
    $view->path = $self->get("flight.views.path");
    $view->extension = $self->get("flight.views.extension");
});  

flight/core/Loader.php

public function register($name, $class, array $params = array(), $callback = null) {
    unset($this->instances[$name]);

    $this->classes[$name] = array($class, $params, $callback);
}

再接下来就是将框架给用户提供的调用方法,设置到调度器Dispatcher类的events属性中。

// Register framework methods
$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));
}

flight/core/Dispatcher.php

/**
 * Assigns a callback to an event.
 *
 * @param string $name Event name
 * @param callback $callback Callback function
 */
public function set($name, $callback) {
    $this->events[$name] = $callback;
}

接下来呢,就是设置框架的一些配置,将这些配置保存在Engine类的vars属性中。

// Default configuration settings
$this->set("flight.base_url", null);
$this->set("flight.case_sensitive", false);
$this->set("flight.handle_errors", true);
$this->set("flight.log_errors", false);
$this->set("flight.views.path", "./views");
$this->set("flight.views.extension", ".php");

flight/Engine.php

/**
 * Sets a variable.
 *
 * @param mixed $key Key
 * @param string $value Value
 */
public function set($key, $value = null) {
    if (is_array($key) || is_object($key)) {
        foreach ($key as $k => $v) {
            $this->vars[$k] = $v;
        }
    }
    else {
        $this->vars[$key] = $value;
    }
}

最后一步的操作,当调用框架的start方法时,给其设置一些前置操作,通过set_error_handler()和set_exception_handler()设置用户自定义的错误和异常处理函数,如何使用自定义的错误和异常函数,可以看这两个范例:https://segmentfault.com/n/13...
https://segmentfault.com/n/13...。

// Startup configuration
$this->before("start", function() use ($self) {
    // Enable error handling
    if ($self->get("flight.handle_errors")) {
        set_error_handler(array($self, "handleError"));
        set_exception_handler(array($self, "handleException"));
    }

    // Set case-sensitivity
    $self->router()->case_sensitive = $self->get("flight.case_sensitive");
});

$initialized = true;

/**
 * Custom error handler. Converts errors into exceptions.
 *
 * @param int $errno Error number
 * @param int $errstr Error string
 * @param int $errfile Error file name
 * @param int $errline Error file line number
 * @throws ErrorException
 */
public function handleError($errno, $errstr, $errfile, $errline) {
    if ($errno & error_reporting()) {
        throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
    }
}

/**
 * Custom exception handler. Logs exceptions.
 *
 * @param Exception $e Thrown exception
 */
public function handleException($e) {
    if ($this->get("flight.log_errors")) {
        error_log($e->getMessage());
    }

    $this->error($e);
}

当调用$self->router()时,会触发当前类的__call()魔术方法,通过$this->loader->get($name)判断属性$classes中router索引是否存在,不存在抛出异常,存在就通过$this->loader->load($name, $shared)去实例化初始化时设置的"flight etRouter",这里是工厂模式,接下来的路由文章会详细分析。

/**
 * Handles calls to class methods.
 *
 * @param string $name Method name
 * @param array $params Method parameters
 * @return mixed Callback results
 * @throws Exception
 */
public function __call($name, $params) {
    $callback = $this->dispatcher->get($name);
 
    if (is_callable($callback)) {
        return $this->dispatcher->run($name, $params);
    }

    if (!$this->loader->get($name)) {
        throw new Exception("{$name} must be a mapped method.");
    }

    $shared = (!empty($params)) ? (bool)$params[0] : true;

    return $this->loader->load($name, $shared);
}

$this->before()操作中,会将前置操作设置到Dispatcher类的filters属性中。这些操作完成后,将$initialized = true

/**
 * Adds a pre-filter to a method.
 *
 * @param string $name Method name
 * @param callback $callback Callback function
 */
public function before($name, $callback) {
    $this->dispatcher->hook($name, "before", $callback);
}

flight/core/Dispatcher.php

/**
 * Hooks a callback to an event.
 *
 * @param string $name Event name
 * @param string $type Filter type
 * @param callback $callback Callback function
 */
public function hook($name, $type, $callback) {
    $this->filters[$name][$type][] = $callback;
}


php微框架 flight源码阅读系列

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29752.html

相关文章

  • php框架 flight源码阅读

    摘要:是一个可扩展的微框架,快速简单,能够快速轻松地构建应用程序,在上有。框架代码十分精简,在几分钟内你就可以看完整个框架源码,使用起来也是很简单优雅。目录微框架源码阅读自动加载微框架源码阅读框架初始化微框架源码阅读路由实现及执行过程 Flight https://github.com/mikecao/fl...是一个可扩展的PHP微框架,快速、简单,能够快速轻松地构建RESTful web...

    CntChen 评论0 收藏0
  • php框架 flight源码阅读——1.自动加载

    摘要:先来看下框架的单入口文件,先引入了框架类文件。中定义了加载存放哪些类型类路径数组对象数组框架目录路径数组中使用将当前类中的方法注册为加载的执行方法。接下来我们试着按照自动加载的方式,写个简单的自动加载进行测试微框架源码阅读系列 先来看下框架的单入口文件index.php,先引入了Flight.php框架类文件。

    OnlyLing 评论0 收藏0
  • php框架 flight源码阅读——3.路由Router实现及执行过程

    摘要:当然在对象中也没有方法,于是会触发当前对象中的魔术方法。获取对象获取对象获取对象设置方法执行的后置操作现在来看操作都做了什么。匹配的部分对路由匹配实现正则匹配微框架源码阅读系列 现在来分析路由实现及执行过程,在项目目录下创建index.php,使用文档中的路由例子(含有路由规则匹配),如下:

    王晗 评论0 收藏0
  • 你不可不知道的20个优秀PHP框架

    摘要:每一个开发者都知道,拥有一个强大的框架可以让开发工作变得更加快捷安全和有效。官方网站是一款老牌的框架,现在稳定版本已经是了。官方网站是由最大的社区之一的管理开发的,也是一个开源的框架。 对于Web开发者来说,PHP是一款非常强大而又受欢迎的编程语言。世界上很多顶级的网站都是基于PHP开发的。 每一个开发者都知道,拥有一个强大的框架可以让开发工作变得更加快捷、安全和有效。在开发项目之前选...

    zombieda 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<