php--include 、require

K戰神發表於2017-06-21

一、include 、require  

   定義:包含並執行指定檔案

   問題:查詢了這兩個語言結構的資料,有人說,什麼require  先執行,什麼include後執行.

   思考:我覺得官方文件已經解釋的很清楚了。這個兩個引數的區別在於報錯處理:

      include 遇到錯誤會警告,程式繼續.

      require 遇到錯誤報錯,程式結束.

  由此可見,引申出了 "先執行後執行" 的問題:

    假如,我在程式執行過程中需要載入一個檔案,你說我用哪一個? -- 用 include , 程式執行過程中,有問題會報警但不會終止執行.

    所以,我在程式執行時載入檔案,用include。相反,如果我在程式開始時就載入檔案,可以考慮用require.

二、require_once  和 include_once :

  定義:相比於上面,唯一區別是 PHP 會檢查該檔案是否已經被包含過,如果是則不會再次包含.

        這個就更好理解了,對於一個檔案可能被載入多次,建議使用_once.

三、看看YII原始碼中的使用例項:

0、require

 1 public function createController($route,$owner=null)
 2     {
 3             ......
42             if(is_file($classFile))
43             {
44                 if(!class_exists($className,false))
45                     require($classFile);//這裡
46                 if(class_exists($className,false) && is_subclass_of($className,'CController'))
47                 {
48                     $id[0]=strtolower($id[0]);
49                     return array(
50                         new $className($controllerID.$id,$owner===$this?null:$owner),
51                         $this->parseActionParams($route),
52                     );
53                 }
54                 return null;
55             }
56             $controllerID.=$id;
57             $basePath.=DIRECTORY_SEPARATOR.$id;
58         }
59     }

 

這裡使用了require,但是上下文中包含是否含有此檔案判斷,這個地方牽扯到建立controller,如此關鍵的步驟,需要讓它有問題報錯提示。

1、require_once  

1 <?php
2 
3 // change the following paths if necessary
4 $yii=dirname(__FILE__).'/../../framework/yii.php';
5 $config=dirname(__FILE__).'/protected/config/main.php';
6 // remove the following line when in production mode
7 // defined('YII_DEBUG') or define('YII_DEBUG',true);
8 require_once($yii);
9 Yii::createWebApplication($config)->run();

 

 這是某個apps下的入口檔案,入口檔案,會多次執行,所以只要驗證載入了就不在載入。

2、include

 1     public static function autoload($className,$classMapOnly=false)
 2     {
 3         // use include so that the error PHP file may appear
 4         if(isset(self::$classMap[$className])) {
 5 
 6             include(self::$classMap[$className]);
 7         }
 8         elseif(isset(self::$_coreClasses[$className]))
 9             include(YII_PATH.self::$_coreClasses[$className]);
10         elseif($classMapOnly)
11             return false;
12         else
13         {
14             // include class file relying on include_path
15         .....

 

1 private static $_coreClasses=array(
2         'CApplication' => '/base/CApplication.php',
3         'CApplicationComponent' => '/base/CApplicationComponent.php',
4         'CBehavior' => '/base/CBehavior.php',
5         'CComponent' => '/base/CComponent.php',
6 
7         'CCache' => '/caching/CCache.php',

擷取一部分,這個autoload方法,根據引數classname作為key,從註冊的_coreClasses提取value。

這裡使用的是include,因為是在程式執行期間動態載入檔案,所以使用了include.我想原因可能是載入的檔案很多,不能保證所有檔案不會變化,所以用到載入一遍,保證最新。

3、include_once

 1 function highlight($str)
 2     {
 3         if (!($this->_renderer)) {
 4             include_once(dirname(__FILE__).'/Renderer/Html.php');
 5             $this->_renderer = new Text_Highlighter_Renderer_Html($this->_options);
 6         }
 7         $this->_state = -1;
 8         $this->_pos = 0;
 9         $this->_stack = array();
10         $this->_tokenStack = array();
11         $this->_lastinner = $this->_defClass;
12         $this->_lastdelim = $this->_defClass;
13         $this->_endpattern = '';
14         $this->_renderer->reset();
15         $this->_renderer->setCurrentLanguage($this->_language);
16         $this->_str = $this->_renderer->preprocess($str);
17         $this->_len = strlen($this->_str);
18         while ($token = $this->_getToken()) {
19             $this->_renderer->acceptToken($token[0], $token[1]);
20         }
21         $this->_renderer->finalize();
22         return $this->_renderer->getOutput();
23     }

這個高亮處理函式,就是採用了_once載入,目的也是執行中載入,並且只載入一次。

 四、YII處理思路--動態載入

  1、指定方法,註冊到__autoload.

  2、將可能用到的檔案,以key-value形式儲存為靜態變數.

  3、根據key(類名),對應出檔案路徑,使用 include 執行中載入.  

總結:我覺得,決定怎樣麼用,需要結合專案,根據實際需要進行呼叫此語法結構。--以上如有錯誤請指出,我會及時更正,轉php的道路上...

 

相關文章