這篇文章給大家分享的內容是關於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的分析