php微架構中flight源碼的自動載入的解析

來源:互聯網
上載者:User
這篇文章給大家分享的內容是關於php微架構中flight源碼的自動載入的解析,有一定的參考價值,有需要的朋友可以參考一下。

先來看下架構的單入口檔案index.php,先引入了Flight.php架構類檔案。

<?phprequire 'flight/Flight.php';Flight::route('/', function(){    echo 'hello world!';});Flight::start();

Flight.php中定義了Flight類,類裡面先定義了3個魔術方法,這三個魔術方法是為了防止當前類被執行個體化

// Don't allow object instantiationprivate 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.phprequire_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<?phpclass MyClass{    public static function __callStatic($name, $params){        self::app();    }    public static function app(){        require_once __DIR__.'/Loader.php';        Loader::autoload(true, dirname(__DIR__));        new \autoload\Test();    }}MyClass::test();new \autoload\Test2();var_dump(Loader::getClasses());//array(2) { [0]=> string(36) "/usr/local/var/www/autoload/Test.php" [1]=> string(37) "/usr/local/var/www/autoload/Test2.php" } /autoload/Loader.php<?phpclass Loader {    public static $dirs = [];    public static $classes = [];    public static function autoload($enabled=true, $dirs=[]) {        if ($enabled) {            spl_autoload_register([__CLASS__, 'loadClass']);        } else {            spl_autoload_unregister([__CLASS__, 'loadClass']);        }                if (!empty($dirs)) {            self::addDirectory($dirs);        }    }    public static function loadClass($class) {        $class_file = str_replace(['\\', '_'], '/', $class).'.php';                foreach (self::$dirs as $dir) {            $file = $dir.'/'.$class_file;                        if (file_exists($file)) {                require $file;                self::$classes[] = $file;                                return;            }        }    }    public static function addDirectory($dir) {        if (is_array($dir) || is_object($dir)) {            foreach ($dir as $value) {                self::addDirectory($value);            }        }        else if (is_string($dir)) {            if (!in_array($dir, self::$dirs)) self::$dirs[] = $dir;        }    }    public static function getClasses(){        return self::$classes;    }}/autoload/Test.php<?phpnamespace autoload;class Test {}/autoload/Test2.php<?phpnamespace autoload;class Test2 {}

x相關推薦:

GoFrame架構的gtime模組和自訂時間格式化文法的分析

Swoft源碼之Swoole和Swoft的分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.