php微框架 flight源码阅读——1.自动加载

先来看下框架的单入口文件index.php,先引入了Flight.php框架类文件。

Flight.php中定义了Flight类,类里面先定义了3个魔术方法,这三个魔术方法是为了防止当前类被实例化

// Don't allow object instantiation
private function __construct() {}
private function __destruct() {}
private function __clone() {}

如果试着去new Flight会提示如下错误:

Fatal error: Uncaught Error: Call to private Flight::__construct() from invalid context in /usr/local/var/www/flight135/index.php:3 Stack trace: #0 {main} Next Error: Call to private Flight::__destruct() from context '' in /usr/local/var/www/flight135/index.php:3 Stack trace: #0 {main} thrown in /usr/local/var/www/flight135/index.php on line 3

接着定义了一个重载方法__callStatic(),在index.php中执行Flight::route('/', 'hello')就会调用该__callStatic,其中$name就是'route'$params就是自己写的hello函数。在__callStatic()中调用了当前类的app()静态方法,这里为什么不使用self::app()来调用呢?

/**
 * Handles calls to static methods.
 *
 * @param string $name Method name
 * @param array $params Method parameters
 * @return mixed Callback results
 * @throws \Exception
 */
public static function __callStatic($name, $params) {
    $app = Flight::app();
    return \flight\core\Dispatcher::invokeMethod(array($app, $name), $params);
}

接着就是在static app()中开始处理自动加载了

/**
 * @return \flight\Engine Application instance
 */
public static function app() {
    static $initialized = false;
    if (!$initialized) {
        require_once __DIR__.'/autoload.php';
        self::$engine = new \flight\Engine();
        $initialized = true;
    }
    return self::$engine;
}

进入到autoload.php来看,引入了core目录下的Loader.php类文件,Loader就是加载器。

autoload.php
require_once __DIR__.'/core/Loader.php';
\flight\core\Loader::autoload(true, dirname(__DIR__));

Loader中定义了加载存放哪些类型:$classes(类路径数组),$instances(对象数组),$dirs(框架目录路径数组)

/**
 * Registered classes.
 *
 * @var array
 */
protected $classes = array();
/**
 * Class instances.
 *
 * @var array
 */
protected $instances = array();
/**
 * Autoload directories.
 *
 * @var array
 */
protected static $dirs = array();

autoload()中使用spl_autoload_register将当前类(__CLASS__)中的loadClass方法注册为加载的执行方法。

/**
 * Starts/stops autoloader.
 *
 * @param bool $enabled Enable/disable autoloading
 * @param array $dirs Autoload directories
 */
public static function autoload($enabled = true, $dirs = array()) {
    if ($enabled) {
        spl_autoload_register(array(__CLASS__, 'loadClass'));
    }
    else {
        spl_autoload_unregister(array(__CLASS__, 'loadClass'));
    }
    if (!empty($dirs)) {
        self::addDirectory($dirs);
    }
}

/**
 * Autoloads classes.
 *
 * @param string $class Class name
 */
public static function loadClass($class) {
    $class_file = str_replace(array('\\', '_'), '/', $class).'.php';
    foreach (self::$dirs as $dir) {
        $file = $dir.'/'.$class_file;
        if (file_exists($file)) {
            require $file;
            return;
        }
    }
}

接下来我们试着按照flight自动加载的方式,写个简单的自动加载进行测试:


/autoload/index.php

 string(36) "/usr/local/var/www/autoload/Test.php" [1]=> string(37) "/usr/local/var/www/autoload/Test2.php" } 

/autoload/Loader.php


/autoload/Test.php


/autoload/Test2.php


php微框架 flight源码阅读系列

你可能感兴趣的:(魔术方法,oop,autoload,自动加载,php)