new一個class時不需要寫require。 PHP 5.2 新增自動加載的魔術方法__autoload($class_name)
一、__autoload()的使用
__autoload.php$db = new DB(); Height::test(); //也是支持静态方法直接调用的 function __autoload($className) { require $className . '.php'; }DB.php(同個目錄下)
class DB { public function __construct() { echo 'Hello DB'; } }Height.php(同個目錄下)
class Height { public function __construct() { echo 'Hello Height'; } public static function test(){ echo 'Hello Height test'; } }
二、spl_autoload_register 使用
__autoload()不允許加載不同路徑的文件,因為一個項目中只能有一個__autoload()。因此spl_autoload_register()誕生。當我們new一個找不到的class時,PHP會自動調用spl_autoload_register註冊的函數class autoloading{ //必须是静态方法,不然报错 public static function load($className) { require $className . '.php'; } } //2种方法都可以 spl_autoload_register(array('autoloading','load')); // spl_autoload_register('autoloading::load'); $db = new DB(); //会自动找到
三、多个spl_autoload_register的使用
function load1($className) { echo 1; if (is_file($className . '.php')) { require $className . '.php'; } } function load2($className) { echo 2; if (is_file('./app/' . $className . '.php')) { require './app/' . $className . '.php'; } } function __autoload($className) { echo 3; if (is_file('./lib/' . $className . '.php')) { require './lib/' . $className . '.php'; } } //注册了3个 spl_autoload_register('load1'); spl_autoload_register('load2'); spl_autoload_register('__autoload'); $db = new DB(); //DB就在本目录下 $info = new LibInfo(); //LibInfo 在/lib/LibInfo.php var_dump(spl_autoload_functions());
輸出:
1 Hello DB 1 2 3 Hello LibInfo array (size=3) 0 => string 'load1' (length=5) 1 => string 'load2' (length=5) 2 => string '__autoload' (length=10)
使用spl_autoload_functions() 來查一共註冊了多少個自動加載
spl_autoload_register()使用時,__autoload()會無效,必須重新註冊進來才有效
四、spl_autoload_register自動加載+namespace命名空間
根據 PSR-0 的規範,使用namespace就能找到詳細的路徑,從而找到class文件spl_autoload_register_namespace.php
//定义当前的目录绝对路径 define('DIR', dirname(__FILE__)); //加载这个文件 require DIR . '/loading.php'; //采用`命名空间`的方式注册。php 5.3 加入的 //也必须是得是static静态方法调用,然后就像加载namespace的方式调用,注意:不能使用use spl_autoload_register("\\AutoLoading\\loading::autoload"); $oMySQL = new Libary\Db\MySQL(); $oMySQL->bear(); // 调用2个namespace类 //定位到Libary目录下的Name.php Libary\Name::test(); //定位到App目录下Android目录下的Name.php App\Android\Name::test();
loading.php
namespace AutoLoading; class loading { public static function autoload($className) { //根据PSR-O的第4点 把 \ 转换层(目录风格符) DIRECTORY_SEPARATOR , //便于兼容Linux文件找。Windows 下(/ 和 \)是通用的 //由于namspace 很规格,所以直接很快就能找到 $fileName = str_replace('\\', DIRECTORY_SEPARATOR, DIR . '\\' . $className) . '.php'; if (is_file($fileName)) { require $fileName; } else { echo $fileName . ' is not exist';die; } } }
Libary/Db/MySQL.php
namespace Libary\Db; use Libary\Name; // use放這 class MySQL { public function __construct() { echo __NAMESPACE__ . ""; } public static function test() { echo __NAMESPACE__ . ' static function test '; } public function bear(){ Name::getInstance(); // 呼叫 Libary/Name.php 的 static function getInstance() } }
Libary/Name.php
namespace Libary; use Libary\Db\MySQL; // use放在這 class Name { public function __construct() { echo __NAMESPACE__ . ""; } public static function test() { // $oMySQL = new Libary\Db\MySQL(); // D:\bear\www\test\autoload\Libary\Libary\Db\MySQL.php is not exist // $oMySQL = new Db\MySQL(); // OK // use Libary\Db\MySQL; // Parse error: syntax error, unexpected 'use' (T_USE) $oMySQL = new MySQL(); // 打印第二個 Libary\Db echo __NAMESPACE__ . ' static function test '; } public static function getInstance(){ echo __NAMESPACE__ . ":getInstance"; } }
App/Android/Name.php
namespace App\Android; class Name { public function __construct() { echo __NAMESPACE__ . ""; } public static function test() { echo __NAMESPACE__ . ' static function test '; } }
輸出:
Libary\Db Libary:getInstance Libary\Db Libary static function test App\Android static function test
s
...using __autoload() is discouraged and may be deprecated or removed in the future.
使用 __autoload() 是將會被棄用的(PHP 7.2.0),因為只能使用一次。應使用spl_autoload_register()
use Libary\Db\MySQL; // use 使用絕對路徑,放在class外面,namespace後面
參考資料:
https://www.zybuluo.com/phper/note/66447 PHP中的自动加载
https://stackoverflow.com/questions/12702527/how-to-call-autoload-in-php-code How to call __autoload() in php code
https://stackoverflow.com/questions/33342994/unexpected-use-t-use-when-trying-to-use-composer unexpected 'use' (T_USE)
https://www.php-fig.org/psr/psr-0/ PSR-0: Autoloading Standard
沒有留言:
張貼留言