php的类装载的步骤,设计PHP自动类装载功能
在使用面向?qū)ο蠓椒ㄗ鯬HP開發(fā)時,可能會經(jīng)常使用到各個路徑中的類文件,這就需要大量的 include 或 require,而 PHP 提供了一個比較快捷的方式,就是利用函數(shù) __autoload 可以編程實現(xiàn)動態(tài)的類裝載功能,這樣就不需要手動的編寫大量include 或 require,好了,下面切入正題。
設(shè)計思路:如果想實現(xiàn)自動類裝載功能,就必須使用 PHP 提供的 __autoload 函數(shù),該函數(shù)只有一個參數(shù),即我們在程序編寫時所涉及到的類名稱,當(dāng)函數(shù)被調(diào)用時,我們要做的就是利用傳入的類名加載這個類所在的文件。
第一個問題就是,我們?nèi)绾蔚弥悓儆谀膫€文件名呢?在做 Java 或 .Net 程序時,整個運行的程序會根據(jù)類名在內(nèi)存中查找對應(yīng)的類型信息(常常會伴隨著命名空間作為限定),內(nèi)存的類型信息來自于應(yīng)用程序初始化時的類文件裝載,這點與 PHP 是有區(qū)別的,PHP 程序不會裝載所有內(nèi)容,它只是在代碼運行到某處需要裝載必要的文件時才會發(fā)出裝載請求。暫時拋棄何時裝載這個問題,再次回到裝載類文件,不管是 .Net 還是 Java,它們在裝載類型信息的時候,都是類名查找類型信息的,從這點看來 __autoload 采用的也是相同的方法,但是 PHP 在定義類時并不要求文件名與類名保持一致,這就有可能造成文件與類雜亂無章,給類裝載實現(xiàn)帶來麻煩,所以有必要人為的規(guī)定類定義與其所在的文件需要采用相同的名稱,或者兩者之間按照某種規(guī)則可以互相映射,這樣就很容易。
第二個問題,類所在的文件名已經(jīng)可以確定,但是這個文件是屬于哪個目錄呢?Java 可以根據(jù)包名來進行查找,.Net 有命名空間,雖然新版本的 PHP 引入了命名空間的概念,但是既存的服務(wù)器也許會因為多種原因不能為每個客戶提供最新的環(huán)境,所以還是得從 PHP 本身下手比較實用。雖然沒有命名空間,但是可以借鑒操作系統(tǒng)的環(huán)境變量概念,將不同的路徑名放入環(huán)境變量中,這樣就可以從環(huán)境變量中讀取各個目錄,然后找到目標類所在的文件。
一、類名與文件名映射
這一步要做的就是定義文件名與類名映射規(guī)則,類名采用駝峰命名法,即類名的每個單詞首字母需大寫,而文件的命名則采用全部單詞小寫,單詞之間以下劃線分割,后綴名為 .class.php 。
二、在環(huán)境變量中進行路徑遍歷
仿照 UNIX 或 Windows 的環(huán)境變量的定義方式,將多個文件夾以分號或冒號分隔,羅列在 CLASSPATH 中。當(dāng)程序讀取時,可以將文件夾路徑放入數(shù)組中。
三、開始裝載
調(diào)用函數(shù) require 或 include 并利用組合好的文件路徑進行文件裝載,但是有兩處需要注意,首先需要判斷組合好的路徑是否有效,其次,文件成功裝載后,為了效率問題,可以馬上退出 __autoload 函數(shù)。
define(CLASSPATH, dirname(__FILE__).'/entity'.':'.dirname(__FILE__).'/meta');function __autoload($classname) {
$filename = strtolower(preg_replace('/(?<=/B)([A-Z])/s', '_$1', $classname)) . ".class.php";
foreach (preg_split('/:/',CLASSPATH) as $cp) {
if (file_exists("$cp/$filename")) {
require_once ("$cp/$filename");
break;
}
}
}
四、啟用自動類裝載功能
主動式:將該函數(shù)直接或間接包含在當(dāng)前文件中,之后無論在文件何處編寫代碼,類文件都可以自動裝載。
被動式:將該函數(shù)直接或間接包含在當(dāng)前文件中,以當(dāng)前文件為主控制程序,然后調(diào)用其它業(yè)務(wù)實現(xiàn),這樣在其他業(yè)務(wù)實現(xiàn)文件中就無需考慮類裝載的問題了。
在圖中采用的是主動式,question_parser.php 通過創(chuàng)建 meta 中存放的類,這些類又調(diào)用 entity 中的內(nèi)容,這個過程僅僅在 question_parser.php 包含了定義 __autoload 的 question_sysext.php,關(guān)系圖如下:
question_parser.php -> question_sysext.php
||
//
meta* => entity*
五、擴展思考
如果文件名與類名無任何關(guān)聯(lián)性的話,可以裝載 CLASSPATH 中定義的文件夾中所有 *.php 文件或是像例子那樣裝載 *.class.php 。
緩存類裝載,當(dāng)成功裝載一個類所在的文件后,可以將類名與文件名記錄下來以便下次使用,這樣就無需每次都進行循環(huán)遍歷,在某些情況下可以節(jié)省查找時間。
總結(jié)
以上是生活随笔為你收集整理的php的类装载的步骤,设计PHP自动类装载功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win2012 ad用户和计算机,Ser
- 下一篇: 动态规划算法php,php算法学习之动态