CI框架原始碼解析一之入口檔案index.php
Index.php作為CI框架的入口檔案,原始碼分析,自然而然由此開始。在原始碼分析的過程中,我們並不會逐行進行解釋,而只解釋核心的功能和實現,如果英文水平很好的話,讀過index.php檔案的英文註釋之後也就基本明白了inde.php都做了些什麼。本來想第一篇寫解析CI框架的目錄結構的,像這一般網上一搜都是一大堆,也就放棄了這個想法。博主是基於CodeIgniter-v3.1.0最新版本進行解讀分析。ok,書歸正傳,在博主看來CI框架的index.php檔案一共完成了四項工作:
① 設定框架應用的環境狀態
② 配置系統、應用、檢視等程式目錄以及得到其路徑
③ 系統、應用、檢視等目錄的正確性驗證
④ 載入 core/CodeIgniter.php框架核心檔案,啟動框架
1、設定框架應用的環境狀態
define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');
這裡的development可以是任何你喜歡的環境名稱(比如working,再如debug),相對應的,你要在下面的switch case程式碼塊中,對設定的環境做相關的錯誤等級控制。(CI框架設定了三種應用場景狀態,分別是:development(開發),testing(測試),production(產品)。development(開發)狀態,也就是預設的狀態下會產生錯誤報告,testing(測試),production(產品)狀態下則不會產生錯誤報告)否則,CI框架會認為你沒有配置好相應的環境,從而退出程序並給出對應的錯誤資訊:
default: //header() 被用來發送自定義的 HTTP 報文。關於HTTP報文的更多資訊請參考php手冊 header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); echo 'The application environment is not set correctly.'; exit(1);
之所以一定要配置配置ENVIRONMENT?這是因為,CI框架中很多元件都依賴於ENVIRONMENT的配置,例如,檢視system/config/Common.php, 這其中有一段引入配置檔案的程式碼,是這樣實現的:
if (file_exists(APPPATH . 'config/' . ENVIRONMENT . '/mimes.php')) { $_mimes = include(APPPATH . 'config/' . ENVIRONMENT . '/mimes.php'); } elseif (file_exists(APPPATH . 'config/mimes.php')) { $_mimes = include(APPPATH . 'config/mimes.php'); } else { $_mimes = array(); }
在CI框架中,很多配置檔案都是通過這種方式引入的,因此ENVRIONMENT對於CI框架的正確執行時必須的,所以需要在開始的時候配置好ENVIRONMENT。設定ENVIRONMENT的一個好處是:可以很方便的切換系統的配置而不必修改系統程式碼。例如,在系統進入測試階段時,database配置為測試的資料庫,而在系統測試完畢時,database切換到線上的資料庫。這好比是用一個開關控制了系統的環境切換,自然是非常方便的。
2、配置系統、應用、檢視等程式目錄以及得到其路徑
CI框架允許你將系統核心原始碼和應用程式程式碼進行分開放置,但是你必須設定好系統的system資料夾和application資料夾(同樣,資料夾名字可以是任何合法的資料夾名稱,而不一定使用’system’和’application’)的名稱、路徑等資訊:
//定義系統目錄名稱 $system_path = 'system'; //定義你的應用目錄名稱 $application_folder = 'application'; //檢視檔案存放目錄 //如果要將檢視目錄移到應用程式目錄,則設定在此處的路徑。如果空白,它將預設為您的應用程式目錄中的標準位置。 $view_folder = '';
下面有這樣一段程式碼,然後很多人就不明白為什麼要放這樣幾句程式碼了,在這裡特別說明一下:
if (defined('STDIN')) { //chdir函式用來改變目錄 chdir(dirname(__FILE__)); }
這段程式碼主要是用來幹嘛的呢?首先,STDIN、STDOUT、STDERR是PHP以 CLI(Command Line Interface)模式執行而定義的三個常量,這三個常量類似於Shell的stdin,stdout,stdout,分別是PHP CLI模式下的標準輸入、標準輸出和標準錯誤流。也就是說,這三行程式碼是為了保證命令列模式下,CI框架可以正常執行。
3、系統、應用、檢視等目錄的正確性驗證
1) 系統(system)檔案目錄的正確性驗證
//得到規範化的絕對路徑名 //此段程式碼用於判斷生成system系統檔案目錄 if (($_temp = realpath($system_path)) !== FALSE) { //$system_path就是當前你的CI框架核心檔案所存放的絕對路徑名 $system_path = $_temp . DIRECTORY_SEPARATOR; } else { $system_path = strtr(rtrim($system_path, '/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; } //如果$system_path所指向的檔案目錄不存在,則die if (!is_dir($system_path)) { header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); echo 'Your system folder path does not appear to be set correctly. Please open the following file and correct this: ' . pathinfo(__FILE__, PATHINFO_BASENAME); exit(3); // EXIT_CONFIG }
2) 應用(application)檔案目錄的正確性驗證
//此段程式碼用於判斷生成application應用檔案目錄 if (is_dir($application_folder)) { if (($_temp = realpath($application_folder)) !== FALSE) { $application_folder = $_temp; } else { $application_folder = strtr(rtrim($application_folder, '/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR); } } elseif (is_dir(BASEPATH . $application_folder . DIRECTORY_SEPARATOR)) { $application_folder = BASEPATH . strtr(trim($application_folder, '/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR); } else { header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: ' . SELF; exit(3); }
3) 檢視(view)檔案目錄的正確性驗證
//此段程式碼用於判斷生成view檢視檔案目錄 if (!isset($view_folder[0]) && is_dir(APPPATH . 'views' . DIRECTORY_SEPARATOR)) { $view_folder = APPPATH . 'views'; } elseif (is_dir($view_folder)) { if (($_temp = realpath($view_folder)) !== FALSE) { $view_folder = $_temp; } else { $view_folder = strtr(rtrim($view_folder, '/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR); } } elseif (is_dir(APPPATH . $view_folder . DIRECTORY_SEPARATOR)) { $view_folder = APPPATH . strtr(trim($view_folder, '/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR); } else { header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: ' . SELF; exit(3); }
幾個定義的常量(PATH結尾的常量表示目錄路徑,DIR結尾的變量表示目錄名):
//SELF(這裡指index.php檔案) define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME)); //BASEPATH(system資料夾的路徑) define('BASEPATH', $system_path); //FCPATH(前端控制器的路徑) define('FCPATH', dirname(__FILE__) . DIRECTORY_SEPARATOR); //SYSDIR(系統system目錄名) define('SYSDIR', basename(BASEPATH)); //APPPATH(應用程式路徑) define('APPPATH', $application_folder . DIRECTORY_SEPARATOR); //VIEWPATH(檢視目錄路徑) define('VIEWPATH', $view_folder . DIRECTORY_SEPARATOR);
注:檢視所有常量的方法:
var_dump(get_defined_constants());
4、載入 core/CodeIgniter.php框架核心檔案,啟動框架
入口檔案的最後一行,引入CodeIgniter.php框架核心檔案(也是下一步框架執行的關鍵)。CodeIgniter.php被稱為bootstrap file,也就是它是一個引導檔案,是CI框架執行流程的核心檔案。
//最後就是載入CI框架的核心引導檔案了 require_once BASEPATH . 'core/CodeIgniter.php';
總結一下,index.php並沒有做太多複雜的工作,而是類似軍隊中押運糧草的,兵馬未動糧草先行,為CI框架的執行提供了一系列配置引數和正確性驗證,而這些配置和驗證,是CI框架能夠正常執行的關鍵。
最後,貼一下整個index.php檔案的原始碼(註釋版):
<?php
/**
* =======================================
* Created by Pocket Knife Technology.
* User: ZhiHua_W
* Date: 2016/10/14 0020
* Time: 下午 2:14
* Project: CodeIgniter框架—原始碼分析
* Power: Analysis for Index.php
* =======================================
*/
/**
* 框架的第一步就是定義框架程式碼當前的使用場景狀態
* 一共有development(開發),testing(測試),production(產品)三個場景狀態
* 不同的場景狀態將會產生不同級別的錯誤報告
*/
define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');
/**
* 這裡就會對場景狀態進行判斷
* development(開發)狀態,也就是預設的狀態下會產生錯誤報告
* testing(測試),production(產品)狀態下則不會產生錯誤報告
*/
switch (ENVIRONMENT) {
case 'development':
//error_reporting()函式是php的內建函式,用來設定php的報錯級別並返回當前級別
//函式語法:
//error_reporting(report_level) report_level引數是錯誤等級,一共有已下幾種:
//值 常量 描述
//1 E_ERROR 致命的執行錯誤。錯誤無法恢復,暫停執行指令碼
//2 E_WARNING 執行時警告(非致命性錯誤)。非致命的執行錯誤,指令碼執行不會停止
//4 E_PARSE 編譯時解析錯誤。解析錯誤只由分析器產生
//8 E_NOTICE 執行時提醒(這些經常是你程式碼中的bug引起的,也可能是有意的行為造成的。)
//16 E_CORE_ERROR PHP啟動時初始化過程中的致命錯誤
//32 E_CORE_WARNING PHP啟動時初始化過程中的警告(非致命性錯)。
//64 E_COMPILE_ERROR 編譯時致命性錯。這就像由Zend指令碼引擎生成了一個E_ERROR
///128 E_COMPILE_WARNING 編譯時警告(非致命性錯)。這就像由Zend指令碼引擎生成了一個E_WARNING警告
//256 E_USER_ERROR 使用者自定義的錯誤訊息。這就像由使用PHP函式trigger_error(程式設計師設定E_ERROR)
//512 E_USER_WARNING 使用者自定義的警告訊息。這就像由使用PHP函式trigger_error(程式設計師設定的一個E_WARNING警告)
//1024 E_USER_NOTICE 使用者自定義的提醒訊息。這就像一個由使用PHP函式trigger_error(程式設計師一個E_NOTICE集)
//2048 E_STRICT 編碼標準化警告。允許PHP建議如何修改程式碼以確保最佳的互操作性向前相容性
//4096 E_RECOVERABLE_ERROR 開捕致命錯誤。這就像一個E_ERROR,但可以通過使用者定義的處理捕獲(又見set_error_handler())
//8191 E_ALL 所有的錯誤和警告(不包括 E_STRICT) (E_STRICT will be part of E_ALL as of PHP 6.0)
//更為具體的用法大家可以查詢php手冊
error_reporting(-1);
//ini_set用來設定php.ini的值,在函式執行的時候生效,指令碼結束後,設定失效。
//無需開啟php.ini檔案,就能修改配置,對於虛擬空間來說,很方便。
//不是所有的引數都可以配置,可以檢視手冊中的列表。
//可以使用ini_get來獲取所設定的值,例如:echo ini_get('display_errors');
ini_set('display_errors', 1);
break;
case 'testing':
case 'production':
ini_set('display_errors', 0);
//version_compare() 用於對比兩個「PHP 規範化」的版本數字字串。 這對於編寫僅能相容某些版本 PHP 的程式很有幫助。
if (version_compare(PHP_VERSION, '5.3', '>=')) {
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
} else {
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE);
}
break;
default:
//header() 被用來發送自定義的 HTTP 報文。關於HTTP報文的更多資訊請參考php手冊
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'The application environment is not set correctly.';
exit(1); // EXIT_ERROR
}
/**
* 定義系統目錄名稱
* 此變數必須包含您的“系統”目錄的名稱。如果它不在與此檔案相同的目錄中,則設定路徑。
* 裡面存放的是CI框架的各種核心檔案。
*/
$system_path = 'system';
/**
* 定義你的應用目錄名稱
* 如果你希望此前控制器使用不同的“應用程式”目錄,而不是預設的“應用程式”目錄,你可以在這裡設定它的名稱。
*/
$application_folder = 'application';
/**
* 檢視檔案存放目錄
* 如果要將檢視目錄移到應用程式目錄,則設定在此處的路徑。如果空白,它將預設為您的應用程式目錄中的標準位置。
*/
$view_folder = '';
// --------------------------------------------------------------------
// END OF USER CONFIGURABLE SETTINGS. DO NOT EDIT BELOW THIS LINE
//使用者可配置設定的結束。不要在這條線下編輯
//這裡只是CI框架進行一下提示,如果你想改動的話,還是可以的
// --------------------------------------------------------------------
//設定正確的目錄
/**
* STDIN、STDOUT、STDERR是PHP以 CLI(Command Line Interface)模式執行而定義的三個常量,
* 這三個常量類似於Shell的stdin,stdout,stdout,分別是PHP CLI模式下的標準輸入、標準輸出和標準錯誤流。
* 也就是說,這三行程式碼是為了保證命令列模式下,CI框架可以正常執行。
*/
if (defined('STDIN')) {
//chdir函式用來改變目錄
chdir(dirname(__FILE__));
}
//得到規範化的絕對路徑名
//此段程式碼用於判斷生成system系統檔案目錄
if (($_temp = realpath($system_path)) !== FALSE) {
//$system_path就是當前你的CI框架核心檔案所存放的絕對路徑名
$system_path = $_temp . DIRECTORY_SEPARATOR;
} else {
$system_path = strtr(
rtrim($system_path, '/\\'),
'/\\',
DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR
) . DIRECTORY_SEPARATOR;
}
//如果$system_path所指向的檔案目錄不存在,則die
if (!is_dir($system_path)) {
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'Your system folder path does not appear to be set correctly. Please open the following file and correct this: ' . pathinfo(__FILE__, PATHINFO_BASENAME);
exit(3); // EXIT_CONFIG
}
/**
* 下面主要是設定各種主要的常量
*/
//當前檔名稱,也就是“index.php”
//pathinfo()函式返回檔案路徑的資訊
define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
//system檔案的絕對路徑
define('BASEPATH', $system_path);
//專案檔案目錄的絕對路徑
//dirname()函式返回路徑中的目錄部分
define('FCPATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);
// system資料夾名稱“system”
//basename()函式返回路徑中的檔名部分
define('SYSDIR', basename(BASEPATH));
//此段程式碼用於判斷生成application應用檔案目錄
if (is_dir($application_folder)) {
if (($_temp = realpath($application_folder)) !== FALSE) {
$application_folder = $_temp;
} else {
$application_folder = strtr(
rtrim($application_folder, '/\\'),
'/\\',
DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR
);
}
} elseif (is_dir(BASEPATH . $application_folder . DIRECTORY_SEPARATOR)) {
$application_folder = BASEPATH . strtr(
trim($application_folder, '/\\'),
'/\\',
DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR
);
} else {
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: ' . SELF;
exit(3); // EXIT_CONFIG
}
//application應用目錄的絕對路徑
define('APPPATH', $application_folder . DIRECTORY_SEPARATOR);
//此段程式碼用於判斷生成view檢視檔案目錄
if (!isset($view_folder[0]) && is_dir(APPPATH . 'views' . DIRECTORY_SEPARATOR)) {
$view_folder = APPPATH . 'views';
} elseif (is_dir($view_folder)) {
if (($_temp = realpath($view_folder)) !== FALSE) {
$view_folder = $_temp;
} else {
$view_folder = strtr(
rtrim($view_folder, '/\\'),
'/\\',
DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR
);
}
} elseif (is_dir(APPPATH . $view_folder . DIRECTORY_SEPARATOR)) {
$view_folder = APPPATH . strtr(
trim($view_folder, '/\\'),
'/\\',
DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR
);
} else {
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: ' . SELF;
exit(3); // EXIT_CONFIG
}
//view檢視目錄的絕對路徑
define('VIEWPATH', $view_folder . DIRECTORY_SEPARATOR);
//最後就是載入CI框架的核心引導檔案了
require_once BASEPATH . 'core/CodeIgniter.php';
相關推薦
CI框架原始碼解析一之入口檔案index.php
Index.php作為CI框架的入口檔案,原始碼分析,自然而然由此開始。在原始碼分析的過程中,我們並不會逐行進行解釋,而只解釋核心的功能和實現,如果英文水平很好的話,讀過index.php檔案的英文註釋之後也就基本明白了inde.php都做了些什麼。本來
CI框架原始碼解析二之引導檔案CodeIgniter.php
上篇解析入口檔案寫到載入 core/CodeIgniter.php框架核心檔案,啟動框架。CodeIgniter.php檔案被稱為BOOTSTRAP,也就是引導檔案,這裡也就是CI框架的核心了。其實把CodeIgniter.php這個檔案的程式碼執行一
【CI框架原始碼解析之】分頁類檔案Pagination.php
<?php /** * ======================================= * Created by Pocket Knife Technology. * User: ZhiHua_W * Date: 2016/11/08 0
CI框架學習之--隱藏入口檔案-index.php
一般CI框架第一次使用時: 原地址為: http://127.0.0.1/CI/index.php/hello/index 隱藏入口檔案後只需要把地址寫成即可: http://127.0.0.1/CI/hello/index 1、需要開啟Apache的 rew
Elastic-Job原始碼解析(一)之與Spring完美整合
看過小編寫SpringFramework原始碼解析的同學應該對Spring支援自定義標籤還有點印象吧,沒有的話我們回顧下,然後看看Elastic-Job是如何巧妙的利用自定義標籤生成Job任務的吧。請注意這裡用了一個巧妙關鍵字。我們看它如何巧妙的吧。 Spring自定義
ci框架原始碼解析
1.index.php :入口檔案|-->define('ENVIRONMENT') |主要用於設定errors日誌輸出級別|-->$system_path |設定系統路徑|-->設定BASEPATH、FCPATH、SYSDIR、APPPATH等
CI框架隱藏入口檔案index.php
1、修改 apache 配置檔案conf/httpd.conf 或者 httpd-vhost.conf開啟重寫模組 LoadModule rewrite_module modules/mod_rewrite.soAllowOverride None 修改為 AllowOver
【opencart3原始碼分析】入口檔案index.php
<?php // 定義版本號 define('VERSION', '3.1.0.0_a1'); // 載入配置檔案 if (is_file('config.php')) { require_once('config.php'); } // 安裝 if (!def
ThinkPHP5.X PHP5.6.27-nts + Apache 通過 URL 重寫來隱藏入口檔案 index.php
我們先來看看官方手冊給出關於「URL 重寫」的參考: 可以通過 URL 重寫隱藏應用的入口檔案 index.php ,Apache 的配置參考: 1、http.conf 配置檔案載入 mod_rewrite.so 模組2、AllowOverride Node 中將 None 改為 All3、將下
Nginx配置 隱藏入口檔案index.php
Nginx配置檔案裡放入這段程式碼 server { location / { index index.php index.html index.htm l.php; autoindex on; if (!-e $request_
tp5隱藏入口檔案index.php,開發環境是Lamp
因為專案需要,我們要注意專案的安全性,同時tp5的url過長,所以我們要隱藏入口檔案index.php 舉例說明:www.xxx.com/tp5(專案名稱)/public/index.php/模組名/控制器名/方法名,這是一般的url訪問地址。 隱藏後:http://xxx.com/tp5/
TP5 隱藏入口檔案 index.php
找到public下的.htaccess <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d Re
TP5如何隱藏入口檔案index.php
一、Apache 在ThinkPHP5.0中,出於優化的URL訪問原則,還支援通過URL重寫隱藏入口檔案,下面以Apache為例說明隱藏應用入口檔案index.php的設定。 下面是Apache的配置過程,可以參考下: 1、httpd.conf配置檔案中載入了mod_rewr
ubuntu-apache下隱藏thinkphp入口檔案index.php
1、首先開啟apache的rewirte模組 修改/etc/apache2/apache2.conf檔案,把AllowOverride None改為AllowOverride All 2、在專案根目錄下新增.htaccess檔案,修改rewrite規則
ThinkPHP3.2URL重寫隱藏應用的入口檔案index.php
可以通過URL重寫隱藏應用的入口檔案index.php,下面是相關伺服器的配置參考: [ Apache ] httpd.conf配置檔案中載入了mod_rewrite.so模組AllowOverride None 將None改為 All把下面的內容儲存為.htacces
thinkPHP5隱藏入口檔案index.php後 讀取不到資源問題
這個問題弄了一下午 <link rel="stylesheet" href="../../../public/static/css/information_content.css" /> 在隱藏入口檔案後,這種方式會不成功 ,所以我們需要在配置檔案config.
ThinkPHP5 Nginx下的配置——支援pathinfo訪問和隱藏入口檔案index.php的rewrite規則
最近賦閒在家,看到TP都更新到5.0.6了,於是弄過來寫了個小專案熟悉了下,發現改動確實蠻大的。首先就是支援Composer了。(強烈建議使用Composer安裝,因為TP5的一些驗證碼之類的擴充套件包必須要用到Composer來安裝。)檔案命名規範的改變:控制器類檔名“Us
Apache伺服器下無法隱藏tp5的入口檔案index.php
找到Wampserver伺服器檔案httpd.conf 去掉‘#LoadModule rewrite_module modules/mod_rewrite.so’前面的‘#’ 。 查詢AllowOverride 。 <Directory "E
tp5隱藏入口檔案index.php
為什麼要隱藏入口檔案 使頁面url美觀,方便搜尋引擎收錄 具體實現 在index.php同級目錄下新建.htaccess(預設自帶) 新增如下內容 <IfModule
thinkphp5重寫隱藏應用的入口檔案index.php Apache IIS Nginx
可以通過URL重寫隱藏應用的入口檔案index.php,下面是相關伺服器的配置參考:[ Apache ]1. httpd.conf配置檔案中載入了mod_rewrite.so模組2. AllowOverride None 將None改為 All3.