萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP include_path 用法詳解

PHP include_path 用法詳解

ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'));
我們看到這個程序動態修改include_path。不過cake在這兒是把 CAKE_CORE_INCLUDE_PATH 和 APP_DIR 加到 include_path裡,並且優先在這兩個目錄下找包含程序。
注意到它這裡用到了PATH_SEPARATOR這個變量。這樣這段代碼在windows和linux下能通用。

從中受到啟發,我們可以根據自己的需要把一些include目錄動態的加入進來。比如說我們有很多libs:lib1,lib2,lib3等等。我們不必把這些libs都加到include_path裡,因為它們之間可能沖突。
可以建立一個inc_dir,並把這個目錄加入到include_path。在inc_dir下,分別建立inc_path1.php教程 inc_path2.php inc_path3.php
分別寫入
<?php
ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.$dirToLib1);
<?php
ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.$dirToLib2);
<?php
ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.$dirToLib3);

在寫程序的時候,比如要用lib2的functions.php
就可以這麼寫
<?php
require 'inc_path2.php';
require 'functions.php';

 

當時候函數include(),require(),fopen_with_path()函數來尋找文件時候.在不設置include_path的情況下,這些函數打開文件時候默認的是以web根目錄去尋找.當設置include_path以後,這些php函數就會先在指定的include_path目錄下面去搜索尋找.

其原理和window系統的環境變量相似,在window運行cmd命令的時候,輸入一些cmd的命令之後系統會在其設定的環境變量裡面去搜索這些命令是否存在,存在就可以執行.


2.include_path的設置
第一種方法:

修改php.ini文件中的include_path項。

include_path = .:/usr/local/lib/php:./include
第二個方法:

使用ini_set方法。
ini_set("include_path", ".:../:./include:../include");     

3.注意
zendframework include 設置 index.php

復制代碼 代碼如下:
set_include_path('.' .PATH_SEPARATOR.'../library/'
.PATH_SEPARATOR.'./application/models/'
.PATH_SEPARATOR.'./application/lib/'
.PATH_SEPARATOR.get_include_path());

PATH_SEPARATOR是一個常量,在Linux系統中是一個" : "號,Windows上是一個";"號。

所以編寫程序時最好用常量 PATH_SEPARATOR 代替,否則如果系統從linux移植到win系統或反過來移植會出錯!
get_include_path取得當前已有的環境變量,加上前面的設置就是新的系統include

include_path是怎麼起作用的?
如果有多個include_path順序是怎麼樣的?
什麼情況下include_path不起作用?
今天, 我就全面的介紹下這個問題, 先從一個例子開始吧.
如下的目錄結構:

  •   root
  •     ├ 1.php
  •     ├ 3.php
  •     └ subdir
  •          ├ 2.php
  •           └ 3.ph

在1.php中:

  • <?php
  • ini_set(“include_path”, “.:path_to_subdir”);
  • require(“2.php”);
  • ?></SPAN

而在2.php中:

  • <?php
  • require(“3.php”);
  • ?></SPAN

而在root目錄下的3.php打印出”root”, 在subdir目錄下的3.php打印出”subdir”;
現在, 我的問題來了:
1. 當在root目錄下運行1.php, 會得到什麼輸出?
2. 在subdir下運行上一級目錄的1.php, 有會得到什麼輸出?
3. 當取消include_path中的當前目錄path(也就是include_path=”path_to_subdir”), 上面倆個問題又會是什麼輸出?
PHP中的include_path
PHP在遇到require(_once)/include(_once)的指令的時候, 首先會做如下的判斷:

  • 要包含的文件路徑是絕對路徑麼?
  • 如果是, 則直接包含, 並結束.
  • 如果不是, 進入另外的邏輯(經過多次調用, 宏展開後進入_php_stream_fopen_with_path)尋找此文件

接下來, 在_php_stream_fopen_with_path中, 會做如下判斷:

  • 要包含的文件路徑是相對路徑麼(形如./file, ../dir/file, 以下用”目錄相對路徑代替”)?
  • 如果是, 則跳過include_path的作用邏輯, 直接解析相對路徑(隨後單獨介紹)

會根據include_path,和當前執行文件的path組成一個待選的目錄列表, 比如對於文章前面的例子來說, 會形成一個如下的待選列表

  • “.:path_to_subdir:current_script_dir

然後, 依次從待選列表頭部開始, 根據DEFAULT_DIR_SEPARATOR(本文的環境是”:”)取出待選列表中的一個路徑, 然後把要包含的文件名附加在這個路徑後面, 進行嘗試. 如果成功包含, 則返回, 否則繼續下一個待選路徑.
到現在為止, 我們已經可以回答我開頭提出的3個問題了.
1. 因為在root目錄下執行, 所以在1.php中包含2.php的時候, include_path的第二個待選路徑起了作用(path_to_subdir), 找到了path_to_subdir/2.php, 而在2.php包含3.php的時候, 當前工作目錄是root下, 所以在包含3.php的時候, include_path的第一個待選路徑”.”(當前工作目錄)下就找到的匹配的文件, 所以得到的輸出是”root”.
2. 同1, 只不過當前的路徑是subdir, 所以得到的輸出是”subdir”.
3. 因為沒有了當前路徑為include_path, 所以在root目錄下運行的時候2.php中包含3.php的時候, 是path_to_subdir起了作用, 所以無論在root還是subdir都將得到”subdir”的輸出.
而如果在2.php中清空include_path,

  • <?php
  • ini_set(“include_path”, ”);
  • require(“3.php”);
  • ?></SPAN

那麼將會是current_script_dir起作用, 而這個時候current_script_dir是2.php的路徑, 所以還是會得到”subdir”的輸出.
目錄相對路徑
在使用目錄相對路徑的情況下, 相對路徑的基點, 永遠都是當前工作目錄.
為了說明在目錄相對路徑下的情況,我們再看個列子, 還是上面的目錄結構, 只不過1.php變成了:

  • <?php
  • ini_set(“include_path”, “/”);
  • require(“./subdir/2.php”);
  • ?></SPAN

2.php變成了:

  • <?php
  • require(“./3.php”);
  • ?></SPAN

如果在root目錄下執行, 2.php中尋找3.php將會在當前目錄的相對路徑下尋找, 所以得到的輸出是”root”, 而如果是在subdir下執行上一級目錄的1.php(php -f ../1.php), 將會因為在subdir下找不到”./subdir/2.php”而異常退出.
後記
1. 因為使用include_path和相對路徑的情況下, 性能會和尋找的次數有關, 最壞的情況下, 如果你有10個include_path, 那麼最多可能會重試11次才能找到要包含的文件, 所以, 在能使用絕對路徑的情況下最好使用絕對路徑.

copyright © 萬盛學電腦網 all rights reserved