搜尋
首頁後端開發PHP問題詳細介紹php自動載入原理

詳細介紹php自動載入原理

Sep 02, 2019 pm 04:55 PM
php原理自動載入

詳細介紹php自動載入原理

說起PHP的自動加載,很多同學可能都會想到各種框架的自動加載功能,PHP規範中的PSR0和PSR4原則,Composer的自動加載功能等等,這些都為我們的開發提供了很大的方便。

那麼PHP自動載入的前因後果到底是什麼? PHP的內部原理又是怎麼樣的呢?接下來我就根據自己的理解來進行分析總結:

為什麼會有自動載入?

在PHP物件導向(OO)程式設計中,為了方便管理,我們都會把一個類別寫在一個單獨的檔案中,那麼如果想在A類別中使用B類的功能,就需要把B類載入到A類。對於這樣的需求在最原始的時候,我們是透過require 和 include 語法實現的,這2種語法結果基本上一樣,執行流程有一些區別,這裡不解釋。例如:

//文件 B.php
<?php
class B{
    public function echo_info(){
        echo "我是class B中的方法执行结果";
    }
}
?>
//文件 A.php
<?php
require &#39;b.php&#39;;//include &#39;b.php&#39;;
class A{
    public function test(){
        $b_object = new B();
        $b_object->echo_info();
    }
}
$a_object = new A();
$a_oject->test();
?>
命令行输入:#php a.php
    输出: “我是class B中的方法执行结果“

於是,PHP5實作了類別的自動載入(Autoload)功能,這個功能最初是透過PHP的一個魔術方法__autoload()實現的。後來,PHP擴充SPL(Standard PHP Library 標準PHP類別函式庫)又實作了更強大的自動載入機制。

php原始自動載入

#首先,先介紹下__autoload()方法。還是剛剛的例子,使用__autoload()可以做如下修改:

//文件 B.php 不做修改
//文件 A.php
<?php
class A{
    public function test(){
        $b_object = new B();
        $b_object->echo_info();
    }
}
function __autoload($classname){
    require $classname.&#39;.php&#39;;//include &#39;b.php&#39;;
}
$a_object = new A();
$a_oject->test();
?>
命令行输入:#php a.php
    输出: “我是class B中的方法执行结果“

我們在A文件中加了一個函數:__autoload(),並且自己在函數中編寫了相應的引入方法,運行之後同樣得到了結果,沒有報錯。我們需要明確__autoload()函數PHP在找不到類別的時候會自動執行,但是PHP內部並沒有定義這個函數,這個函數需要開發著自己定義,並且編寫內部邏輯,PHP只負責在需要的時候自動調用執行。而且在呼叫的時候會自動傳人要載入的類別名稱作為參數。

有了__autoload()函數,可以看出,如果我們現在需要引入100個其它文件,只需要訂好一個規則,編寫一個函數就可以了。這比直接用require/inlude有了很大進步,但是同樣也有新的問題,在一個專案中,我們只能寫一個__autoload()函數,如果專案比較大,載入每個檔案都使用相同的規則顯然是不切實際的,那麼我們可能需要在__autoload()中編寫複雜的規則邏輯來滿足載入不同檔案的需求。這同樣會使得__autoload()函數變得複雜臃腫,難以維持管理。

於是,SPL(Standard PHP Library 標準PHP類別函式庫)的自動載入機制就應時而生了。

SPL自動載入

#首先,明確一點,PHP在實例化一個物件時(實際上在實現接口,使用類別常數或類別中的靜態變量,調用類別中的靜態方法時都會如此),首先會在系統中查找該類別(或接口)是否存在,如果不存在的話就嘗試使用autoload機制來加載該類。而autoload機制的主要執行過程為:

1、檢查執行器全域變數函數指標autoload_func是否是NULL;

2.如果autoload_func==NULL ,則查找系統是否定義__autoload() 函數,如果定義了,則執行並傳回載入結果。如果沒有定義,則報錯並退出;

3、如果 autoload_func 不等於NULL,則直接執行 autoload_func 指向的函數載入類別,此時並沒有檢查 __autoload() 函數是否定義。

透過對PHP自動載入流程的了解,可以看到PHP實際上提供了兩種方法來實現自動裝載機制:

一種我們前面已經提到過,是使用用戶定義的__autoload()函數,這通常在PHP原始程式中來實現;

另外一種是設計一個函數,將autoload_func指標指向它,這通常使用C語言在PHP擴充中實現,即SPL autoload機制。

如果兩種方式都實作了,也就是 autoload_func 不等於NULL,程式只會執行第二種方式,__autoload() 函數是不會被執行的。

先看一個SPL 自動載入範例:

B.php文件不变
A.php
<?php
class A{
    public function test(){
        $b_object = new B();
        $b_object->echo_info();
    }
}

function __autoload($classname){
    require $classname.&#39;.php&#39;;//include &#39;b.php&#39;;
}

function my_autoload($classname){
    require $classname.&#39;.php&#39;;//include &#39;b.php&#39;;
    echo &#39;my_autoload   &#39;;
}

spl_autoload_register(&#39;my_autoload&#39;);
$a_object = new A();
$a_object->test();

结果:my_autoload  我是class B中的方法执行结果
?>

在這個小例子,可以看到,透過spl_autoload_register('my_autoload'),實作了當程式執行找不到類別B時,會執行自訂的my_autoload()函數,載入B類。實際上 spl_autoload_register(’my_autoload’) 的作用就是 把autoload_func 指標指向 my_autoload()。現在,整個PHP 自動載入過程就明白了。

詳細分析SPL自動載入過程

#首先還是剛剛的小例子,假如把spl_autoload_register('my_autoload') 改成spl_autoload_register()不添加任何參數,B類能被載入嗎?答案是:YES。 

為什麼呢?

因为SPL扩展内部自己定义了一个自动加载函数 spl_autoload(),实现了自动加载的功能,如果我们不定义自己的自动加载函数,并且程序里写了 spl_autoload_register()(如果不传参数,必须是第一次执行才会有效)或者 spl_autoload_register(’spl_autoload’),那么autoload_func 指针就会指向内部函数 spl_autoload()。程序执行的时候如果找不到相应类就会执行该自动加载函数。

那么,SPL 是怎么实现autoload_func 指针指向不同的函数呢?

原来,在SPL内部定义了 一个函数 spl_autoload_call() 和 一个全局变量autoload_functions。autoload_functions本质上是一个HashTable,不过我们可以将其简单的看作一个链表,链表中的每一个元素都是一个函数指针,指向一个具有自动加载类功能的函数。

spl_autoload_call()的作用就是按顺序遍历 autoload_functions,使得autoload_func指向每个自动加载函数,如果加载成功就停止,如果不成功就继续遍历下个自动加载函数,直到加载成功或者遍历完所有的函数。

那么,autoload_functions 这个列表是谁来维护的呢?就是 spl_autoload_register() 这个函数。我们说的自动加载函数的注册,其实就是通过spl_autoload_register()把自动加载函数加入到 autoload_functions 列表。

到此为止,整个自动加载的流程就是分析结束了。

  相关SPL自动加载函数:
  spl_autoload_functions() //打印autoload_functions列表
  spl_autoload_unregister() //注销自动加载函数

以上便是php自动加载原理的全部介绍,想了解更多相关内容请访问PHP中文网:PHP视频教程

以上是詳細介紹php自動載入原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
酸與基本數據庫:差異和何時使用。酸與基本數據庫:差異和何時使用。Mar 26, 2025 pm 04:19 PM

本文比較了酸和基本數據庫模型,詳細介紹了它們的特徵和適當的用例。酸優先確定數據完整性和一致性,適合財務和電子商務應用程序,而基礎則側重於可用性和

PHP安全文件上傳:防止與文件相關的漏洞。PHP安全文件上傳:防止與文件相關的漏洞。Mar 26, 2025 pm 04:18 PM

本文討論了確保PHP文件上傳的確保,以防止諸如代碼注入之類的漏洞。它專注於文件類型驗證,安全存儲和錯誤處理以增強應用程序安全性。

PHP輸入驗證:最佳實踐。PHP輸入驗證:最佳實踐。Mar 26, 2025 pm 04:17 PM

文章討論了PHP輸入驗證以增強安全性的最佳實踐,重點是使用內置功能,白名單方法和服務器端驗證等技術。

PHP API率限制:實施策略。PHP API率限制:實施策略。Mar 26, 2025 pm 04:16 PM

本文討論了在PHP中實施API速率限制的策略,包括諸如令牌桶和漏水桶等算法,以及使用Symfony/Rate-limimiter之類的庫。它還涵蓋監視,動態調整速率限制和手

php密碼哈希:password_hash和password_verify。php密碼哈希:password_hash和password_verify。Mar 26, 2025 pm 04:15 PM

本文討論了使用password_hash和pyspasswify在PHP中使用密碼的好處。主要論點是,這些功能通過自動鹽,強大的哈希算法和SECH來增強密碼保護

OWASP前10 php:描述並減輕常見漏洞。OWASP前10 php:描述並減輕常見漏洞。Mar 26, 2025 pm 04:13 PM

本文討論了OWASP在PHP和緩解策略中的十大漏洞。關鍵問題包括注射,驗證損壞和XSS,並提供用於監視和保護PHP應用程序的推薦工具。

PHP XSS預防:如何預防XSS。PHP XSS預防:如何預防XSS。Mar 26, 2025 pm 04:12 PM

本文討論了防止PHP中XSS攻擊的策略,專注於輸入消毒,輸出編碼以及使用安全增強的庫和框架。

PHP接口與抽像類:何時使用。PHP接口與抽像類:何時使用。Mar 26, 2025 pm 04:11 PM

本文討論了PHP中接口和抽像類的使用,重點是何時使用。界面定義了無實施的合同,適用於無關類和多重繼承。摘要類提供常見功能

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)