程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> 使用CodeIgniter框架快速開發PHP應用(十二)

使用CodeIgniter框架快速開發PHP應用(十二)

編輯:PHP綜合
第 12 章 產品版本,升級和重大決定有意義的一天來臨了。 你開發的網站在你的本地開發環境中運行得足夠好了,是時候把它上傳到遠程的WEB服務器上成為一個正式運行的網站了。實現它應該是容易的。上傳所有的文件,包括系統文件夾的全部, 更新 config 設置, 復制完畢並連接到數據庫, 把它們傳送出去。 有時候,它真的是很容易。但是當它還沒有成功的時候,它處在你把重要的一切呈現在一個風險資本家或公眾視野面前的前夜。 因此, 為了防止出現意外, 這一章涉及: 。 該在你的 config 文件中設置什麼。 如果出現問題需要的一些診斷工具。 本地服務器與可能讓你出現差錯的服務器上的隱性差異。 幾點安全提示, 現在你將處身於大千世界下一步, 這一章包括升級, 以及留意那些CI在年內已經改變的一些方式。它穩定嗎? 如果你提交一個重要網站你應該如何決策?你該怎麼行動?一旦你的網站開始運作,而CI又推出新版本你又如何應對?最後,我們簡短地討論如何針對 CI 的核心作出你自己的修改。它都在那裡; 它是開放源代碼的,修改是可能的。 是否可行是另一件事情。連接: 檢查 Config 文件系統通常會在接口處出錯。 那是為什麼需要 config 文件的原因: 給你一個地方放那些接口。 如果你還沒有這麼做,你已經錯過 CI 的主要優點之一。主要的接口問題可能是: URL CI 通過查找文件工作。 你的用戶連接到 index.PHP, 然後開始運行整個程序。 至少,它應該運行。 確定你在你的 config 文件中已經正確地設置好WEB地址和其它服務器地址。 WEB地址是你的網站根目錄; 你可能需要咨詢你的ISP以便得到服務器地址,他們有他們自己的文件管理系統,一查便知。我曾經嘗試運行子域。 許多主機允許這麼做, 但是把域映射到你的目錄也許不是你希望的。數據庫定位並連接到你的數據庫經常是一個主要的話題。 查看你的 config 文件和你的 config/database文件。 你需要確定你有正確的網站和服務器地址和正確的數據庫名稱、地址, 用戶名和密碼。 小心前綴-有時這些自動地被添加的。 (你的網站叫 'fred' 。 你的數據庫, 叫做 'mydata' 和你的用戶名是 'mylogin'. 但是在服務器上他們叫做 'fred_mydata' , 'fred_mylogin', 等等。) 有時,它幫助在你的數據庫上創建一個新的用戶,即使你已經有了一個, 而且設定為以新的用戶名和密碼登錄。 我不知道為什麼會這樣,但是經常會這樣。在 config 文件中,你能設定 CI 接受不同的URL協議類型,決定服務器如何處理 URI 字符串。 默認值是: $config['uri_protocol']="auto"; 但是如果這不能正常工作,有其他四個選項可以嘗試。 如果正確的選項沒被設定,你可能發現你的網站只有部分工作正常(舉例來說) 表單不能調用目標頁。其他的 config 文件 config/routes文件設定程序執行的默認路徑,如果用戶沒有指定一個controller/method (也就是如果他們僅僅登錄到[url]www.mysite.com[/url]). 這通常應該在默認值中被設定: $route['default_controller']='index'; 如果你重新命名系統文件夾了,必須記得你還需要在網站的根目錄中改變 index.php 文件。 默認值設定為: $system_folder="system"; 找出PHP 4/5 和操作系統間的差異 CI 應該能夠兼容PHP 4.3及以後的任何版本. 然而,這不意味著你寫的任何的 PHP 編碼都能正常工作-因此如果你在使用 PHP 5, 並且正在向一個 PHP 4 服務器遷移, 由於版本不同有可能引發問題。 PHP(無論哪一個版本) 可能以不同的方式被建立。值得一做的是在你本地和遠程服務器上運行PHPinfo(), 找到它們之間的差異。大小寫敏感在微軟和 Linux 服務器之間是不同的。 因此如果你在一台Windows操作系統的PC上開發你的網站, 然後上傳到一台 Linux 服務器上,可能會收到出錯信息,報告它找不到一些你要裝載的模型或者類庫。如果你檢查過確定它們已經被上傳, 你也需要確定大小寫是正確的。 因為在 CI 的類定義和構造函數命名是要求以一個大寫字母開始的,而且以一個大寫字母開始一個文件名實現也很容易。 因此在一個控制器內,你裝載一個模型,冠以一個大寫字母開始,比如:($this->load->Mymodel), 但是Windows和 Linux 可能會通過$this->Model調用不同的視圖。作為不同服務器的一個極端例子, 我有一次開始寫一個控制器,並決定修改使它成為一個模型, 我把它保存在moel目錄中,卻沒有意識到我已經寫了頭幾行代碼如下: class Myclass extends Controller {
function Myclass() {
   parent::Controller(); 而不是把它改成: class Myclass extends Model {
function Myclass() {
       parent::Model(); 在本地的Xampplite上運行,這沒有出錯。 遷移到一個遠程的Linux服務器上, 立刻報錯。(而且你能想像調試它花費了多長時間…) 一些 PHP 函數在不同的操作系統上似乎也有不同的行為表現: 舉例來說, include_once()在Windows上是大小寫敏感的,但在其它系統上不是。雖然這與CI本身無關。同時,你的數據庫可能是一個不同的版本-許多ISP還在使用MySQL 3.23! 這似乎引起一些不兼容, 這意味著,通過SQL查詢上傳一個數據庫不是很容易實現。(舉例來說,它可能不接受數據表的提交。) Linux與Windows相比,有一個不同的文件權限管理系統。 確定你有對應的文件和目錄的權限。CI有幾個目錄文件的權限在它能夠正常運行前必須正確設置。診斷工具 index.php文件的第一行是: error_reporting(E_ALL); 會在你的屏幕上顯示所有的 PHP 錯誤。很顯然,這種錯誤報告很糟糕,可能給黑客太多的信息,所以在產品服務器上你應該改成: error_reporting;(0) 但是然後,任何的問題可能只是造成一個空白的屏幕,沒有可提供幫助的診斷信息。 你可能必須把錯誤報告再打開直到你已經使網站正常運行。 一個折中的做法是把它設定為一個中間狀態, 像是: error_reporting(E_ERROR); 這將會避免 'warning' 但是仍然會給你關於嚴重的問題信息。 'warning' 通常不會中止程序的執行, 但是可能轉向其它你沒有考慮到的問題。 CI Profiler 類-見第 8 章-也非常有用: 它顯示你正在做什麼查詢, POST數組的內容是什麼。當這些工具都不起作用時,需要使用其它的工具,下面列出一些我已經發現的其它工具: 1.   設定 CI 開啟日志文件。(通過修改 config 文件實現-見第 8 章-你需要設定:
$config['log_threshold']=4; 4顯示所有的信息, 包括notices和warnings; 有時這些會顯示潛在的問題。 然後查看日志文件 (保存在
/system/logs中.) 這將會告訴你哪一個 CI 部分已經被調用,因此,你能至少能看到程序中止的地方。 (把值設定回 0 會停止日志記錄。 記得這樣做, 調試完畢後請刪除日志文件: 它尺人地占用空間。) 2.   如果你能存取他們, 打印出 PHP 服務器和會話變量: print_r($_SERVER) 而且: print_r($_SESSION) 而且使用他們檢查 document_root 和 script_filename 值是不是你意料之中的。 如果不是,你可能需要調整config文件中的 base_url,server的值的設置,你還可以看一下是否有[HTTP_COOKIE]的設置,它會顯示是否你的session類能夠工作。 3.   用PHP的方法檢查 CI 把什麼裝載進它的“超級對象”: get_declared_classes();和: get_class_methods(); 4.   CI 自己的 show_error() 函數只是格式化生成的錯誤報告. 因此在你的代碼中加入下面的這一行,可以顯示出程序運到到哪一個命令分支: show_error('test of error function'); 會在你的屏幕上顯示: test of error function 我沒有發現這非常有用。 當我想要系統在我需要時給我一個完整的有幫助的錯誤報告, 在何時以及哪裡找到他們, 但是當我不想要他們出現的時候將不顯示他們。 我需要編寫我自己的函數,如下: function reportme($file, $line, $message) $obj =& get_instance();  
if (isset($_POST)) {
   $bert = print_r($_POST, TRUE);
} else {
   $bert = 'no post array'; if (isset($_SESSION)) {
   $sid = print_r($_SESSION, TRUE);
} else {
   $sid = 'no session array'; $time = Gmdate("H:i j-M-Y");
/*full report*/
$errorstring =   "$time - $file - $line: $message: POST array: $bert SESSION array: $sid\n";
/*short report*/
$shortstring =   "$file - $line: $message";
/*set $setting to 'test' if you want to write to the screen*/
$setting = 'test';
if ($setting == 'test') {
   echo $errorstring; /*set $action to 'log' if you want to log errors*/
$action = 'log';
if ($action == 'log') {
      $filename = $obj->config->item('errorfile');
      $fp = fopen("$filename", "a+")or dIE("cant open file");
      fwrite($fp, $errorstring);
      fclose($fp); }                                       
把它放在一個叫做errors的library文件中。我需要裝載這個library, 然後, 每當我對一段代碼沒有信心的時候,我include這個函數: $this->errors->reportme(__FILE__,__LINE__,'if the code has reached here it is becase...'); 然後我能設定 reportme() 函數在屏幕上顯示, 或保存在日志文件中。
這樣一個簡單的方法的有幾個優點:第一,我能容易地修改 reportme() 函數, 使它寫錯誤信息到一個文件, 或全然什麼也不做: 因此我能立刻使我所有的錯誤信息從屏幕消失, 或再回來, 只要修改一行代碼。第二,我生成一個包含特別的值的變量。 (一個ID,類型為整型,比方說。) 我生成一個盡可能完整和有幫助的信息。我試著找到一個整數, 連同我實際上得到的值。 函數也用PHP__FILE__ 和 __LINE__魔術常數完整地告訴我它發生的地方。因此, 如果當我把程序遷移到另外的一個服務器的時候,這塊特別的代碼在我寫了一段時間之後如果出現一個問題,我能立刻找到這段代碼,而且文字信息幫助我記起它為什麼是一個問題。 在你編程完成之後六個月,你不可能馬上弄明白, 尤其如果它發生在深夜,一位客戶在電話中要求你給他解釋什麼的! 更有幫助的錯誤本文,將使你容易地作出反應。第三,如果網站的完整性真的至關緊要,我可以設定函數用電郵把錯誤報告發送給我。在開發階段可能造成郵箱爆滿,但是一旦網站運行穩定,如果網站遇到問題,有一個即時的警告郵件發給我會是非常有用的。你將會在你的用戶知道之前就發現問題。應對新的CI版本帶來的變化在2006年2月28日到2006年10月30日之間, CI 從它的第一個Beta版升級到1.5版。 那是相當令人印象深刻的升級。在那期間,Rick Ellis做了一些非常激進的變化, 特別地在網站的結構上。 大致上,他已經小心使他們向後兼容-但是並沒有完全做到。 如果你剛使用 CI 並下載了最新版本,你能夠跳越這一個階段。 但是如果你們寫了使用較早的版本的程序。如果你正在使用 CI libraries或者是其他人寫的plug-ins。瑞克已經努力解決二個主要的問題: 該如何裝載模型、和如何調用他們起先,沒有模型,只是使用目錄來管理腳本和libraries。沒有准備要自動地初始化它們作為CI超級對象的一部份。結果是, 你有了一個 MVC 系統沒有 'M' 文件,似乎令人困惑。不僅這樣,還有二個libraries目錄: /system/application/libraries保存你為自己編寫的一些文件, 而 /system/librarIEs保存系統自己的操作文件。 這可能讓一些人感到混亂: 這二者之間存在很大的差異! 你應該增加到或改變前一個目錄中的文件,但你或許不需要改變後者,當然這很容易搞錯。 (而且如果你這樣做了,如果你對 CI 版本升級,你會面臨無法兼容的嚴重危險: 在下面可以看到。) 1.3 版帶來了一個新的 'Model'類。 用戶手冊定義模型為" 被設計用來與你的數據庫中的數據合作的PHP類 ". 當第一次使用時, CI 模型自動地與數據庫連接。 然而, 從1.3.3 版起, 你一定要在模型或控制器中顯式地連接數據庫。或者, 當你從控制器調用模型的時候,你可以以如下格式實現: $this->load->model('Mymodel', '', TRUE);
然後 'TRUE' 指定當與默認的數據庫連接時才裝載模型,正象你的 config 文件所定義的那樣。 (第二個三數, 在這裡的空格,是模型的一個可選擇的別名.) 如果你把'模型 '功能(在 MVC 意義上的) 放到一個 'library' 或者一個 (聲明:不贊成這麼做)腳本之內,CI 或許還可以工作。 較早的版本並沒有'model'目錄: 你不得不用其它方式存取CI資源-見到下一個區段! 如何初始化你自己的 'library' 類本來,你無法使你自己的類成為 CI 超級對象的一部份。這是一個問題,因為它意味著你的library代碼不能通過AR讀寫數據庫,或使用其他的 CI library,這樣的限制太大了。 1.2 版本增加了讀對類的 get_instance() 函數,允許你讀寫CI的超級對象(見第七章),你可以在你的 'library' 或者腳本中include它,然後使用 CI 資源。(除非你的新文件是一個函數腳本而不是一個 OO 類。 當然,腳本文件可能性用來編寫簡單的基本函數的選擇。) 1.4 版引進了一個新的系統。你必須為每個'library'類創建二個文件。第一個是類本身,比如Newclass.php ,保存在application/librarIEs目錄中,第二個,保存在application/init目錄中, 必須叫做 init_newclass.PHP 必須包含幾個標准代碼行,用來初始化,讓它成為CI超級對象的一部分,你仍然需要使用
get_instance()函數存取 CI 資源。在1.5版中, init 文件夾已經被不鼓勵使用了,初始化將自動地進行。 每個'library'只需要一個文件。舊的腳本目錄也已經不鼓勵使用了。'不鼓勵使用'通常意味著相關的實現方法能夠工作,但是開發者應該盡量不要這麼做,因為CI不能保證在未來的版本中還支持它。 如果你仍然有一個system/application/scripts目錄,不需要緊張-但是也不要再使用它。如果你正在計劃使用由 CI 社區編寫的librarIEs或者plug-ins,請首先檢查這些資源是否是為CI的最新版本開發的。 有相當多的是為1.4.1版本開發的,還有另一個'init'文件。 更新它們不困難,但是需要小心行事,確保它們正常工作。如果新的 CI 版本出來,我應該更新嗎? CI 的新版本時不時會推出。 它們帶有如何更新的指南。 通常,這包括拷貝一組新的文件到你的system目錄。 有時,你需要改變 config 文件, 或者你的 index.PHP 文件。不會有巨大的改變。因為目錄結構把你的應用保存在他們自己的位置,這樣可以在升級系統時不用涉及到你的應用系統。但是, 假如說你已經在 1.5 版中寫了一個你的優秀作品. 它被上傳到你的生產系統並且運行得很好。 如果Rick推出了CI 1.6 版.(或 2.8 或任何其它的…) 它有一些有趣的新功能、還有一些Bug修正。你是否需要對它進行升級? 我會說, '是的', 如果它是一個較小的升級, 比如在 1.5.2 和 1.5.3之間,你應該升級. 但是如果它是一個主要的版本變化, 而你的現有系統正在工作, 暫緩升級是個比較明智的選擇。 你可能從數字部分分辨出版本升級變化大小的程度, 但是也可以從新版本附帶的'變化清單' 列表得出結論。從去年開始 CI 劃分了三個目錄來列出三類不同的變化: Bug修正: 令人驚訝地少,CI有優良的代碼, 而且大部份的基礎類已經被數以千計的使用者精心地測試了上百遍。新的功能:. 這些經常地出現,但是如果你不使用這些新功能來開發你的應用,它們並不會對你有什麼幫助。敏感的變化: 就象我已經描述過的, CI 已經經過一個內存的升級的過程,而且它理所當然會繼續這麼做。你能從下面的列表看到,其中的一些向後兼容, 否則它們可能導致你重寫你的部分代碼。在 CI 的版本之間的一些變化: 版本 變化記錄 1.2 增加一個全局函數,名為get_instance(),允許你自定義的讀寫CI的主對象。 1.3 增加對模型的支持。 1.3 增加傳遞你自己的初始化參數到客戶自定義library能力,你可以這樣做:$this->load->library() 1.3 增加較好的類和函數的命名空間-避免沖突。所有的CodeIgniter類開始冠以CI_前綴和所有的控制器方法
   以_ci為前綴避免控制器命名沖突。 1.3.3 模型不自動連接數據庫。 1.4 增加了用你自定義的類替換核心系統類的能力。 1.4 升級模型的裝載函數,允許對同一模型多次裝載。 1.4.1 更新了plugins, helpers和language類,允許你的應用程序目錄包含你自己的plugins, helpers
   和language類。先前,在安裝時它們總是被當作全局的,如果你的應用目錄包含了它們中的任一個,你自定義的將會覆蓋系統中的這些資源。 1.4.1 聲明不鼓勵使用application/script目錄。 但它將會繼續為以前的使用者提供正常使用的可能性,但
   是建議你改為創建你自己的library或model。在CI支持用戶自定義library或者model之前,它本來就存在,但是它不再是必不可少的。 1.5 增加能力擴展library和核心類的功能,而且也能替換它們。 1.5 聲明不鼓勵使用init 文件夾。初始化現在自動進行。不要誤解我。 這些全部是有意義的改變,並且他們全部是對CI的升級。 如果你開始一個新的項目, 請使用最新的 CI 版本。 但是如果你使用1.3版開發應用,你會發現你的scripts目錄被聲明不鼓勵使用,而且你的模型也不會自動連接數據庫。我個人在使用CI的1.3版,而不嘗試升級它。 生命苦短。如何修改CI的基礎類一般使用者不可能需要改變基本的CI類。 它是相當好的框架,它做許多事物, 而且畢竟,使用框架會使做事更容易, 對不對? 然而, 如果你一定…. CI 是開源產品, 一旦下載你能看到所有的代碼。 這包括使 CI 工作 (在system/libraries保存) 的基本library以及你一旦編寫後保存system/application/libraries的你自己的libraries,因此你可能改變CI讓它以你喜歡的方式工作。修改系統libraries文件有二個問題,就是: 。 沒有保證,你的新密碼是否會與 CI 的其余部分兼容,或與更新的版本兼容。這可能導致不容易跟蹤敏感或者奇怪的錯誤。。 如果你稍後升級你的 CI 版本,系統目錄可能被改變。 你改變過去的librarIEs將被新的文件覆蓋或升級, 因此你需要維護你自己的修改並把它們遷移到升級的版本。不過,從 1.5 版起, 現在針對修改CI類庫有二個有意義的機制(除了針對'數據庫'和'控制器'類,觸及這兩個都很危險.) 第一,無論在哪個操作系統中,你能在你的 /system/application目錄中創建一個與系統基礎類同名的文件。 系統會優先使用這一個, 如果這個文件不存在或不可用則使用/system目錄中的那個。 這需要有精確的命名限制-詳見用戶手冊。 它也需要你復制所有在現有的類中存在的功能,讓它們和你自己修改過的那些一起工作。第二, 更方便地,你能從現有系統類派生出一個新類。 (因此可能派生一個子類是更好的做法),當然也有命名限制,詳見用戶手冊。繼承一個系統類意味著你的新子類潛在繼承了CI類中的所有資源,並增加幾個你自己的額外方法。這應該意味著,如果你升級你的 CI 版本,祖先類將會被替換,但是你的新子類(你應該把它放在system/application目錄)將安然無恙。然而, 兩者都不能保證你的代碼與CI的其它部分完全兼容。通過CI在線論壇,有擴充校驗類、單元測試和會話類的各種不同的建議。 單元測試, 舉例來說,只有二個函數和比較有限的字符數。 也許你想要一個函數,用紅色顯示錯誤信息,因此,當測驗結果被返回時,他們會顯得比較醒目 ? 如果你想要擴充一些其他的測試函數,通過一個子類把它加入會是比較簡單的,每次在控制器中編寫代碼調用單元測試。如果你想要這樣做,你可以這樣開始你的新子類: class MY_Unit_test extends CI_Unit-test {
function My_Unit_test() {
       parent::CI_Unit_test();
} function newfunction() {
       //new code here! } 在這裡注意三件事: 。 單元測試類的名稱是CI_Unit_test,即使類的代碼文件名是system/libraries.unit_test。。 如果你需要在你的子類中使用一個構造函數,確定你首先在裡面調用父類的構造函數。。 你的新子類名稱應該與 MY_ 前綴並保存為application/librarIEs/MY_unit_test.php。(不像系統中那些主要的類, 它們是以CI_為前綴,但是不是文件名, 在這裡MY_前綴是兩者的一部份.) 一旦你已經創建你的子類,你像這樣裝載它: $this->load->library('unit_test'); 換句話說, 完全地與你以前編寫的了類相同; 而且你以同樣的方式調用一個函數,但是這次你不但能調用原來的單元測試函數,還能調用你自己編寫的新函數: $this->unit_test->newfunction(); 當你以後升級你的 CI 的時候,在系統文件夾中的單元測試類庫將會覆蓋,但是那個在application目錄中的將不會,因此你的代碼將會仍然在那裡。 當然,你將會需要檢查被更新的系統類是否仍然與你自己的代碼兼容。摘要在這一章裡,當你嘗試遷移一個本地應用到遠程服務器的時候,有些東西可能會出錯。 這可能包括: 。 PHP 或 MySQL 的版本差異。 不同的操作系統特別地,我們分析了大小寫敏感問題, PHP 差異、和 MySQL 問題。 我們也談及幾個診斷工具。然後我們分析了CI 的升級。 這些都帶來了重要的進步, 但是我的忠告是, 如果你在現在的 CI 版本上工作得很好,如果CI有新的版本推出,仔細評估是否需要升級和如何升級。最後,我們分析修改 CI 基礎類的正反兩方面。 大多數的使用者將不需要這麼做。但是如果你確信需要這麼做,我強烈建議:實現它的最好方式是從一個現存的library類中派生一個子類。下一章關於實現CRUD—或讓它們進行組合查詢
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved