乐趣区

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

在自动加载实现完成后,接着 new flightEngine() 实例化了下框架的核心类 Engine,这个类翻译过来名字就是引擎发动机的意思,是 flight 的引擎发动机,很有想象力吧。
public static function app() {
static $initialized = false;

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

self::$engine = new \flight\Engine();

$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\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’);
$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);
}

在 $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;
}

退出移动版