类的自动加载
两个函数 __autoload()魔术方法、spl_autoload_register
当php文件中使用了new关键字实例化一个对象时,如果该类没有在本php文件中被定义,将会触发__autoload函数
__autoload
运行到new Animal()时,发现 class Animal没有定义
触发了__autoload函数,该函数引进了Animal.php文件
实例化成功。
spl_autoload_register
(注意:当文件中同时出现__autoload和spl_autoload_register时,以spl_autoload_register为准)
bool spl_autoload_register ([ callable autoloadfunction[,boolthrow = true [, bool $prepend = false ]]] )
autoload_function
- 欲注册的自动装载函数。如果没有提供任何参数,则自动注册 autoload 的默认实现函数spl_autoload()。
throw
- 此参数设置了 autoload_function 无法成功注册时, spl_autoload_register()是否抛出异常。
prepend
- 如果是 true,spl_autoload_register() 会添加函数到队列之首,而不是队列尾部。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
#main.php <?php function myLoad($classname){ $classpath = "{$classname}.php"; if(file_exists($classpath)){ require_once($classpath); }else{ echo $classpath." not be found!"; } } spl_autoload_register("myLoad");
// 当系统找不到相应的类库的时候 调用 myload方法 如果没有规定 自动注册autoload的默认实现函数spl_autoload();
$ani = new Animal(); ?>
|
两者的区别
1,可以按需多次写spl_autoload_register注册加载函数,加载顺序按谁先注册谁先调用。__aotuload由于是全局函数只能定义一次,不够灵活。 自动加载对象方便
2,可以被catch到错误,而__autoload不能。
3,spl_autoload_register注册的加载函数可以按需被spl_autoload_unregister掉
Composer
运行 Composer 需要 PHP 5.3.2+ 以上版本。
composer的使用
在composer.json内包含 require
composer install
require vendor/autoload.php
以上就可以实现自动加载
composer 自动加载原理
Laravel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
/public/index.php
<?php
/** * Laravel - A PHP Framework For Web Artisans * * @package Laravel * @author Taylor Otwell <taylor@laravel.com> */
define('LARAVEL_START', microtime(true));
/* |-------------------------------------------------------------------------- | Register The Auto Loader |-------------------------------------------------------------------------- | | Composer provides a convenient, automatically generated class loader for | our application. We just need to utilize it! We'll simply require it | into the script here so that we don't have to worry about manual | loading any of our classes later on. It feels great to relax. | */
require \_\_DIR__.'/../vendor/autoload.php'; // 发现使用autoload 看到getloader
|
composer内部代码GetLoader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
vendor/composer/autoload_real.php
class ComposerAutoloaderInit175720aab51ecef5d6218812498b5793 { private static $loader;
public static function loadClassLoader($class) { if ('Composer\Autoload\ClassLoader' === $class) { require __DIR__ . '/ClassLoader.php'; } }
public static function getLoader() { if (null !== self::$loader) { return self::$loader; }
spl_autoload_register(array('ComposerAutoloaderInit175720aab51ecef5d6218812498b5793', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit175720aab51ecef5d6218812498b5793', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); // 根据版本判断使用哪个loader if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit175720aab51ecef5d6218812498b5793::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { $loader->set($namespace, $path); }
$map = require __DIR__ . '/autoload_psr4.php'; foreach ($map as $namespace => $path) { $loader->setPsr4($namespace, $path); }
$classMap = require __DIR__ . '/autoload_classmap.php'; if ($classMap) { $loader->addClassMap($classMap); } }
$loader->register(true);
if ($useStaticLoader) { $includeFiles = Composer\Autoload\ComposerStaticInit175720aab51ecef5d6218812498b5793::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { composerRequire175720aab51ecef5d6218812498b5793($fileIdentifier, $file); }
return $loader; } }
|
步骤 :首先判断PHP版本决定使用Staticloader还是普通的Namespaceloader
加载PSR-0规范的类 方法在ClassLoader内
加载PSR-4规范的类 方法在ClassLoader内
加载上面两个类就是对ClassLoader内的需要加载的类进行编辑操作
register进行类注册加载 方法在ClassLoader内 调用spl_autoloader_register();