所謂的測(cè)試,就是看看你寫的代碼是否達(dá)到了預(yù)期的效果,執(zhí)行就行,如果報(bào)
成都創(chuàng)新互聯(lián)專注于網(wǎng)站制作、網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站制作、網(wǎng)站開發(fā)。公司秉持“客戶至上,用心服務(wù)”的宗旨,從客戶的利益和觀點(diǎn)出發(fā),讓客戶在網(wǎng)絡(luò)營(yíng)銷中找到自己的駐足之地。尊重和關(guān)懷每一位客戶,用嚴(yán)謹(jǐn)?shù)膽B(tài)度對(duì)待客戶,用專業(yè)的服務(wù)創(chuàng)造價(jià)值,成為客戶值得信賴的朋友,為客戶解除后顧之憂。
錯(cuò),則根據(jù)錯(cuò)誤提示去修改錯(cuò)誤,若沒提示錯(cuò)但預(yù)期目的還是沒能夠達(dá)到,則
需要你一步一步進(jìn)行調(diào)試,例如輸出某些步驟的數(shù)據(jù),看看是否正確;
建議:編譯器你下了我就不推薦了。
網(wǎng)站開發(fā)所需要的技術(shù)的幫助文檔要全。
最好還有一個(gè)能轉(zhuǎn)碼的編譯工具,如UE。
最后要下載一個(gè),也就是最重要的--持之以恒的心!
比如有個(gè)user的表,且表里有數(shù)據(jù)。
$user=M('User');
$list=$user-find();
dump($list);
若有數(shù)據(jù),則表示連接成功。土辦法。
緣起
關(guān)于PHP 很多人的直觀感覺是PHP是一種靈活的腳本語(yǔ)言 庫(kù)類豐富 使用簡(jiǎn)單 安全 非常適合WEB開發(fā) 但性能低下 PHP的性能是否真 的就如同大家的感覺一樣的差呢?本文就是圍繞這么一個(gè)話題來進(jìn)行探討的 從源碼 應(yīng)用場(chǎng)景 基準(zhǔn)性能 對(duì)比分析等幾個(gè)方面深入分析PHP之性能問題 并通 過真實(shí)的數(shù)據(jù)來說話
從原理分析PHP性能
從原理分析PHP的性能 主要從以下幾個(gè)方面 內(nèi)存管理 變量 函數(shù) 運(yùn)行機(jī)制來進(jìn)行分析
內(nèi)存管理
類似Nginx的內(nèi)存管理方式 PHP在內(nèi)部也是基于內(nèi)存池 并且引入內(nèi)存池的生命周期概念 在內(nèi)存池方面 PHP對(duì)PHP腳本和擴(kuò)展的所有內(nèi) 存相關(guān)操作都進(jìn)行了托管 對(duì)大內(nèi)存和小內(nèi)存的管理采用了不同的實(shí)現(xiàn)方式和優(yōu)化 具體可以參考以下文檔 在內(nèi)存分配和回收的生命周期內(nèi) PHP采用一次初始化申請(qǐng)+動(dòng)態(tài)擴(kuò)容+內(nèi)存標(biāo)識(shí)回收機(jī)制 并且在每次請(qǐng)求結(jié)束后直 接對(duì)內(nèi)存池進(jìn)行重新mask
變量
總所周知 PHP是一種弱變量類型的語(yǔ)言 所以在PHP內(nèi)部 所有的PHP變量都對(duì)應(yīng)成一種類型Zval 其中具體定義如下
圖一PHP變量
在變量方面 PHP做了大量的優(yōu)化工作 比如說Reference counting和copy on writer機(jī)制 這樣能夠保證內(nèi)存使用上的優(yōu)化 并且減少內(nèi)存拷貝次數(shù)(請(qǐng)參考) 在數(shù)組方面 PHP內(nèi)部采用高效的hashtable來實(shí)現(xiàn)
函數(shù)
在PHP內(nèi)部 所有的PHP函數(shù)都回轉(zhuǎn)化成內(nèi)部的一個(gè)函數(shù)指針 比如說擴(kuò)展中函數(shù)
ZEND_FUNCTION?(?my_function?);//類似function?my_function(){}
在內(nèi)部展開后就會(huì)是一個(gè)函數(shù)
void?zif_my_function?(?INTERNAL_FUNCTION_PARAMETERS?);
void?zif_my_function(
int?ht
zval?*?return_value
zval?*?this_ptr
int?return_value_used
zend_executor_globals?*?executor_globals
);
從這個(gè)角度來看 PHP函數(shù)在內(nèi)部也是對(duì)應(yīng)一個(gè)函數(shù)指針
運(yùn)行機(jī)制
在話說PHP性能的時(shí)候 很多人都會(huì)說“C/C++是編譯型 JAVA是半編譯型 PHP是解釋型” 也就是說PHP是先動(dòng)態(tài)解析再代碼運(yùn)行的 所以從這個(gè)角度來看 PHP性能必然很差
的確 從PHP腳本運(yùn)行來輸出 的確是一個(gè)動(dòng)態(tài)解析再代碼運(yùn)行的過程 具體來說 PHP腳本的運(yùn)行機(jī)制如下圖所示
圖二 PHP運(yùn)行機(jī)制
PHP的運(yùn)行階段也分成三個(gè)階段
Parse 語(yǔ)法分析階段
Compile 編譯產(chǎn)出opcode中間碼
Execute 運(yùn)行 動(dòng)態(tài)運(yùn)行進(jìn)行輸出
所以說 在PHP內(nèi)部 本身也是存在編譯的過程 并且據(jù)此產(chǎn)生了大量的opcode cache工具 比如說apc eacc xcache等等 這些opcode cache在生產(chǎn)環(huán)境基本上在標(biāo)配 基于opcode cache 能到做到“PHP腳本編譯一次 多次運(yùn)行”的效果 從這點(diǎn)上 PHP就和JAVA的半編譯機(jī)制非常類似
所以 從運(yùn)行機(jī)制上來看 PHP的運(yùn)行模式和JAVA是非常類似的 都是先產(chǎn)生中間碼 然后運(yùn)行在不同虛擬機(jī)上
動(dòng)態(tài)運(yùn)行
從上面的幾個(gè)分析來看 PHP在內(nèi)存管理 變量 函數(shù) 運(yùn)行機(jī)制等幾個(gè)方面都做了大量的工作 所以從原理來看 PHP 不應(yīng)該存在性能問題 性能至少也應(yīng)該和Java 比較接近
這個(gè)時(shí)候就不得不談PHP動(dòng)態(tài)語(yǔ)言的特性所帶來的性能問題了 由于PHP是動(dòng)態(tài)運(yùn)行時(shí) 所以所有的變量 函數(shù) 對(duì)象調(diào)用 作用域?qū)崿F(xiàn)等等都是在 執(zhí)行階段中才確定的 這個(gè)從根本上決定了PHP性能中很難改變的一些東西 在C/C++等能夠在靜態(tài)編譯階段確定的變量 函數(shù) 在PHP中需要在動(dòng)態(tài)運(yùn)行 中確定 也就決定了PHP中間碼不能直接運(yùn)行而需要運(yùn)行在Zend Engine上
說到PHP變量的具體實(shí)現(xiàn) 又不得不說一個(gè)東西了 Hashtable Hashtable可以說在PHP靈魂之一 在PHP內(nèi)部廣泛用到 包含變量符號(hào)棧 函數(shù)符號(hào)棧等等都是基于hashtable的
以PHP變量為例來說明下PHP的動(dòng)態(tài)運(yùn)行特點(diǎn) 比如說代碼
?php
$var?=?“hello ?blog xiuwz ”;
?
該代碼的執(zhí)行結(jié)果就是在變量符號(hào)棧(是一個(gè)hashtable)中新增一個(gè)項(xiàng)
當(dāng)要使用到該變量時(shí)候 就去變量符合棧中去查找(也就是變量調(diào)用對(duì)出了一個(gè)hash查找的過程)
同樣對(duì)于函數(shù)調(diào)用也基本上類似有一個(gè)函數(shù)符號(hào)棧(hashtable)
其實(shí)關(guān)于動(dòng)態(tài)運(yùn)行的變量查找特點(diǎn) 在PHP的運(yùn)行機(jī)制中也能看出一些 PHP代碼通過解釋 編譯后的流程下圖
圖 PHP運(yùn)行實(shí)例
從上圖可以看出 PHP代碼在pile之后 產(chǎn)出的了類符號(hào)表 函數(shù)符號(hào)表 和OPCODE 在真正執(zhí)行的時(shí)候 zend Engine會(huì)根據(jù)op code去對(duì)應(yīng)的符號(hào)表中進(jìn)行查找 處理
從某種程度上 在這種問題的上 很難找到解決方案 因?yàn)檫@是由于PHP語(yǔ)言的動(dòng)態(tài)特性所決定的 但是在國(guó)內(nèi)外也有不少的人在尋找解決方案 因?yàn)?通過這樣 能夠從根本上完全的優(yōu)化PHP 典型的列子有facebook的hiphop
結(jié)論
從上面分析來看 在基礎(chǔ)的內(nèi)存管理 變量 函數(shù) 運(yùn)行機(jī)制方面 PHP本身并不會(huì)存在明顯的性能差異 但由于PHP的動(dòng)態(tài)運(yùn)行特性 決定了 PHP和其他的編譯型語(yǔ)言相比 所有的變量查找 函數(shù)運(yùn)行等等都會(huì)多一些hash查找的CPU開銷和額外的內(nèi)存開銷 至于這種開銷具體有多大 可以通過后 續(xù)的基準(zhǔn)性能和對(duì)比分析得出
因此 也可以大體看出PHP不太適合的一些場(chǎng)景 大量計(jì)算性任務(wù) 大數(shù)據(jù)量的運(yùn)算 內(nèi)存要求很嚴(yán)格的應(yīng)用場(chǎng)景 如果要實(shí)現(xiàn)這些功能 也建議通過擴(kuò)展的方式實(shí)現(xiàn) 然后再提供鉤子函數(shù)給PHP調(diào)用 這樣可以減低內(nèi)部計(jì)算的變量 函數(shù)等系列開銷
基準(zhǔn)性能
對(duì)于PHP基準(zhǔn)性能 目前缺少標(biāo)準(zhǔn)的數(shù)據(jù) 大多數(shù)同學(xué)都存在感性的認(rèn)識(shí) 有人認(rèn)為 QPS就是PHP的極限了 此外 對(duì)于框架的性能和框架對(duì)性能的影響很沒有響應(yīng)的權(quán)威數(shù)字
本章節(jié)的目的是給出一個(gè)基準(zhǔn)的參考性能指標(biāo) 通過數(shù)據(jù)給大家一個(gè)直觀的了解
具體的基準(zhǔn)性能有以下幾個(gè)方面
裸PHP性能 完成基本的功能
裸框架的性能 只做最簡(jiǎn)單的路由分發(fā) 只走通核心功能
標(biāo)準(zhǔn)模塊的基準(zhǔn)性能 所謂標(biāo)準(zhǔn)模塊的基準(zhǔn)性能 是指一個(gè)具有完整服務(wù)模塊功能的基準(zhǔn)性能
環(huán)境說明
測(cè)試環(huán)境
Uname aPnux db forum test db baidu _ # SMP Wed Aug : : CST x _ x _ x _ GNU/Pnux
Red Hat Enterprise Pnux AS release (Nahant Update )
Intel(R) Xeon(R) CPU?????????? E ? @ GHz
軟件相關(guān)
Nginx nginx version: nginx/ ? built by gcc (Red Hat )
Php (采用php fpm)
PHP (cP) (built: Mar? : : )
Copyright (c) The PHP Group
Zend Engine v Copyright (c) Zend Technologies
with eAccelerator v Copyright (c) eAccelerator by eAccelerator
bingo
PHP框架
其他說明
目標(biāo)機(jī)器的部署方式 nginx php fpm php腳本
測(cè)試壓力機(jī)器和目標(biāo)機(jī)器獨(dú)立部署
裸PHP性能
最簡(jiǎn)單的PHP腳本
?php
require_once?‘ /actions/indexAction php’;
$objAction?=?new?indexAction();
$objAction init();
$objAction execute();
?
Acitons/indexAction php里面的代碼如下
?php
class?indexAction
{
pubPc?function?execute()
{
echo?‘hello ?world!’;
}
}
?
通過壓力工具測(cè)試結(jié)果如下
裸PHP框架性能
為了和 的對(duì)比 基于bingo 框架實(shí)現(xiàn)了類似的功能 代碼如下
?php
require_once?‘Bingo/Controller/Front php’;
$objFrontController?=?Bingo_Controller_Front::getInstance(array(
‘a(chǎn)ctionDir’?=?‘ /actions’
));
$objFrontController dispatch();
壓力測(cè)試結(jié)果如下
從該測(cè)試結(jié)果可以看出 框架雖然有一定的消耗 但對(duì)整體的性能來說影響是非常小的
標(biāo)準(zhǔn)PHP模塊的基準(zhǔn)性能
所謂標(biāo)準(zhǔn)PHP模塊 是指一個(gè)PHP模塊所必須要具體的基本功能
路由分發(fā)
自動(dòng)加載
LOG初始化Notice日志打印 所以的UI請(qǐng)求都一條標(biāo)準(zhǔn)的日志
錯(cuò)誤處理
時(shí)間校正
自動(dòng)計(jì)算每個(gè)階段耗時(shí)開銷
編碼識(shí)別編碼轉(zhuǎn)化
標(biāo)準(zhǔn)配置文件的解析和調(diào)用
采用bingo 的代碼自動(dòng)生成工具產(chǎn)生標(biāo)準(zhǔn)的測(cè)試PHP模塊 test
測(cè)試結(jié)果如下
結(jié)論
從測(cè)試數(shù)據(jù)的結(jié)論來看 PHP本身的性能還是可以的 基準(zhǔn)性能完全能夠達(dá)到幾千甚至上W的QPS 至于為什么在大多數(shù)的PHP模塊中表現(xiàn)不佳 其實(shí)這個(gè)時(shí)候更應(yīng)該去找出系統(tǒng)的瓶頸點(diǎn) 而是簡(jiǎn)單的說OK PHP不行 那我們換C來搞吧 (下一個(gè)章節(jié) 會(huì)通過一些例子來對(duì)比 采用C來處理不見得有特 別的優(yōu)勢(shì))
通過基準(zhǔn)數(shù)據(jù) 可以得出以下幾個(gè)具體的結(jié)論
PHP本身性能也很不錯(cuò) 簡(jiǎn)單功能下能夠達(dá)到 QPS 極限也能過W
PHP框架本身對(duì)性能影響非常有限 尤其是在有一定業(yè)務(wù)邏輯和數(shù)據(jù)交互的情況下 幾乎可以忽略
一個(gè)標(biāo)準(zhǔn)的PHP模塊 基準(zhǔn)性能能夠達(dá)到 QPS( cpu idle)
對(duì)比分析
lishixinzhi/Article/program/PHP/201311/21287
?php
$conn
=
mysql_connect('localhost','root','')
or
die('連接數(shù)據(jù)庫(kù)失敗,請(qǐng)檢查您的數(shù)據(jù)庫(kù)配置');
?
mysql_connect第二個(gè)參數(shù)是用戶名,第三個(gè)參數(shù)
默認(rèn)情況下,用上面測(cè)試下,如果不行就看下面是密碼
?php
$conn
=
mysql_connect('localhost','用戶名','密碼')
or
die('連接數(shù)據(jù)庫(kù)失敗,請(qǐng)檢查您的數(shù)據(jù)庫(kù)配置');
?