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
沒有留言:
張貼留言