PHP自動加載類__autoload()淺談


在面向對象編程中,都是以對象為單位的操作,如果我有兩個不同的類,類A和類B,在同一個文件里,實例化對象,就能在這個文件同時調用類A和類B的函數

 1 <?php
 2 #a.php
 3 
 4 class A{
 5     public function funA()
 6     {
 7         echo 'The class:'.__class__.'<br/>';
 8     }
 9 }
10 
11 class B{
12     public function funB()
13     {
14         echo 'The class:'.__class__.'<br/>';
15     }
16 }
17 $a = new A();
18 $b = new B();
19 $a->funA(); //The class:A
20 $b->funB(); //The class:B

兩個類都在同一個文件,所有能運行成功,但現在大部分應用都分MVC,不同類專門處理特定的事物,比如C(Controller),只執行與事物有關的邏輯操作,這些文件很明顯分屬於不同目錄下:

|—root

    |—controller

        |—controllerA.php

    |—model

       |—modelA.php

  |—view

        |—viewA.php

這時我要在modelA.php里怎么引用controllerA.php的函數呢?這就用到__autoload()了。

 1 <?php
 2 #保存在MyClass.php
 3 
 4 class MyClass {
 5 
 6     public function getNamespace()
 7     {
 8         return get_class($this);
 9     }
10 }

 

現在我們在同級目錄下引用這個類

 1 <?php
 2 
 3 function __autoload($name)
 4 {
 5     $file = realpath(__DIR__).'/'.$name.'.php';
 6     if(file_exists($file))
 7         {
 8                 require_once($file);
 9         if(class_exists($name,false))
10                 {
11             return true;
12                 }
13                 return false;
14           }
15           return false;
16 }
17 
18 $obj = new MyClass();
19 echo $obj->getNamespace();    //輸出 MyClass;

 當你引用不存在的類時,__autoload就會被調用,並且你的類名會被作為參數傳送過去(當你同時使用命名空間,包含命名空間部分會一起作為參數傳送)。

 

下面我們把命名空間和自動加載類合並使用

命名空間,PHP從5.3開始支持命名空間(namespace),這個在C語言里非常常見,剛開始我不理解,直到我完整接觸一個項目,需要加載在不同目錄下Class時,恍然大悟。OK,下面講一講自己的理解吧。

用不同的命名空間區別相同的函數名,同時命名空間也可以作為引入類文件的路徑。

(在WEB項目中,當在client輸入一個url時,一般會有一個入口文件,在這個文件里解析你要調用的controller,以及傳遞的參數,然后動態的加載相應類文件,這其實就牽扯到一點路由規則,當然還有另外一種,在項目初始化之初就把所有類文件全部加載在內存中,這樣,每次請求響應都不用再加載,常駐內存后響應要快點。)

 

 1 <?php
 2 #首先建立一個MyClass目錄,在該目錄下新MyClass.php文件,代碼如下。
 3 
 4 namespace MyClass;
 5 
 6 class MyClass {
 7 
 8         public function getNamespace()
 9         {
10                 return get_class($this);
11         }
12 }

 

 1 <?php
 2 #在跟MyClass目錄同級的目錄下,新建一個文件,內容如下
 3 function __autoload($name)
 4 {
 5     $class_path = str_replace('\\',DIRECTORY_SEPARATOR,$name);   //把表示命名空間的分割符號,轉換成表示目錄結構的斜線
 6     $file = realpath(__DIR__).'/'.$class_path.'.php';   
 7     if(file_exists($file))
 8         {
 9                 require_once($file);    //引入文件
10         if(class_exists($name,false))    //帶有命名空間的類名
11                 {
12             return true;
13                 }
14                 return false;
15           }
16           return false;
17 }
18 echo MyClass\MyClass::getNamespace();    //輸出: MyClass\MyClass;

這樣非常容易避免了,當一個項目非常大時,不停的require文件。

讓我們再思考,有沒有更工程化的解決方案?當然有,我們可以建立自己的 Autoload 類,在這個類里面自動加載不同的類(可以包含命名空間),需要引用其他類的文件,只需要顯示寫入這個 Autoload 類即可。

具體實現放在下一篇博客 ^_^ .( http://www.cnblogs.com/CpNice/p/4369399.html )

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM