2017年3月7日14:23:21javascript
其實計劃好久可是移植沒時間去收集和處理弄成一個完整的文件php
SVN地址: https://git.oschina.net/zxadmin/live_zcss
目前基礎部分更新到79題,高級部分,我博客裏面有些,可是須要整理成文檔html
直接下載便可,不定時更新 最新版情趣svn地址下載,可是爲何須要登陸我就不知道了java
PHP面試大全 ZX1.1版 版本說明:基於部分網絡+我的+部分羣網友幫助集合而成。若是有錯誤的地方,請聯繫博主 修改完成版會從新發布 我的博客:http://www.cnblogs.com/zx-admin/ SVN地址:https://git.oschina.net/zxadmin/live_z 若是你能熟練背誦或者掌握如下資料,BAT問題不大 1.php基礎部分 1.1堆棧 2.php高級部分 2.1 單點登陸 2.2 ajax p3p 多站點登陸 2.3 php SPL 2.4 php MVC框架 2.5異常處理 2.6 權限系統rbac 2.7支持的協議和封裝協議 2.8 編譯php擴展 2.9 SSL 2.10 設計模式 3.php核心及內核,c部分 3.1設計模式 3.2反射機制 3.3 網站安全問題 4.linux服務搭建,nginx apche php-fpm +項目代碼管理 5.mysql基礎+複雜語句 6,mysql sql優化+死鎖問題+主從+中間件 7.數據庫分庫,分表問題 8.網站基礎架構,到大流量,大併發 9.非關係數據庫 redis mongodb 10.服務SOA化 11.本身寫簡單php框架 12.各類協議tcp http udp socket ftp 13.c作php擴展 14.支付寶,微信,網銀支付等 15.緩存系統 文件緩存 數據庫緩存 redis緩存 等 16.算法 php相關 排序,冒泡,二分查找,單鏈表,雙鏈表,環形鏈表等 17.大數據,雲平臺(粗略介紹) 一些無法歸類的問題 關於面試的一些廢話和寄語! 1.php基礎部分 1. 簡述兩種屏蔽php程序的notice警告的方法 初始化變量,文件開始設置錯誤級別或者修改php.ini 設置error_reporting set_error_handler 和 @抑制錯誤 1.在程序中添加:error_reporting (E_ALL & ~E_NOTICE); 2.或者修改php.ini中的:error_reporting = E_ALL 改成:error_reporting = E_ALL & ~E_NOTICE 3.error_reporting(0);或者修改php.inidisplay_errors=Off 2. include_once和require_once 分別返回什麼錯誤級別 include_once會系統警告並繼續執行,require_once會發出系統警告可是會引致致命錯誤令腳本終止運行 3. 例舉幾個經常使用的魔術方法, 並說明做用? 魔術函數 1。__construct() 實例化對象時被調用, 當__construct和以類名爲函數名的函數同時存在時,__construct將被調用,另外一個不被調用。 2。__destruct() 當刪除一個對象或對象操做終止時被調用。 3。__call() 對象調用某個方法, 若方法存在,則直接調用; 若不存在,則會去調用__call函數。 4。__get() 讀取一個對象的屬性時, 若屬性存在,則直接返回屬性值; 若不存在,則會調用__get函數。 5。__set() 設置一個對象的屬性時, 若屬性存在,則直接賦值; 若不存在,則會調用__set函數。 6。__toString() 打印一個對象的時被調用。如echo $obj;或print $obj; 7。__clone() 克隆對象時被調用。如:$t=new Test();$t1=clone $t; 8。__sleep() serialize以前被調用。若對象比較大,想刪減一點東東再序列化,可考慮一下此函數。 9。__wakeup() unserialize時被調用,作些對象的初始化工做。 10。__isset() 檢測一個對象的屬性是否存在時被調用。如:isset($c->name)。 11。__unset() unset一個對象的屬性時被調用。如:unset($c->name)。 12。__set_state() 調用var_export時,被調用。用__set_state的返回值作爲var_export的返回值。 13。__autoload() 實例化一個對象時,若是對應的類不存在,則該方法被調用。 魔術常量 1。__LINE__ 返回文件中的當前行號。 2。__FILE__ 返回文件的完整路徑和文件名。若是用在包含文件中,則返回包含文件名。自 PHP 4.0.2 起,__FILE__ 老是包含一個絕對路徑,而在此以前的版本有時會包含一個相對路徑。 3。__FUNCTION__ 返回函數名稱(PHP 4.3.0 新加)。自 PHP 5 起本常量返回該函數被定義時的名字(區分大小寫)。在 PHP 4 中該值老是小寫字母的。 4。__CLASS__ 返回類的名稱(PHP 4.3.0 新加)。自 PHP 5 起本常量返回該類被定義時的名字(區分大小寫)。在 PHP 4 中該值老是小寫字母的。 5。__METHOD__ 返回類的方法名(PHP 5.0.0 新加)。返回該方法被定義時的名字(區分大小寫)。 4. 類靜態方法和實例化類方法比較及優缺點 5. 例如google,baidu等大型網站,當使用不一樣客戶端(如手機和PC機)訪問一樣的URL時,呈現的頁面卻不相同,這是何原理? 簡單的能夠用user_agent判斷,可是及其初步 能夠的話經過服務器或者手機終端特徵或者wap網關accept信息等 6. 請說明PHP中傳值與傳引用的區別。何時傳值何時傳引用? 傳值只是把某一個變量的值傳給了另外一個變量,而引用則說明二者指向了同一個地方。 7. echo(),print(),print_r()的區別 echo是語言結構,無返回值;print功能和echo基本相同,不一樣的是print是函數,有返回值;print_r是遞歸打印,用於輸出數組對象 echo與print: 它們都不是真正的函數,是一種語法結構(也有說print是函數,echo不是)。 echo和print 後面均可不用加(),如: echo ‘ok’; print ‘ok’; 運行速度echo稍快一些,由於echo並不返回值,print返回一個值int(1)。 結論: 一、通常用echo,除非三元運算時。$a=5; ($a==5) ? print ’5′: print 0; 二、echo 後通常不要跟()。 print_r是遞歸打印,主要用於輸出數組對象。 print只能有一個參數,因此不能不能用」,」,而echo能夠。 Sprintf 以必定的格式 格式化一個字符串 8. 如何實現字符串翻轉? 用strrev函數唄,不許用PHP內置的就本身寫: [php] view plain copy 在CODE上查看代碼片派生到個人代碼片 strrev($str) { $len=strlen($str); $newstr = ''; for($i=$len;$i>=0;$i--) { $newstr .= $str{$i}; } return $newstr; } 9. 實現中文字串截取無亂碼的方法。 mb_substr() 10. 求兩個日期的差數,求前一天 (strtotime(‘2007-3-6’)-strtotime(‘2007-2-5’))/3600*24 echo date('Y-m-d H:i:s', strtotime('-1 day')); 11. 如何用php的環境變量獲得一個網頁地址的內容?ip地址又要怎樣獲得? $_SERVSR[‘REQUEST_URI’] , $_SERVER[‘REMOTE_ADDR’] 12. 使用五種以上方式獲取一個文件的擴展名 get_ext1($file_name) { return strrchr($file_name, '.');} 2) get_ext2($file_name) { return substr($file_name, strrpos($file_name, '.'));} 3) get_ext3($file_name) { return array_pop(explode('.', $file_name));} 4) get_ext4($file_name) { $p = pathinfo($file_name); return $p['extension'];} 5) get_ext5($file_name) { return strrev(substr(strrev($file_name), 0, strpos(strrev($file_name), '.')));} 13. 寫幾個經常使用的PHP的擴展的名稱和做用 mysql、gd二、pdo、curl、mbstring、soap等,在php.ini中能夠找到。儘可能多瞭解一些擴展,瞭解他們的功能(能作什麼)。 php經過使用php_ming 庫(Ming庫)快速生成 Flash 動畫 14. MVC模式的瞭解 MVC是Model(模型)、View(視覺)、Controll(控制器)的縮寫。 MVC(Model-View-Controller)介紹 模型(Model): 應用程序的模型部分關心的是欲顯示的數據的細節。模型一般關注的是應用程序的業務邏輯部分,關注的是如何使用數據庫來讀取和保存數據。 視圖(View): 視圖關心的是用戶顯示的部分,它一般是HTML。 控制器(Controller):控制器將特定的模型和視圖結合起來,保證將正確的數據顯示到頁面上。 還有部分未寫。。。。。。。。。。。待補充 15. 可以使HTML和PHP分離開使用的模板 經常使用的模板引擎:smarty,還有PHPLib,FastTemplate,Savant等。 可是php自身也是模版引擎 16. 簡述如何獲得當前執行腳本路徑,包括所獲得參數。 訪問http://temp.com/phpinfo.php?id=1 echo $_SERVER['SCRIPT_URL']; //獲得/phpinfo.php echo $_SERVER["SCRIPT_URI"]; //獲得http://temp.com/phpinfo.php echo $_SERVER["SCRIPT_FILENAME"]; //獲得F:/www/Temp/phpinfo.php echo $_SERVER["REQUEST_URI"]; //獲得/phpinfo.php?id=1 echo $_SERVER["SCRIPT_NAME"]; //獲得/phpinfo.php 17. 在PHP中,heredoc是一種特殊的字符串,它的結束標誌必須__。 結束標識符所在的行不能包含任何其它字符除」;」 Heredoc echo <<<END This text is written to the screen as output and this $variable is parsed too. If you wanted you can have <span> HTML tags in here as well.</span> The END; remarks must be on a line of its own, and can’t contain any extra white space. END; 18. 寫出session的運行機制。 session建立時,是否會在服務端記錄一個cookie?cookie裏面的內容是什麼? session機制是一種服務器端的機制,服務器使用一種相似於散列表的結構(也可能就是使用散列表)來保存信息。 當程序須要爲某個客戶端的請求建立一個session的時候,服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識-稱爲sessionid,若是已包含一個sessionid則說明之前已經爲此客戶端建立過session,服務器就按照sessionid把這個session檢索出來使用(若是檢索不到,可能會新建一個),若是客戶端請求不包含sessionid,則爲此客戶端建立一個session而且生成一個與此session相關聯的sessionid,sessionid的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個sessionid將被在本次響應中返回給客戶端保存。 保存這個sessionid的方式能夠採用cookie,這樣在交互過程當中瀏覽器能夠自動的按照規則把這個標識發給服務器。通常這個cookie的名字都是相似於SEEESIONID。 因爲cookie能夠被人爲的禁止,必須有其餘機制以便在cookie被禁止時仍然可以把sessionid傳遞迴服務器。常常被使用的一種技術叫作URL重寫,就是把sessionid直接附加在URL路徑的後面,附加方式也有兩種,一種是做爲URL路徑的附加信息,表現形式爲http://…../xxx;SEEESIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 另外一種是做爲查詢字符串附加在URL後面,表現形式爲http://…../xxx?SEEESIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 爲了在整個交互過程當中始終保持狀態,就必須在每一個客戶端可能請求的路徑後面都包含這個SEEESIONID。 19. Cookie的原理及使用? Cookie是網站保存在瀏覽器客戶端的信息,也就是說保存在訪客的機器裏的變量,通常隨着HTTP頭髮送到服務器端。在Cookie生效以後及失效以前,客戶每次發出頁面請求的時候(包括PHP頁面和靜態html頁面),都會把Cookie一塊發送到服務器,只要咱們針對它進行相應的處理,就能夠實現變量」追隨」。 cookie能夠跨越子域名。 好比咱們在xiaofeicn.com下面註冊個個cookie,那麼能夠在bbs.xiaofeicn.com上讀取到該cookie。 session不能夠跨越子域名: 好比咱們在xiaofeicn.com下面註冊個個session,那麼不能夠在bbs.xiaofeicn.com,www.xiaofeicn.com上讀取到該session。 20. 請將數組的值用’,’號分隔併合併成字符串輸出。如何將一個以’,’隔開的字符串分割成數組? 參考 implode.php 把數組變成字符串 要掌握implode和explode的用法。 21. 不用新變量直接交換現有兩個變理的值 List($a,$b) 22. 表單中 get與post提交方法的區別? a、Get 方法經過 URL 請求來傳遞用戶的數據,將表單內各字段名稱與其內容,以成對的字符串鏈接,置於 action 屬性所指程序的 url 後,如http://www.domain.com/test.asp?name=51js&password=51js,數據都會直接顯示在 url 上,就像用戶點擊一個連接同樣;Post 方法經過 HTTP post 機制,將表單內各字段名稱與其內容放置在 HTML 表頭(header)內一塊兒傳送給服務器端交由 action 屬性能所指的程序處理,該程序會經過標準輸入(stdin)方式,將表單的數據讀出並加以處理 b、 Get 方式須要使用 $_GET 來取得變量的值;而 Post 方式經過 $_POST 來訪問提交的內容 c、Get 方式傳輸的數據量很是小,通常限制在 2 KB 左右,可是執行效率卻比 Post 方法好;而 Post 方式傳遞的數據量相對較大,它是等待服務器來讀取數據,不過也有字節限制,這是爲了不對服務器用大量數據進行惡意攻擊。可在php.in中 對 post_max_size 進行設置。 建議:除非你確定你提交的數據能夠一次性提交,不然請儘可能用 Post 方法 d、Get 方式提交數據,會帶來安全問題,好比一個登錄頁面,經過 Get 方式提交數據時,用戶名和密碼將出如今 URL 上,若是頁面能夠被緩存或者其餘人能夠訪問客戶這臺機器,就能夠從歷史記錄得到該用戶的賬號和密碼,因此表單提交建議使用 Post 方法;Post 方法提交的表單頁面常見的問題是,該頁面若是刷新的時候,會彈出一個對話框。 建議:出於安全性考慮,建議最好使用 Post 提交數據***********************************在B/S應用程序中,前臺與後臺的數據交互,都是經過HTML中Form表單完成的。Form提供了兩種數據傳輸的方式——get和post。雖然它們都是數據的提交方式,可是在實際傳輸時確有很大的不一樣,而且可能會對數據產生嚴重的影響。雖然爲了方便的獲得變量值,Web容器已經屏蔽了兩者的一些差別,可是瞭解兩者的差別在之後的編程也會頗有幫助的。 Form中的get和post方法,在數據傳輸過程當中分別對應了HTTP協議中的GET和POST方法。兩者主要區別以下: a、Get是用來從服務器上得到數據,而Post是用來向服務器上傳遞數據。 b、Get將表單中數據的按照variable=value的形式,添加到action所指向的URL後面,而且二者使用」?」鏈接,而各個變量之間使用」&」鏈接;Post是將表單中的數據放在form的數據體中,按照變量和值相對應的方式,傳遞到action所指向URL。 c、Get是不安全的,由於在傳輸過程,數據被放在請求的URL中,而現在現有的不少服務器、代理服務器或者用戶代理都會將請求URL記錄到日誌文件中,而後放在某個地方,這樣就可能會有一些隱私的信息被第三方看到。另外,用戶也能夠在瀏覽器上直接看到提交的數據,一些系統內部消息將會一同顯示在用戶面前。Post的全部操做對用戶來講都是不可見的。 d、Get傳輸的數據量小,這主要是由於受URL長度限制;而Post能夠傳輸大量的數據,因此在上傳文件只能使用Post(固然還有一個緣由,將在後面的提到)。 e、Get限制Form表單的數據集的值必須爲ASCII字符;而Post支持整個ISO10646字符集。 f、Get是Form的默認方法。 *.Post傳輸數據時,不須要在URL中顯示出來,而Get方法要在URL中顯示。 *.Post傳輸的數據量大,能夠達到2M,而Get方法因爲受到URL長度的限制,只能傳遞大約1024字節. *.Post顧名思義,就是爲了將數據傳送到服務器段,Get就是爲了從服務器段取得數據.而Get之因此也能傳送數據,只是用來設計告訴服務器,你到底須要什麼樣的數據.Post的信息做爲http請求的內容,而Get是在Http頭部傳輸的。 23. session與cookie的區別? session是服務器端緩存,cookie是客戶端緩存。 cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在服務器端保持狀態的方案。 24. Cookie、session的聯繫和區別,多臺web服務器如何共享session Session採用鍵值對 , 也就是說ID存放客戶端 , 而值放在服務器端 , 是經過用戶的ID去找服務器上對應的值 , 這種方式值放置在服務器端 ,有個時間限制 ,時間到則服務器自動釋放. Cookies則有兩種方法 , 一種方法是把值保存在瀏覽器的變量中 , 當瀏覽器關閉時結束 , 另外一種方法是保存在硬盤中 , 只要時間不過時 , 下次還可以使用. Session 是由應用服務器維持的一個服務器端的存儲空間,用戶在鏈接服務器時,會由服務器生成一個惟一的SessionID,用該SessionID 爲標識符來存取服務器端的Session存儲空間。而SessionID這一數據則是保存到客戶端,用Cookie保存的,用戶提交頁面時,會將這一 SessionID提交到服務器端,來存取Session數據。這一過程,是不用開發人員干預的。因此一旦客戶端禁用Cookie,那麼Session也 會失效。 服務器也能夠經過URL重寫的方式來傳遞SessionID的值,所以不是徹底依賴Cookie。若是客戶端Cookie禁用,則服務器能夠自動經過重寫URL的方式來保存Session的值,而且這個過程對程序員透明。 能夠試一下,即便不寫Cookie,在使用request.getCookies();取出的Cookie數組的長度也是1,而這個Cookie的名字就是JSESSIONID,還有一個很長的二進制的字符串,是SessionID的值。 25. 請說明在php.ini中safe_mode開啓以後對於PHP系統函數的影響? safe_mode是惟一PHP_INI_SYSTEM屬性,必須經過php.ini或httpd.conf來設置。要啓用safe_mode,只需修改php.ini: safe_mode = On 或者修改httpd.conf,定義目錄: Options FollowSymLinks php_admin_value safe_mode 1 重啓apache後safe_mode就生效了。啓動safe_mode,會對許多PHP函數進行限制,特別是和系統相關的文件打開、命令執行等函數。 默認狀況下,全部操做文件的函數將只能操做與腳本UID相同的文件。 注意:若是在linux中啓用了safe_mode,那麼若是要在一個目錄中建立一個目錄,好比要在/upload中建立一個20081202,那麼/upload目錄全部者必須是apache的全部者。 26. isset()和empty()的區別 二者都是測試變量用的。可是isset()是測試變量是否被賦值,而empty()是測試一個已經被賦值的變量是否爲空。若是一個變量沒被賦值就引用在php裏是被容許的,但會有notice提示。若是一個變量被賦空值,$foo=」」或者$foo=0或者$foo=false,那麼empty($foo)返回真,isset($foo)也返回真,就是說賦空值不會註銷一個變量。要註銷一個變量,能夠用 unset($foo)或者$foo=NULL。 27. 使用哪些工具進行版本控制? cvs,svn,git; 28.請寫一個函數驗證電子郵件的格式是否正確 (2分) 答:function checkEmail($email) { $pregEmail="/([a-z0-9]*[-_/.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[/.][a-z]{2,3}([/.][a-z]{2})?/i"; return preg_match($pregEmail,$email); } 29. 請寫出PHP5權限控制修飾符 public(公共) private(私用) protected(繼承) final static const 30. 解析一個URL $url ="http://ci.localhost/index.php/home/adminlogin"; //$url = "http://shopnc.localhost/shop/index.php?act=goods&op=index&goods_id=25220"; $s = parse_url($url); var_dump($s); $t = parse_str($s['query'],$arr); var_dump($arr); var_dump(pathinfo($url)); //不行 var_dump(basename($url)); var_dump(dirname($url)); //這種模式類型都不行,因此換個思路 $mm = $s['path']; $g = explode("/",$mm); var_dump($g); //unset($g['0']); //var_dump($g); list($b,$n,$acttion,$function) = $g; 31.PHP配置指令做用域說明 PHP總共有4個配置指令做用域:(PHP中的每一個指令都有本身的做用域,指令只能在其做用域中修改,不是任何地方都能修改配置指令的) PHP_INI_PERDIR:指令能夠在php.ini、httpd.conf或.htaccess文件中修改 PHP_INI_SYSTEM:指令能夠在php.ini 和 httpd.conf 文件中修改 PHP_INI_USER:指令能夠在用戶腳本中修改 PHP_INI_ALL:指令能夠在任何地方修改 32.可變變量 有時候使用可變變量名是很方便的。就是說,一個變量的變量名能夠動態的設置和使用。一個普通的變量經過聲明來設置 有些時候須要可擴展的多種支付類型能夠寫成 $identify = $this->identify; 入口標識,必須和類名一致 $pay = New $identify(); $pay->pay(); 可變變量 也能夠實現相似的可擴展的方法 $a = "whfbbs"; //whfbbs就是可變變量的名字 $$a = 'b'; echo $whfbbs; 33.$this 和 –>& 引用 的意思和區別 $this便是實例化對象自己, –>對象訪問符 和c/c++相似,可是注意不是徹底同樣的 &在c裏面叫取地址符,可是php裏面徹底不是,官方原文是: 在 PHP 中引用意味着用不一樣的名字訪問同一個變量內容。這並不像 C 的指針:例如你不能對他們作指針運算,他們並非實際的內存地址…… 查看引用不是什麼瞭解更多信息。 替代的是,引用是符號表別名。注意在PHP 中,變量名和變量內容是不同的, 所以一樣的內容能夠有不一樣的名字。最接近的比喻是 Unix 的文件名和文件自己——變量名是目錄條目,而變量內容則是文件自己。引用能夠被看做是 Unix 文件系統中的硬連接。 僅做爲別名理解,足以 還有好比 foreach ($array as $key =>&$value) { } 並不會加速循環處理速度,僅是提供 $value能夠修改修改其參數的值 function functionName(&$param) { } 僅傳遞進去,返回該值 引用傳遞 function functionName($param,&$error) { } 引用返回 不清楚的能夠看下官方文檔說明 (廢話一句,我也認爲php和c/c++的基本用法和數據結構相似,實際上是大錯特錯,僅僅是相似,可是基本實現了殼,好比php7的嚴格數據返回格式) 34.Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0 錯誤 在不少接口對接中遇到的這個問題 ,主要緣由就是 php7.0以前 always_populate_raw_post_data默認是0,須要設置成-1,必須在php.ini裏面設置 7.0以後就沒這問題了,屬於遺留bug Warning: Cannot modify header information - headers already sent in Unknown on line 0,也有多是由這個引發的 35. = == === 的區別 = 賦值 == 比較類型必須一致,先轉換類型在比較 ===同時比較類型和數值,都一致纔是true 須要細細理解,由於php是弱語言類型,容易出現一些bug判斷 36.遍歷全部目錄 function zx($dir){ if(is_dir($dir)){ $filesnames = scandir($dir); foreach ($filesnames as $name) { if($name!='.'&&$name!='..'){ echo $name; } if($name!='.'&&$name!='..'){ if(is_dir($name)){ zx($name); }else{ echo '這是文件'; } } echo '<br>'; } } } 37.instanceof的做用, 常常在什麼設計模式中使用 單例模式,可是其餘的模式也會用到 38.計算幾天前,幾個月前,固定日子多少時間前 echo strtotime("now") . "<br>"; echo strtotime("15 October 1980") . "<br>"; echo strtotime("+5 hours") . "<br>"; echo strtotime("+1 week") . "<br>"; echo strtotime("+1 week 3 days 7 hours 5 seconds") . "<br>"; echo strtotime("next Monday") . "<br>"; echo strtotime("last Sunday"); 輸出的是時間戳須要date轉換 $apply['apply_date'] 某月某日 時間戳 $contract['application_days'] 多天前 $days = "+".$contract['application_days']." days"; $first_pay_day =date("Y-m-d",strtotime($days,strtotime(date("Y-m-d", $apply['apply_date'])))); 39.解決urlencode 沒有吧=轉換成%20 相似的問題 Rawurldecode這個函數 rawurlencode 最好使用這對函數 按照 RFC 1738 對 URL 進行編碼 返回字符串,此字符串中除了 -_. 以外的全部非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數。這是在 RFC 1738 中描述的編碼,是爲了保護原義字符以避免其被解釋爲特殊的 URL 定界符,同時保護 URL 格式以避免其被傳輸媒體(像一些郵件系統)使用字符轉換時弄亂。 與urlencode()的區別: urlencode: 返回字符串,此字符串中除了 -_. 以外的全部非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數,空格則編碼爲加號(+)。此編碼與 WWW 表單 POST 數據的編碼方式是同樣的,同時與 application/x-www-form-urlencoded 的媒體類型編碼方式同樣。因爲歷史緣由,此編碼在將空格編碼爲加號(+)方面與 RFC1738 編碼(參見 rawurlencode())不一樣。 40.如何在php中設置header頭信息 建議參考:http://www.cnblogs.com/zx-admin/p/6172029.html 內容不少如下是幾個簡單demo //定義編碼 header( 'Content-Type:text/html;charset=utf-8 '); //Atom header('Content-type: application/atom+xml'); //CSS header('Content-type: text/css'); //Javascript header('Content-type: text/javascript'); //JPEG Image header('Content-type: image/jpeg'); //JSON header('Content-type: application/json'); //PDF header('Content-type: application/pdf'); //RSS header('Content-Type: application/rss+xml; charset=ISO-8859-1'); //Text (Plain) header('Content-type: text/plain'); //XML header('Content-type: text/xml'); //200 OK header('HTTP/1.1 200 OK'); //設置一個404頭: header('HTTP/1.1 404 Not Found'); //設置地址被永久的重定向 header('HTTP/1.1 301 Moved Permanently'); //轉到一個新地址 header('Location: http://www.example.org/'); //文件延遲轉向: header('Refresh: 10; url=http://www.example.org/'); print 'You will be redirected in 10 seconds'; //固然,也能夠使用html語法實現 //<meta http-equiv="refresh" content="10;http://www.example.org/ /> //override X-Powered-By: PHP: header('X-Powered-By: PHP/4.4.0'); header('X-Powered-By: Brain/0.6b'); //文檔語言 header('Content-language: en'); //告訴瀏覽器最後一次修改時間 $time = time() - 60; // or filemtime($fn), etc header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT'); //告訴瀏覽器文檔內容沒有發生改變 header('HTTP/1.1 304 Not Modified'); //設置內容長度 header('Content-Length: 1234'); //設置爲一個下載類型 header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="example.zip"'); header('Content-Transfer-Encoding: binary'); //load the file to send: readfile('example.zip'); //對當前文檔禁用緩存 header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate'); header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past header('Pragma: no-cache'); //設置內容類型: header('Content-Type: text/html; charset=iso-8859-1'); header('Content-Type: text/html; charset=utf-8'); header('Content-Type: text/plain'); //純文本格式 header('Content-Type: image/jpeg'); //JPG*** header('Content-Type: application/zip'); // ZIP文件 header('Content-Type: application/pdf'); // PDF文件 header('Content-Type: audio/mpeg'); // 音頻文件 header('Content-Type: application/x-shockw**e-flash'); //Flash動畫 //顯示登錄對話框 header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Basic realm="Top Secret"'); print 'Text that will be displayed if the user hits cancel or '; print 'enters wrong login data'; 41.取得客戶端IP /** * 獲取客戶端IP地址 * @param integer $type 返回類型 0 返回IP地址 1 返回IPV4地址數字 * @return mixed */ function get_client_ip($type = 0) { $type = $type ? 1 : 0; static $ip = NULL; if ($ip !== NULL) return $ip[$type]; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $pos = array_search('unknown',$arr); if(false !== $pos) unset($arr[$pos]); $ip = trim($arr[0]); }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; }elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } // IP地址合法驗證 $long = sprintf("%u",ip2long($ip)); $ip = $long ? array($ip, $long) : array('0.0.0.0', 0); return $ip[$type]; } 42.varchar和char有什麼區別 char 長度是固定的,無論你存儲的數據是多少他都會都固定的長度。 而varchar則處可變長度但他要在總長度上加1字符,這個用來存儲位置。 char 固定長度,因此在處理速度上要比varchar快速不少,可是浪費存儲空間, 因此對存儲不大,但在速度上有要求的能夠使用char類型,反之能夠用varchar類型來實例 char (13)長度固定, 如'www.jb51.net' 存儲須要空間 12個字符 varchar(13) 可變長 如'www.jb51.net' 須要存儲空間 13字符 43.寫代碼來解決多進程/線程同時讀寫一個文件的問題 PHP是不支持多線程的,能夠使用php的flock加鎖函數實現。 $fp = fopen("/tmp/lock.txt", "w+"); if (flock($fp, LOCK_EX)) { // 進行排它型鎖定 fwrite($fp, "Write something here\n"); flock($fp, LOCK_UN); // 釋放鎖定 } else { echo "Couldn't lock the file !"; } fclose($fp); 44.Mysql 的存儲引擎,myisam和innodb的區別 a. MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持. b. MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快. c. InnoDB不支持FULLTEXT類型的索引. d. InnoDB 中不保存表的具體行數,也就是說, 執行select count(*) from table時,InnoDB要掃描一遍整個表來計算有多少行, 可是MyISAM只要簡單的讀出保存好的行數便可. e. 對於AUTO_INCREMENT類型的字段,InnoDB中必須包含只有該字段的索引,可是在MyISAM表中,能夠和其餘字段一塊兒創建聯合索引。 f. DELETE FROM table時,InnoDB不會從新創建表,而是一行一行的刪除。 g. LOAD TABLE FROM MASTER操做對InnoDB是不起做用的,解決方法是首先把InnoDB表改爲MyISAM表,導入數據後再改爲InnoDB表, 可是對於使用的額外的InnoDB特性(例如外鍵)的表不適用. h. MyISAM支持表鎖,InnoDB支持行鎖。 45.對於大流量的網站,您採用什麼樣的方法來解決各頁面訪問量統計問題 a. 確認服務器是否能支撐當前訪問量。 b. 優化數據庫訪問。 c. 禁止外部訪問連接(盜鏈), 好比圖片盜鏈。 d. 控制文件下載。 e. 使用不一樣主機分流。 f. 使用瀏覽統計軟件,瞭解訪問量,有針對性的進行優化。 46.判斷一個數據是不是一個標準的json數據 function is_json($string) { json_decode($string); return (json_last_error() == JSON_ERROR_NONE); } define ('JSON_ERROR_NONE', 0); JSON_ERROR_NONE 沒有錯誤發生 JSON_ERROR_DEPTH 到達了最大堆棧深度 JSON_ERROR_STATE_MISMATCH 無效或異常的 JSON JSON_ERROR_CTRL_CHAR 控制字符錯誤,多是編碼不對 JSON_ERROR_SYNTAX 語法錯誤 JSON_ERROR_UTF8 異常的 UTF-8 字符,也許是由於不正確的編碼。JSON_ERROR_RECURSION One or more recursive references in the value to be JSON_ERROR_INF_OR_NAN One or more NAN or INF values in the value to be JSON_ERROR_UNSUPPORTED_TYPE 指定的類型,值沒法編碼。JSON_ERROR_INVALID_PROPERTY_NAME 指定的屬性名沒法編碼。 JSON_ERROR_UTF16 畸形的 UTF-16 字符,可能由於字符編碼不正確。 47.寫一個簡單的行爲控制函數 //簡單行爲管理,若是請求此方法次數多於5次,就顯示驗證碼 吧當前方法的name傳進來, //有效時間是5分鐘,$return=1是增長,$return=2就是隻是返回$_COOKIE[$name]的值 function behavior_function($function = __FUNCTION__, $class = __CLASS__, $return = 1) { $name = 'behavior_' . $class . '_' . $function; if ($return == 1) { setcookie($name, $_COOKIE[$name] + 1, time() + 3000, "/"); } elseif ($return == 2) { return $_COOKIE[$name] > 5 ? true : false; } } 48.三元運算 ($a==5) ? print ‘5’:print 0; 49. PHP中的替代語法(冒號、endif、endwhile、endfor) PHP 提供了一些流程控制的替代語法,包括 if,while,for,foreach 和 switch。替代語法的基本形式是把左花括號({)換成冒號(:),把右花括號(})分別換成 endif;,endwhile;,endfor;,endforeach; 以及 endswitch;。 Demo : if ($a == 5): echo "a equals 5"; elseif ($a == 6): echo "!!!"; else: echo "a is neither 5 nor 6"; endif; 注意:不支持在同一個控制塊內混合使用兩種語法 50.轉錢的大寫 //數字轉大寫 此函數只有到分 function cny($ns) { static $cnums = array("零", "壹", "貳", "叄", "肆", "伍", "陸", "柒", "捌", "玖"), $cnyunits = array("圓", "角", "分"), $grees = array("拾", "佰", "仟", "萬", "拾", "佰", "仟", "億"); list($ns1, $ns2) = explode(".", $ns, 2); $ns2 = array_filter(array($ns2[1], $ns2[0])); $ret = array_merge($ns2, array(implode("", _cny_map_unit(str_split($ns1), $grees)), "")); $ret = implode("", array_reverse(_cny_map_unit($ret, $cnyunits))); return str_replace(array_keys($cnums), $cnums, $ret); } function _cny_map_unit($list, $units) { $ul = count($units); $xs = array(); foreach (array_reverse($list) as $x) { $l = count($xs); if ($x != "0" || !($l % 4)) $n = ($x == '0' ? '' : $x) . ($units[($l - 1) % $ul]); else $n = is_numeric($xs[0][0]) ? $x : ''; array_unshift($xs, $n); } return $xs; } 51.PHP支持的數據類型 四種標量類型: boolean (布爾型) integer (整型) float (浮點型, 也稱做 double) string (字符串) 兩種複合類型: array (數組) object (對象) 最後是兩種特殊類型: resource (資源) NULL (NULL) 爲了確保代碼的易讀性,本手冊還介紹了一些僞類型: mixed number callback 52.請說明在php.ini中safe_mode開啓以後對於PHP系統函數的影響? safe_mode是惟一PHP_INI_SYSTEM屬性,必須經過php.ini或httpd.conf來設置。要啓用safe_mode,只需修改php.ini: safe_mode = On 或者修改httpd.conf,定義目錄: Options FollowSymLinks php_admin_value safe_mode 1 重啓apache後safe_mode就生效了。啓動safe_mode,會對許多PHP函數進行限制,特別是和系統相關的文件打開、命令執行等函數。 默認狀況下,全部操做文件的函數將只能操做與腳本UID相同的文件。 注意:若是在linux中啓用了safe_mode,那麼若是要在一個目錄中建立一個目錄,好比要在/upload中建立一個20081202,那麼/upload目錄全部者必須是apache的全部者 53.zend optimizer是什麼 用優化代碼的方法來提升php應用程序的執行速度,且能夠解密Zend Guard加密事後代碼,使之可以正常運行 54.設計一個緩存系統。寫出思路。畫出圖。考慮命中,生存期等多種要素 55.數據庫中的事務是什麼? 事務(transaction)是做爲一個單元的一組有序的數據庫操做。若是組中的全部操做都成功,則認爲事務成功,即便只有一個操做失敗,事務也不成功。若是全部操做完成,事務則提交,其修改將做用於全部其餘數據庫進程。若是一個操做失敗,則事務將回滾,該事務全部操做的影響都將取消 56.優化MYSQL數據庫的方法 一、選取最適用的字段屬性,儘量減小定義字段長度,儘可能把字段設置NOT NULL,例如'省份,性別',最好設置爲ENUM 二、使用鏈接(JOIN)來代替子查詢: a.刪除沒有任何訂單客戶:DELETE FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo) b.提取全部沒有訂單客戶:SELECT FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo) c.提升b的速度優化:SELECT FROM customerinfo LEFT JOIN orderid customerinfo.customerid=orderinfo.customerid WHERE orderinfo.customerid IS NULL 3、使用聯合(UNION)來代替手動建立的臨時表 a.建立臨時表:SELECT name FROM `nametest` UNION SELECT username FROM `nametest2` 四、事務處理: a.保證數據完整性,例如添加和修改同時,二者成立則都執行,一者失敗都失敗 mysql_query("BEGIN"); mysql_query("INSERT INTO customerinfo (name) VALUES ('$name1')"; mysql_query("SELECT * FROM `orderinfo` where customerid=".$id"); mysql_query("COMMIT"); 五、鎖定表,優化事務處理: a.咱們用一個 SELECT 語句取出初始數據,經過一些計算,用 UPDATE 語句將新值更新到表中。 包含有 WRITE 關鍵字的 LOCK TABLE 語句能夠保證在 UNLOCK TABLES 命令被執行以前, 不會有其它的訪問來對 inventory 進行插入、更新或者刪除的操做 mysql_query("LOCK TABLE customerinfo READ, orderinfo WRITE"); mysql_query("SELECT customerid FROM `customerinfo` where id=".$id); mysql_query("UPDATE `orderinfo` SET ordertitle='$title' where customerid=".$id); mysql_query("UNLOCK TABLES"); 六、使用外鍵,優化鎖定表 a.把customerinfo裏的customerid映射到orderinfo裏的customerid, 任何一條沒有合法的customerid的記錄不會寫到orderinfo裏 CREATE TABLE customerinfo ( customerid INT NOT NULL, PRIMARY KEY(customerid) )TYPE = INNODB; CREATE TABLE orderinfo ( orderid INT NOT NULL, customerid INT NOT NULL, PRIMARY KEY(customerid,orderid), FOREIGN KEY (customerid) REFERENCES customerinfo (customerid) ON DELETE CASCADE )TYPE = INNODB; 注意:'ON DELETE CASCADE',該參數保證當customerinfo表中的一條記錄刪除的話同時也會刪除order 表中的該用戶的全部記錄,注意使用外鍵要定義事務安全類型爲INNODB; 七、創建索引: a.格式: (普通索引)-> 建立:CREATE INDEX <索引名> ON tablename (索引字段) 修改:ALTER TABLE tablename ADD INDEX [索引名] (索引字段) 創表指定索引:CREATE TABLE tablename([...],INDEX[索引名](索引字段)) (惟一索引)-> 建立:CREATE UNIQUE <索引名> ON tablename (索引字段) 修改:ALTER TABLE tablename ADD UNIQUE [索引名] (索引字段) 創表指定索引:CREATE TABLE tablename([...],UNIQUE[索引名](索引字段)) (主鍵)-> 它是惟一索引,通常在建立表是創建,格式爲: CREATA TABLE tablename ([...],PRIMARY KEY[索引字段]) 八、優化查詢語句 a.最好在相同字段進行比較操做,在創建好的索引字段上儘可能減小函數操做 例子1: SELECT * FROM order WHERE YEAR(orderDate)<2008;(慢) SELECT * FROM order WHERE orderDate<"2008-01-01";(快) 例子2: SELECT * FROM order WHERE addtime/7<24;(慢) SELECT * FROM order WHERE addtime<24*7;(快) 例子3: SELECT * FROM order WHERE title like "%good%"; SELECT * FROM order WHERE title>="good" and name<"good"; 57.在PHP中,heredoc是一種特殊的字符串,它的結束標誌必須? heredoc的語法是用"<<<"加上本身定義成對的標籤,在標籤範圍內的文字視爲一個字符串 定界符 例子: $str = <<<EOT後 my name is Jiang Qihui! EOT; 58.InnoDB引擎中,如何開啓一個排它的讀寫鎖 lock tables test write; //通過測試啓用另外一個mysql回話都不能讀和寫test表,代表此答案是正確的(答案很簡單,僅供回到,其餘裏面涉及的東西多的嚇人) 59.面向對象中,self與$this的區別是? this是指向當前對象的指針(姑且用C裏面的指針來看吧),self是指向當前類的指針,parent是指向父類的指針(做者注,不能看作c的指針,只能看作相似別名的東西) 1.self能夠訪問本類中的靜態屬性和靜態方法,能夠訪問父類中的靜態屬性和靜態方法。用self時,能夠不用實例化的 2.this能夠調用本類中的方法和屬性,也能夠調用父類中的能夠調的方法和屬性,能夠說除過靜態和const常量,基本上其餘均可以使用this聯絡 3.parent是指向父類的指針,通常咱們使用parent來調用父類的構造函數 60.求兩個日期的差數,例如2007-2-5 ~ 2007-3-6 的日期差數 $begin=strtotime('2007-2-5'); $end=strtotime('2007-3-6'); echo ($end-$begin)/(24*3600); 61.請簡述數據庫設計的範式及應用 通常第3範式就足以,用於表結構的優化,這樣作既能夠避免應用程序過於複雜同時也避免了SQL語句過於龐大所形成系統效率低下。 ANSWER: 第一範式:若關係模式R的每個屬性是不可再分解的,再屬於第一範式。 第二範式:若R屬於第一範式,且全部的非碼屬性都徹底函數依賴於碼屬性,則爲第二範式。 第三範式:若R屬於第二範式,且全部的非碼屬性沒有一個是傳遞函數依賴於候選碼,則屬於第三範式 62. mysql創建索引 (普通索引)-> 建立:CREATE INDEX <索引名> ON tablename (索引字段) 修改:ALTER TABLE tablename ADD INDEX [索引名] (索引字段) 創表指定索引:CREATE TABLE tablename([...],INDEX[索引名](索引字段)) (惟一索引)-> 建立:CREATE UNIQUE <索引名> ON tablename (索引字段) 修改:ALTER TABLE tablename ADD UNIQUE [索引名] (索引字段) 創表指定索引:CREATE TABLE tablename([...],UNIQUE[索引名](索引字段)) (主鍵)-> 它是惟一索引,通常在建立表是創建,格式爲: CREATA TABLE tablename ([...],PRIMARY KEY[索引字段]) 63.foo()和@foo()之間有什麼區別? @foo()控制錯誤輸出 有些時候@沒法徹底一致錯誤顯示,必定要設置錯誤顯示級別 64.爲了微信頁面好看,將中文字符小於4的補充空格 function cn_string_to_4($str) { if (mb_strlen($str, 'utf8') < 4) { return $str = $str . str_repeat(' ', (4 - mb_strlen($str, 'utf8'))); } return $str; } 65.context上下文 php版解釋 context翻譯爲上下文其實不是很好,只是翻譯理解大概的做用,對於開發來講,context是對定義的使用的變量,常量或者說是配置, 部分的函數功能除了缺省值以外,每每須要手動設置一些定義量來配合當前語境,來適配開發者想法的需求,這些能夠適配其餘方法或者函數的 定義量就是context,數據來源有多是變量,也多是數據流,這些函數是爲了適應更多其餘函數調用或者方便開發者使用操做函數, 讓開發者配合當前語境來設置,好比stream_context_create 經過設置選項來讓file_get_contents實現更多需求的功能(php中例子) 好比fopen操做多個數據流,返回值能夠區分不一樣的打開的數據流,這個不是很確切可是足以說明問題 66.php變量和數組大小限制 php.ini 的memory_limit的大小就是php變量的大小 67.php數組操做 $people = array("Bill", "Steve", "Mark", "David"); echo current(people)."<br>";//當前元素是Billechonext(people)."<br>"; echo current(people)."<br>";//如今當前元素是Steveechoprev(people)."<br>"; echo end(people)."<br>";//最後一個元素是Davidechoprev(people)."<br>"; echo current(people)."<br>";//目前的當前元素是Markechoreset(people)."<br>"; echo next($people) . "<br>"; // Bill 的下一個元素是 Steve print_r (each($people)); // 返回當前元素的鍵名和鍵值(目前是 Steve),並向前移動內部指針 68.mysql替換制定的內容的 相似正則表達式的功能 content= 'asnfojassozxpdsgdspdps神龍架誰驕傲的驕傲搜ID飛機掃' SELECT content FROM test WHERE id =1 吧zx替換成ZZZZ UPDATE test SET content = REPLACE(content,'zx','ZZZZ') WHERE id =1 content = asnfojassoZZZZpdsgdspdps神龍架誰驕傲的驕傲搜ID飛機掃 吧ZZZZ到神龍架之間的內容替換成空 UPDATE test SET content = INSERT(content, INSTR(content,'ZZZZ')+LENGTH('ZZZZ'), INSTR(content,'神農架')- INSTR(content,'ZZZZ')-LENGTH('神農架'),'') WHERE id =1 content = `INSERT`(str,pos,len,newstr) str 須要替換的字段 pos其實位置 len 長度 newstr 須要替換的字符 69.PHP.ini中auto_prepend_file與auto_append_file的用法 使用auto_prepend_file與auto_append_file在全部頁面的頂部與底部require文件。 php.ini中有兩項: auto_prepend_file 在頁面頂部加載文件 auto_append_file 在頁面底部加載文件 使用這種方法能夠不須要改動任何頁面,當須要修改頂部或底部require文件時,只須要修改auto_prepend_file與auto_append_file的值便可。 例如:修改php.ini,修改auto_prepend_file與auto_append_file的值。 auto_prepend_file = "/home/fdipzone/header.php" auto_append_file = "/home/fdipzone/footer.php" 這樣就不須要修改代碼,可是移植的時候必定要記得加上這個配置 70.php吧字符串直接轉換成數組處理 $str ='123456'; echo strlen($str) - 1; echo '<br>'; echo $str{strlen($str) - 1}; echo '<br>'; echo $str[strlen($str) - 1]; 之後處理即便很複雜的字符串,均可以很輕鬆的處理了 71. windows 和linux mysql怎麼導入大文件的sql文件,防止超時 C:\wamp\bin\mysql\mysql5.5.20\bin\mysql -u root -p --default-character-set=utf8 tt < C:\22.sql 上面是windows,請記住必定要設置編碼格式 tt 是數據庫名稱 linux 導出命令 /usr/local/Comsenz/mysql/bin/mysqldump -uroot -p shopnc > /root/22.sql 導入命令 /usr/local/Comsenz/mysql/bin/mysql -uroot -proot@ tt < /root/22.sql 72.php代碼優化,由於內容過多目前只引用博客的內容,精簡列下幾點 http://www.cnblogs.com/zx-admin/p/4762961.html 用單引號代替雙引號來包含字符串,這樣作會更快一些。由於PHP會在雙引號包圍的字符串中搜尋變量,單引號則不會,注意:只有echo能這麼作,它是一種能夠把多個字符串看成參數的「函數」(譯註:PHP手冊中說echo是語言結構,不是真正的函數,故把函數加上了雙引號)。 PS:在單引號中,PHP不會自動搜尋變量、轉義字符等,所以效率上快不少。而通常來講字符串是沒有變量的,因此使用雙引號會致使性能不佳。 一、若是能將類的方法定義成static,就儘可能定義成static,它的速度會提高將近4倍。 PS:事實上,function、method、static method的速度不會有太大差別。具體可見「PHP函數的實現原理及性能分析【轉載】」一文。 二、row[′id′]的速度是row[′id′]的速度是row[id]的7倍。 PS:不太懂,貌似差別只有後者會先判斷id這個宏是否存在,若是不存在則自動轉變爲字符串。 三、echo 比 print 快,而且使用echo的多重參數(譯註:指用逗號而不是句點)代替字符串鏈接,好比echo str1,str1,str2。 PS:若是使用echo str1.str1.str2 就會須要 PHP 引擎首先把全部的變量鏈接起來,而後在輸出,而echo str1,str1,str2,PHP 引擎就會按照循序輸出他們 四、在執行for循環以前肯定最大循環數,不要每循環一次都計算最大值,最好運用foreach代替。 PS:像count、strlen這樣的操做實際上是O(1)的,所以不會帶來太多消耗,固然避免每次循環都計算是比較好的策略。最好用foreach代替for,這個效率更高,若是考慮到 foreach(arrayasarrayasvar)每次拷貝的消耗,能夠使用foreach(array as &array as &var)這樣的引用。 五、註銷那些不用的變量尤爲是大數組,以便釋放內存。 PS:若是沒有記錯的話,unset($array)不會馬上釋放內存,但隨時釋放是個好習慣。 六、儘可能避免使用__get,__set,__autoload。 七、require_once()代價昂貴。 PS:require_once和include_once須要判重,所以效率上要低,可是5.2版本後效率問題已經基本解決。 八、include文件時儘可能使用絕對路徑,由於它避免了PHP去include_path裏查找文件的速度,解析操做系統路徑所需的時間會更少。 PS:支持,儘可能少用iniset()來設置include_path。 九、若是你想知道腳本開始執行(譯註:即服務器端收到客戶端請求)的時刻,使用SERVER[′REQUESTTIME′]要好於time()。PS:SERVER[′REQUESTTIME′]要好於time()。PS:_SERVER['REQUEST_TIME']保存了發起該請求時刻的時間戳,而time()則返回當前時刻的Unix時間戳。 十、函數代替正則表達式完成相同功能。 PS:這種函數是指strtok、strstr、strpos、str_replace、substr、explode、implode等等。 十一、str_replace函數比preg_replace函數快,但strtr函數的效率是str_replace函數的四倍。 PS:字符串操做比正則替換要快。 十二、若是一個字符串替換函數,可接受數組或字符做爲參數,而且參數長度不太長,那麼能夠考慮額外寫一段替換代碼,使得每次傳遞參數是一個字符,而不是隻寫一行代碼接受數組做爲查詢和替換的參數。 PS:須要考慮到內置函數和用戶自定義函數的開銷差別,恐怕這種作法得不償失。 1三、使用選擇分支語句(譯註:即switch case)好於使用多個if,else if語句。 PS:php中switch支持數值和字符串變量,比C的switch要好用,建議使用。 1四、用@屏蔽錯誤消息的作法很是低效,極其低效。 PS:有什麼替代方法嗎?沒有的話仍是不得不用的…… 1五、打開apache的mod_deflate模塊,能夠提升網頁的瀏覽速度。 1六、數據庫鏈接當使用完畢時應關掉,不要用長鏈接。 PS:在鏈接以前,最好設置一下相應的超時機制,例如連接超時、讀寫超時、等待超時等。 1七、錯誤消息代價昂貴。 1八、在方法中遞增局部變量,速度是最快的。幾乎與在函數中調用局部變量的速度至關。 1九、遞增一個全局變量要比遞增一個局部變量慢2倍。 20、遞增一個對象屬性(如:$this->prop++)要比遞增一個局部變量慢3倍。 2一、遞增一個未預約義的局部變量要比遞增一個預約義的局部變量慢9至10倍。 2二、僅定義一個局部變量而沒在函數中調用它,一樣會減慢速度(其程度至關於遞增一個局部變量)。PHP大概會檢查看是否存在全局變量。 2三、方法調用看來與類中定義的方法的數量無關,由於我(在測試方法以前和以後都)添加了10個方法,但性能上沒有變化。 2四、派生類中的方法運行起來要快於在基類中定義的一樣的方法。 2五、調用帶有一個參數的空函數,其花費的時間至關於執行7至8次的局部變量遞增操做。相似的方法調用所花費的時間接近於15次的局部變量遞增操做。 2六、Apache解析一個PHP腳本的時間要比解析一個靜態HTML頁面慢2至10倍。儘可能多用靜態HTML頁面,少用腳本。 2七、除非腳本能夠緩存,不然每次調用時都會從新編譯一次。引入一套PHP緩存機制一般能夠提高25%至100%的性能,以避免除編譯開銷。 2八、儘可能作緩存,可以使用memcached。memcached是一款高性能的內存對象緩存系統,可用來加速動態Web應用程序,減輕數據庫負載。對運算碼 (OP code)的緩存頗有用,使得腳本沒必要爲每一個請求作從新編譯。 2九、當操做字符串並須要檢驗其長度是否知足某種要求時,你想固然地會使用strlen()函數。此函數執行起來至關快,由於它不作任何計算,只返回在zval 結構(C的內置數據結構,用於存儲PHP變量)中存儲的已知字符串長度。可是,因爲strlen()是函數,多多少少會有些慢,由於函數調用會通過諸多步驟,如字母小寫化(譯註:指函數名小寫化,PHP不區分函數名大小寫)、哈希查找,會跟隨被調用的函數一塊兒執行。在某些狀況下,你能夠使用isset() 技巧加速執行你的代碼。 (舉例以下) if (strlen(foo) < 5) { echo 「Foo is too short」foo) < 5) { echo 「Foo is too short」$ } (與下面的技巧作比較) if (!isset(foo{5})) { echo 「Foo is too short」foo{5})) { echo 「Foo is too short」$ } 調用isset()恰巧比strlen()快,由於與後者不一樣的是,isset()做爲一種語言結構,意味着它的執行不須要函數查找和字母小寫化。也就是說,實際上在檢驗字符串長度的頂層代碼中你沒有花太多開銷。 PS:長見識了。 30、當執行變量i的遞增或遞減時,i的遞增或遞減時,i++會比++i慢一些。這種差別是PHP特有的,並不適用於其餘語言,因此請不要修改你的C或Java代碼並期望它們能當即變快,沒用的。++i慢一些。這種差別是PHP特有的,並不適用於其餘語言,因此請不要修改你的C或Java代碼並期望它們能當即變快,沒用的。++i更快是由於它只須要3條指令(opcodes),$i++則須要4條指令。後置遞增實際上會產生一個臨時變量,這個臨時變量隨後被遞增。而前置遞增直接在原值上遞增。這是最優化處理的一種,正如Zend的PHP優化器所做的那樣。牢記這個優化處理不失爲一個好主意,由於並非全部的指令優化器都會作一樣的優化處理,而且存在大量沒有裝配指令優化器的互聯網服務提供商(ISPs)和服務器。 3一、並非事必面向對象(OOP),面向對象每每開銷很大,每一個方法和對象調用都會消耗不少內存。 3二、並不是要用類實現全部的數據結構,數組也頗有用。 3三、不要把方法細分得過多,仔細想一想你真正打算重用的是哪些代碼? 3四、當你須要時,你總能把代碼分解成方法。 PS:分解成方法要適當,行數少使用頻率高的方法儘可能用直接寫代碼,能夠減小函數堆棧開銷;且方法嵌套不宜過深,不然大大影響PHP的運行效率。 3五、儘可能採用大量的PHP內置函數。 3六、若是在代碼中存在大量耗時的函數,你能夠考慮用C擴展的方式實現它們。 3七、評估檢驗(profile)你的代碼。檢驗器會告訴你,代碼的哪些部分消耗了多少時間。Xdebug調試器包含了檢驗程序,評估檢驗整體上能夠顯示出代碼的瓶頸。 3八、mod_zip可做爲Apache模塊,用來即時壓縮你的數據,並可以讓數據傳輸量下降80%。 3九、在能夠用 file_get_contents替代file、fopen、feof、fgets等系列方法的狀況下,儘可能用file_get_contents,由於他的效率高得多!可是要注意file_get_contents在打開一個URL文件時候的PHP版本問題; PS:這個要記住,儘可能使用file_get_contents和file_put_contents,不須要本身判斷文件句柄打開是否成功。 40、儘可能的少進行文件操做,雖然PHP的文件操做效率也不低的; 4一、優化Select SQL語句,在可能的狀況下儘可能少的進行Insert、Update操做(在update上,我被惡批過); 4二、儘量的使用PHP內部函數(可是我卻爲了找個PHP裏面不存在的函數,浪費了本能夠寫出一個自定義函數的時間,經驗問題啊!); PS:內置函數比用戶自定義函數效率高了將近一個數量級。 4三、循環內部不要聲明變量,尤爲是大變量:對象(這好像不僅是PHP裏面要注意的問題吧?); PS:這個必須的,變量過多或者過大時,每次重分配的開銷就沒法忽略。 4四、多維數組儘可能不要循環嵌套賦值; 4五、在能夠用PHP內部字符串操做函數的狀況下,不要用正則表達式; 4六、foreach效率更高,儘可能用foreach代替while和for循環; 4七、用單引號替代雙引號引用字符串; PS:暈,這個不就是第一條嗎? 4八、「用i+=1代替i=i+1。符合c/c++的習慣,效率還高」; 4九、對global變量,應該用完就unset()掉; i++和++i++和++i的區別,這個不少公司問代碼優化最後的一個問題,問題是這種寫法在php在opcode層面的時候是++i性能更好,可是whocare,實際上,在執行成編譯以後0.1以後,性能是同樣的,呵呵,由於php是c編寫的,只不過是opcode的時候回多出一個臨時變量,是php語言自身解析代碼的作法和c語言不同,可是最終是有那麼十萬分一毫秒的損失,可是但就一個臨時變量就是更改代碼習慣,想一想不以爲蛋疼嗎?你一個功能方法使用的臨時變量不知道有多少,在或者有人會說代碼性能就是這麼多個十萬分之一累加起來的,其實這種扣細節的人,只不過是壓工資的理由而已,實際開發,whofuckingcare你個i性能更好,可是whocare,實際上,在執行成編譯以後0.1以後,性能是同樣的,呵呵,由於php是c編寫的,只不過是opcode的時候回多出一個臨時變量,是php語言自身解析代碼的作法和c語言不同,可是最終是有那麼十萬分一毫秒的損失,可是但就一個臨時變量就是更改代碼習慣,想一想不以爲蛋疼嗎?你一個功能方法使用的臨時變量不知道有多少,在或者有人會說代碼性能就是這麼多個十萬分之一累加起來的,其實這種扣細節的人,只不過是壓工資的理由而已,實際開發,whofuckingcare你個i++和++$i是怎麼樣寫的,公司只關心你能不能完成某個功能模塊,什麼時間能夠完成,我研究過不少開源cms的代碼,實際中發現,徹底都不是一回事,這些建議只有少一部分運用到實際開發中,開發更可能是爲了實現某種特殊目的而是作的,好比我須要實現很複雜的邏輯業務,或者我須要這個模塊須要很好的性能,或者我須要作成接口,而這個時候每每和這些代碼優化有屁關係 php的口號就是快,粗,易,面試你的人分要吧寫c/c++,或者java的習慣拖進php,也沒辦法,其實這個時候你徹底能夠說,你應該是找個java或者c/c++程序員來寫php 1. 短代碼不等於快的代碼 不少人在寫程序時但願將代碼寫的越簡潔越好,可是越短的代碼有時候反而須要更長的執行時間。 2. 在寫程序的時候更應該注重程序的擴展性,而不是追求速度。 3. 在優化你的代碼以前,先看看跟數據庫有關的部分,由於大多數應用程序的瓶頸在數據庫而不是代碼。 4. 微優化得不償失 什麼叫作微優化?就像前面所說的將正則表達式部分的代碼改用字符串函數代替。這樣作有如下缺點: (1)花費時間較長 (2)不會根本上解決性能問題 (3)頗有可能會破壞之前的代碼從而產生未知的錯誤 (4)付出大於回報 還有關於代碼結構的優化,也是重構的技巧 1,功能性代碼,重複使用最好作成公用型函數,不必定須要作成完整的類,就是提取公共代碼 2,經常使用靜態常量,建議集中起來做爲配置文件,全局使用 引用官方文檔的一句話,不少時候不須要自做聰明的去優化代碼,由於編譯器會幫你完整這部分工做 做者注:php和c/c++徹底不同,不要以c/c++的理解去優化代碼 73. php的內存回收機制 這個根據不用版本不一樣,5.X和7.X會有寫不一樣 74. 支持的協議和封裝協議 file:// — 訪問本地文件系統 http:// — 訪問 HTTP(s) 網址 ftp:// — 訪問 FTP(s) URLs php:// — 訪問各個輸入/輸出流(I/O streams) zlib:// — 壓縮流 data:// — 數據(RFC 2397) glob:// — 查找匹配的文件路徑模式 phar:// — PHP 歸檔 ssh2:// — Secure Shell 2 rar:// — RAR ogg:// — 音頻流 expect:// — 處理交互式的流 經常使用的 php:// 訪問各個輸入/輸出流 好比接受一些二進制的數據流 $data = urldecode(file_get_contents('php://input')); 其實這個用處很大,能夠好好研究,特別是各類語言對接API的時候 php://input 是個能夠訪問請求的原始數據的只讀流。 POST 請求的狀況下,最好使用 php://input 來代替 $HTTP_RAW_POST_DATA,由於它不依賴於特定的 php.ini 指令。 並且,這樣的狀況下 $HTTP_RAW_POST_DATA 默認沒有填充, 比激活 always_populate_raw_post_data 潛在須要更少的內存。 enctype="multipart/form-data" 的時候 php://input 是無效的 php://output php://output 是一個只寫的數據流, 容許你以 print 和 echo 同樣的方式 寫入到輸出緩衝區。 php://fd php://fd 容許直接訪問指定的文件描述符。 例如 php://fd/3 引用了文件描述符 3。 php://memory 和 php://temp php://memory 和 php://temp 是一個相似文件 包裝器的數據流,容許讀寫臨時數據。 二者的惟一區別是 php://memory 老是把數據儲存在內存中, 而 php://temp 會在內存量達到預約義的限制後(默認是 2MB)存入臨時文件中。 臨時文件位置的決定和 sys_get_temp_dir() 的方式一致。 php://temp 的內存限制可經過添加 /maxmemory:NN 來控制,NN 是以字節爲單位、保留在內存的最大數據量,超過則使用臨時文件。 php://filter php://filter 是一種元封裝器, 設計用於數據流打開時的篩選過濾應用。 這對於一體式(all-in-one)的文件函數很是有用,相似 readfile()、 file() 和 file_get_contents(), 在數據流內容讀取以前沒有機會應用其餘過濾器。 php://filter 目標使用如下的參數做爲它路徑的一部分。 複合過濾鏈可以在一個路徑上指定。詳細使用這些參數能夠參考具體範例。 75.獲取系統和用定義的常量,方法,變量 get_defined_constants();//獲取定義的常量 get_defined_vars();//獲取定義的變量 get_defined_functions();//獲取定義的方法 76. php運行模式的比較 cgi fast-cgi cli web模塊模式 多線程 參考博客地址:http://www.cnblogs.com/zx-admin/p/4082992.html http://www.cnblogs.com/zx-admin/p/5564984.html 在說明多線程的題前,須要弄清楚如下幾個問題 1,ts 和 nts的區別 Thread Safe和NoneThread Safe 先說windows的,在php官網,在windows區域有在文件下在有 http://windows.php.net/download#php-7.0 文件名有很明顯區分 VC14 x86 Non Thread Safe (2016-May-25 23:02:14) VC14 x86 Thread Safe (2016-May-25 23:02:14) VC6與VC9的區別: VC6版本是使用Visual Studio 6編譯器編譯的,若是你的PHP是用Apache來架設的,那你就選擇VC6版本。 VC9版本是使用Visual Studio 2008編譯器編譯的,若是你的PHP是用IIS來架設的,那你就選擇 VC9版本。 VC9版本是針對IIS服務器的版本,沒有對APACHE的支持,而VC6版本對IIS和apache都提供了支持 Windows版的PHP從版本5.2.1開始有Thread Safe和NoneThread Safe之分。 先從字面意思上理解,Thread Safe是線程安全,執行時會進行線程(Thread)安全檢查,以防止有新要求就啓動新線程的CGI執行方式而耗盡系統資源。Non Thread Safe是非線程安全,在執行時不進行線程(Thread)安全檢查。 Linux上的PHP一樣有NTS和TS版本的區別,默認是NTS版本,configure時加上--enable-maintainer-zts則編譯爲TS版本.何時須要TS版本呢?好比你要使用pthreads這個多線程的PECL擴展時,或者PHP以MOD_PHP嵌入多線程運行下的Apache,好比Apache在Linux上提供的Event MPM就是一個多進程多線程的工做模型,Windows上Apache採用的WinNT MPM也是一個多線程模型,這時都須要TS版本的PHP. 而若是以PHP-FPM(好比搭配Nginx或者Apache的mod_fastcgi)或者PHP-CGI(好比搭配Apache的mod_fcgid或者Win上的IIS)來運行PHP,則通常都不須要TS線程安全版本的PHP.這個在以前博客也說過 2,運行模式 1)CGI(通用網關接口 / Common Gateway Interface) 2)FastCGI(常駐型CGI / Long-Live CGI) 3)CLI(命令行運行 / Command Line Interface) 4)Web模塊模式(Apache等Web服務器運行的模式) 5)ISAPI(Internet Server Application Program Interface) 備註:在PHP5.3之後,PHP再也不有ISAPI模式,安裝後也再也不有php5isapi.dll這個文件。要在IIS6上使用高版本PHP,必須安裝FastCGI 擴展,而後使IIS6支持FastCGI。 爲何要說運行模式呢?由於在有些擴展併發的時候,有些擴展只能在cli下運行,其實不是 3,php多線程 目前經常使用的擴展有pcnlt,POSIX ,pthreads,這三個比較多,可是與其說是多線程其實多進程,在併發的時候會巨急消耗內存因此用的時候,請注意,好比pcnlt, 真的多線程只有pthreads,可是本人沒有確認過,參看http://zyan.cc/pthreads/,由於我如今的測試環境是nts的,全部測試就必須從新在作一個新環境 因此來不及測試,後續更新測試結果,還有一個問題就是php-fpm去管理php的內存帶來的php併發效果不錯,可是php-fpm會有一個壞處就是執行完以後,不會主動把內存 還給系統而是吧資源依然控制在php-fpm,因此爲何php第一次運行慢,第二次速度就上來了,這個就帶來一個問題關於php-fpm分配內存的選擇 dm有三種分配方式dynamic ,static,demand,光這個調優就得一片文章來說,因此pcnlt在服務器正式環境使用 最好是吧內存弄大一些,並且併發數也不要多 否則很容易內存消耗過多,致使錯誤,這裏還有一個地方值得注意的是,當php以靜態模塊在apache下運行的時候內存消耗是怎麼樣的,會及時還給系統嗎?,和php-fpm管理內存對比也是值得注意的,這測試也是有必要去作的 若是實際項目須要使用建議使用 workerman swoole 一、cgi (Common Gateway Interface) CGI即通用網關接口(Common Gateway Interface),它是一段程序, 通俗的講CGI就象是一座橋,把網頁和WEB服務器中的執行程序鏈接起來,它把HTML接收的指令傳遞給服務器的執行程序,再把服務器執行程序的結果返還給HTML頁。CGI 的跨平臺性能極佳,幾乎能夠在任何操做系統上實現。 CGI已是比較老的模式了,這幾年都不多用了。 每有一個用戶請求,都會先要建立cgi的子進程,而後處理請求,處理完後結束這個子進程,這就是fork-and-execute模式。 當用戶請求數量很是多時,會大量擠佔系統的資源如內存,CPU時間等,形成效能低下。因此用cgi方式的服務器有多少鏈接請求就會有多少cgi子進程,子進程反覆加載是cgi性能低下的主要緣由。 若是不想把 PHP 嵌入到服務器端軟件(如 Apache)做爲一個模塊安裝的話,能夠選擇以 CGI 的模式安裝。或者把 PHP 用於不一樣的 CGI 封裝以便爲代碼建立安全的 chroot 和 setuid 環境。這樣每一個客戶機請求一個php文件,Web服務器就調用php.exe(win下是php.exe,linux是php)去解釋這個文件,而後再把解釋的結果以網頁的形式返回給客戶機。 這種安裝方式一般會把 PHP 的可執行文件安裝到 web 服務器的 cgi-bin 目錄。CERT 建議書 CA-96.11 建議不要把任何的解釋器放到 cgi-bin 目錄。 這種方式的好處是把web server和具體的程序處理獨立開來,結構清晰,可控性強,同時缺點就是若是在高訪問需求的狀況下,cgi的進程fork就會成爲很大的服務器負擔,想 象一下數百個併發請求致使服務器fork出數百個進程就明白了。這也是爲何cgi一直揹負性能低下,高資源消耗的惡名的緣由。 CGI模式安裝: CGI已是比較老的模式了,這幾年都不多用了,因此咱們只是爲了測試。 安裝CGI模式須要註釋掉 LoadModule php5_module modules/libphp5.so 這行。若是不註釋這行會一直走到handler模式。也就是模塊模式。 而後在httpd.conf增長action: Action application/x-httpd-php /cgi-bin/ 若是在/cgi-bin/目錄找不到php-cgi.可自行從php的bin裏面cp一個。 而後重啓apache,再打開測試頁面發現Server API變成:CGI/FastCGI。說明成功切換爲cgi模式。 問題: 1) 若是cgi程序放在/usr/local/httpd/cgi-bin/裏沒法執行,遇到403或500錯誤的話 打開apache錯誤日誌 有以下提示: Permission denied: exec of 能夠檢查cgi程序的屬性,按Linux contexts文件 裏定義的,/usr/local/httpd/cgi-bin/裏必須是httpd_sys_script_exec_t 屬性。 經過ls -Z查看,若是不是則經過以下命令更改: chcon -t httpd_sys_script_exec_t /var/www/cgi-bin/*.cgi 若是是虛擬主機裏的cgi,則參考問題2使之能正常使用普通的功能後,再經過chcon設置cgi文件的context爲 httpd_sys_script_exec_t便可。chcon -R -t httpd_sys_script_exec_t cgi-bin/ 2) apache錯誤提示:.... malformed header from script. Bad header= 根據提示說明有header有問題,查看文件輸出的第一句話是什麼,應該相似於以下 Content-type: text/plain; charset=iso-8859-1\n\n 或者Content-type:text/html\n\n 注意:聲明好Content-type後要輸出兩個空行。 3)apache錯誤提示: Exec format error 腳本解釋器設置錯誤。腳本第一行應該以'#!解釋器路徑'的形式, 填寫腳本解釋器的路徑,若是是PERL程序,常見的路徑爲: #!/usr/bin/perl 或 #!/usr/local/bin/perl 若是是PHP程序,不須要填寫解釋器路徑,系統會自動找到PHP。 二、fast-cgi模式 fast-cgi 是cgi的升級版本,FastCGI 像是一個常駐 (long-live) 型的 CGI,它能夠一直執行着,只要激活後,不會每次都要花費時間去 fork 一次 (這是 CGI 最爲人詬病的 fork-and-execute 模式)。 FastCGI的工做原理是: (1)、Web Server啓動時載入FastCGI進程管理器【PHP的FastCGI進程管理器是PHP-FPM(php-FastCGI Process Manager)】(IIS ISAPI或Apache Module); (2)、FastCGI進程管理器自身初始化,啓動多個CGI解釋器進程 (在任務管理器中可見多個php-cgi.exe)並等待來自Web Server的鏈接。 (3)、當客戶端請求到達Web Server時,FastCGI進程管理器選擇並鏈接到一個CGI解釋器。Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。 (4)、FastCGI子進程完成處理後將標準輸出和錯誤信息從同一鏈接返回Web Server。當FastCGI子進程關閉鏈接時,請求便告處理完成。FastCGI子進程接着等待並處理來自FastCGI進程管理器(運行在 WebServer中)的下一個鏈接。在正常的CGI模式中,php-cgi.exe在此便退出了。 在CGI模式中,你能夠想象 CGI一般有多慢。每個Web請求PHP都必須從新解析php.ini、從新載入所有dll擴展並重初始化所有數據結構。使用FastCGI,全部這些都只在進程啓動時發生一次。一個額外的好處是,持續數據庫鏈接(Persistent database connection)能夠工做。 Fastcgi的優勢: 1)從穩定性上看, fastcgi是以獨立的進程池運行來cgi,單獨一個進程死掉,系統能夠很輕易的丟棄,而後從新分 配新的進程來運行邏輯. 2)從安全性上看,Fastcgi支持分佈式運算. fastcgi和宿主的server徹底獨立, fastcgi怎麼down也不會把server搞垮. 3)從性能上看, fastcgi把動態邏輯的處理從server中分離出來, 大負荷的IO處理仍是留給宿主server, 這樣宿主server能夠一心一意做IO,對於一個普通的動態網頁來講, 邏輯處理可能只有一小部分, 大量的圖片等靜態 FastCGI缺點:說完了好處,也來講說缺點。從個人實際使用來看,用FastCGI模式更適合生產環境的服務器。但對於開發用機器來講就不太合適。由於當使用 Zend Studio調試程序時,因爲 FastCGI會認爲 PHP進程超時,從而在頁面返回 500錯誤。這一點讓人很是惱火,因此我在開發機器上仍是換回了 ISAPI模式。 三、cli模式 cli是php的命令行運行模式,你們常常會使用它,可是可能並無注意到(例如:咱們在linux下常用 "php -m"查找PHP安裝了那些擴展就是PHP命令行運行模式;有興趣的同窗能夠輸入php -h去深刻研究該運行模式) 四、模塊模式 模塊模式是以mod_php5模塊的形式集成,此時mod_php5模塊的做用是接收Apache傳遞過來的PHP文件請求,並處理這些請求,而後將處理後的結果返回給Apache。若是咱們在Apache啓動前在其配置文件中配置好了PHP模塊(mod_php5), PHP模塊經過註冊apache2的ap_hook_post_config掛鉤,在Apache啓動的時候啓動此模塊以接受PHP文件的請求。 除了這種啓動時的加載方式,Apache的模塊能夠在運行的時候動態裝載,這意味着對服務器能夠進行功能擴展而不須要從新對源代碼進行編譯,甚至根本不須要中止服務器。咱們所須要作的僅僅是給服務器發送信號HUP或者AP_SIG_GRACEFUL通知服務器從新載入模塊。可是在動態加載以前,咱們須要將模塊編譯成爲動態連接庫。此時的動態加載就是加載動態連接庫。 Apache中對動態連接庫的處理是經過模塊mod_so來完成的,所以mod_so模塊不能被動態加載,它只能被靜態編譯進Apache的核心。這意味着它是隨着Apache一塊兒啓動的。 Apache是如何加載模塊的呢?咱們之前面提到的mod_php5模塊爲例。首先咱們須要在Apache的配置文件httpd.conf中添加一行: 該運行模式是咱們之前在windows環境下使用apache服務器常用的,而在模塊化(DLL)中,PHP是與Web服務器一塊兒啓動並運行的。(是apache在CGI的基礎上進行的一種擴展,加快PHP的運行效率) LoadModule php5_module modules/mod_php5.so 這裏咱們使用了LoadModule命令,該命令的第一個參數是模塊的名稱,名稱能夠在模塊實現的源碼中找到。第二個選項是該模塊所處的路徑。若是須要在服務器運行時加載模塊,能夠經過發送信號HUP或者AP_SIG_GRACEFUL給服務器,一旦接受到該信號,Apache將從新裝載模塊,而不須要從新啓動服務器。 五、php 在nginx 中運行模式(nginx+PHP-FPM ) 使用FastCGI方式如今常見的有兩種stack:ligthttpd+spawn-fcgi;另一種是nginx+PHP-FPM(也能夠用spawn-fcgi)。 A、如上面所說該兩種結構都採用FastCGI對PHP支持,所以HTTPServer徹底解放出來,能夠更好地進行響應和併發處理。所以lighttpd和nginx都有small, but powerful和efficient的美譽。 B、該二者還能夠分出一個好壞來,spawn-fcgi因爲是lighttpd的一部分,所以安裝了lighttpd通常就會使用spawn-fcgi對php支持,可是目前有用戶說ligttpd的spwan-fcgi在高併發訪問的時候,會出現上面說的內存泄漏甚至自動重啓fastcgi。即:PHP腳本處理器當機,這個時候若是用戶訪問的話,可能就會出現白頁(即PHP不能被解析或者出錯)。 另外一個:首先nginx不像lighttpd自己含帶了fastcgi(spawn-fcgi),所以它徹底是輕量級的,必須藉助第三方的FastCGI處理器才能夠對PHP進行解析,所以其實這樣看來nginx是很是靈活的,它能夠和任何第三方提供解析的處理器實現鏈接從而實現對PHP的解析(在nginx.conf中很容易設置)。nginx能夠使用spwan-fcgi(須要一同安裝lighttpd,可是須要爲nginx避開端口,一些較早的blog有這方面安裝的教程),可是因爲spawn-fcgi具備上面所述的用戶逐漸發現的缺陷,如今慢慢減小使用nginx+spawn-fcgi組合了。 C、因爲spawn-fcgi的缺陷,如今出現了新的第三方(目前仍是,據說正在努力不久未來加入到PHP core中)的PHP的FastCGI處理器,叫作PHP-FPM(具體能夠google)。它和spawn-fcgi比較起來有以下優勢: 因爲它是做爲PHP的patch補丁來開發的,安裝的時候須要和php源碼一塊兒編譯,也就是說編譯到php core中了,所以在性能方面要優秀一些; 同時它在處理高併發方面也優於spawn-fcgi,至少不會自動重啓fastcgi處理器。具體採用的算法和設計能夠google瞭解。 所以,如上所說因爲nginx的輕量和靈活性,所以目前性能優越,愈來愈多人逐漸使用這個組合:nginx+PHP/PHP-FPM 總結: 目前在HTTPServer這塊基本能夠看到有三種stack比較流行: (1)Apache+mod_php5 (2)lighttp+spawn-fcgi (3)nginx+PHP-FPM 三者後二者性能可能稍優,可是Apache因爲有豐富的模塊和功能,目前來講仍舊是老大。有人測試nginx+PHP-FPM在高併發狀況下可能會達到Apache+mod_php5的5~10倍,如今nginx+PHP-FPM使用的人愈來愈多。 77. 隱藏 PHP 統弱點的難度。在 php.ini 文件裏設置 expose_php = off ,能夠減小他們能得到的有用信息。 一些簡單的方法能夠幫助隱藏 PHP,這樣作能夠提升攻擊者發現系另外一個策略就是讓 web 服務器用 PHP 解析不一樣擴展名。不管是經過 .htaccess 文件仍是 Apache 的配置文件,均可以設置能誤導攻擊者的文件擴展名: AddType application/x-httpd-php .asp .py .pl 使用未知的擴展名做爲 PHP 的擴展名 AddType application/x-httpd-php .bop .foo .133t 用 HTML 作 PHP 的文件後綴 AddType application/x-httpd-php .htm .html 能夠看頭部信息只要是php,僅作一部分防護做用 78. 範圍解析操做符 (::) 範圍解析操做符(也可稱做 Paamayim Nekudotayim)或者更簡單地說是一對冒號,能夠用於訪問靜態成員,類常量,還能夠用於覆蓋類中的屬性和方法。 79. 判斷文件是否引用成功 if (false === @include_once 'OpenID/RelyingParty.php') { exit; exit('引用XX失敗,請確保文件路徑正確'); } 80. 100.php7特性 2.堆棧的理解 均可以看作是一維數組來操做,隊列先進先出,出列只能在列頭,進列只能在列尾,堆棧是後進先出,進棧和出棧都是從棧頂 堆棧的工做原理是什麼? 堆棧是一種抽象數據結構,其操做機理是後進先出。當你把新條目推動堆棧時,已經在堆棧內的任何條目都會壓到堆棧的深處。一樣的,把一個條目從堆棧移出則會讓堆棧內的其餘條目都向堆棧的頂部移動。只有堆棧最頂端的條目能從堆棧中取出,條目離開堆棧的順序和它們被推動堆棧的順序同樣。你不妨回想下自動售貨機的裝貨和取貨過程就明白了。