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

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

require 'flight/Flight.php';

Flight::route('/', function(){

echo 'hello world!';

});

Flight::start();

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

class 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

class 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

namespace autoload;

class Test {}

/autoload/Test2.php

namespace autoload;

class Test2 {}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值