php調試信息
A. 如何調試php的Core之獲取基本信息
首先, 讓生成一個供舉例子的Core文件: <?phpfunction recurse($num) { recurse(++$num);} recurse(0); 運行這個PHP文件: $ php test.phpSegmentation fault (core mped) 這個PHP因為無線遞歸, 會導致爆棧, 從而造成 segment fault而在PHP的當前工作目錄產生Coremp文件(如果你的系統沒有產生Coremp文件, 那請查詢ulimit的相關設置). 好, 現在, 讓刪除掉這個test.php, 忘掉上面的代碼, 我們現在僅有的是這個Core文件, 任務是, 找出這個Core產生的原因, 以及發生時候的狀態. 首先, 讓用gdb打開這個core文件: $ gdb php -c core.31656 會看到很多的信息, 首先讓我們注意這段: Core was generated by `php test.php'.Program terminated with signal 11, Segmentation fault. 他告訴我們Core發生的原因:」Segmentation fault」. 一般來說, 這種Core是最常見的, 解引用空指針, double free, 以及爆棧等等, 都會觸發SIGSEGV, 繼而默認的產生Coremp. 現在讓看看Core發生時刻的堆棧: #0 execute (op_array=0xdc9a70) at /home/laruence/package/php-5.2.14/Zend/zend_vm_execute.h:5353 memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);(gdb) bt#0 execute (op_array=0xdc9a70) at /home/laruence/package/php-5.2.14/Zend/zend_vm_execute.h:53#1 0x00000000006ea263 in zend_do_fcall_common_helper_SPEC (execute_data=0x7fbf400210) at /home/laruence/package/php-5.2.14/Zend/zend_vm_execute.h:234#2 0x00000000006e9f61 in execute (op_array=0xdc9a70) at /home/laruence/package/php-5.2.14/Zend/zend_vm_execute.h:92#3 0x00000000006ea263 in zend_do_fcall_common_helper_SPEC (execute_data=0x7fbf400440) at /home/laruence/package/php-5.2.14/Zend/zend_vm_execute.h:234#4 0x00000000006e9f61 in execute (op_array=0xdc9a70) at /home/laruence/package/php-5.2.14/Zend/zend_vm_execute.h:92#5 0x00000000006ea263 in zend_do_fcall_common_helper_SPEC (execute_data=0x7fbf400670) at /home/laruence/package/php-5.2.14/Zend/zend_vm_execute.h:234..... 不停的按回車, 可以看到堆棧很深, 不停的是zend_do_fcall_common_helper_SPEC和execute的重復, 那麼這基本就能斷定是因為產生了無窮大的遞歸(不能一定說是無窮遞歸, 比如之前文章中介紹深悉正則(pcre)最大回溯/遞歸限制). 從而造成爆棧產生的Core. Ok, 那麼現在讓看看, Core發生在PHP的什麼函數中, 在PHP中, 對於FCALL_* Opcode的handler來說, execute_data代表了當前函數調用的一個State, 這個State中包含了信息: (gdb)f 1#1 0x00000000006ea263 in zend_do_fcall_common_helper_SPEC (execute_data=0x7fbf400210) at /home/laruence/package/php-5.2.14/Zend/zend_vm_execute.h:234234 zend_execute(EG(active_op_array) TSRMLS_CC);(gdb) p execute_data->function_state.function->common->function_name$3 = 0x2a95b65a78 "recurse"(gdb) p execute_data->function_state.function->op_array->filename$4 = 0x2a95b632a0 "/home/laruence/test.php"(gdb) p execute_data->function_state.function->op_array->line_start$5 = 2 現在我們得到, 在調用的PHP函數是recurse, 這個函數定義在/home/laruence/test.php的第二行 經過重復驗證幾個frame, 可以看出, 一直是在重復調用這個PHP函數. 要注意的是, 為了介紹查看執行信息的原理, 我才採用原生的gdb的print來查看, 其實我們還可以使用PHP源代碼中提供的.gdbinit(gdb命令編寫腳本), 來簡單的獲取到上面的信息: (gdb) source /home/laruence/package/php-5.2.14/.gdbinit(gdb) zbacktrace[0xbf400210] recurse() /home/laruence/test.php:3[0xbf400440] recurse() /home/laruence/test.php:3[0xbf400670] recurse() /home/laruence/test.php:3[0xbf4008a0] recurse() /home/laruence/test.php:3[0xbf400ad0] recurse() /home/laruence/test.php:3[0xbf400d00] recurse() /home/laruence/test.php:3[0xbf400f30] recurse() /home/laruence/test.php:3[0xbf401160] recurse() /home/laruence/test.php:3..... 關於.gdbinit, 是一段小小的腳本文件, 定義了一些方便我們去調試PHP的Core, 大家也可以用文本編輯器打開, 看看裡面定義的一些快捷的命令, 一般來說, 我常用的有: zbacktraceprint_ht**系列zmemcheck OK, 回歸正題, 我們現在知道, 問題發生在/home/laruence/test.php的recurse函數的遞歸調用上了. 現在, 讓我們來看看, 在調用這個函數的時候的參數是什麼? PHP的參數傳遞是依靠一個全局Stack來完成的, 也就是EG(argument_stack), EG在非多線程情況下就是executor_globals, 它保持了很多執行狀態. 而argument_statck就是參數的傳遞棧, 保存著對應PHP函數調用層數相當的調用參數. 要注意的是, 這個PHP函數調用堆棧(層數)不和gdb所看到的backtrace簡單的一一對應, 所以參數也不能直接和gdb的backtrace對應起來, 需要單獨分析: //先看看, 最後一次函數調用的參數數目是多少(gdb) p (int )*(executor_globals->argument_stack->top_element - 2)$13 = 1 //再看看, 最後一次函數調用的參數是什麼(gdb) p **(zval **)(executor_globals->argument_stack->top_element - 3)$2 = {value = {lval = 22445, dval = 1.1089303420906779e-319, str = {val = 0x57ad <Address 0x57ad out of bounds>, len = 7}, ht = 0x57ad, obj = {handle = 22445, handlers = 0x7}}, refcount = 2, type = 1 '\001', is_ref = 0 '\0'} 好, 我們現在得到, 最後一次調用的參數是一個整數, 數值是22445 到了這一步, 我們就得到了這個Core發生的時刻的PHP層面的相關信息, 接下來, 就可以交給對應的PHP開發工程師來排查, 這個參數下, 可能造成的無窮大遞歸的原因, 從而修復這個問題..
B. phpstorm 中是怎樣調試PHP
## 配置到php
1. 打開php.ini文件
```bash
cd /private/etc/
#默認沒有php.ini,需要拷貝一下
sudo cp php.ini.default php.ini
sudo vi php.ini
```
2. 在下面加入
```bash
[Xdebug]
zend_extension="/usr/local/php_user/xdebug.so"
xdebug.remote_enable = on
;xdebug.remote_handler=dbgp
xdebug.remote_host="127.0.0.1"
xdebug.remote_port=9000
xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = off
xdebug.profiler_output_name = cachegrind.out.%t.%p
xdebug.remote_autostart = on
```
3. 重啟`apache`
```bash
sudo apachectl restart
```
4. 查看phpinfo()信息裡面搜索一下`debug`如果有,你成功了。
## 配置phpstorm
1. 打開phpstorm,進入頂部導航`phpstrom->perferences..`
2. 點擊`php`項,點擊`interpreter`後面的`...`按鈕
3. 點擊`php home`後面的刷新(`...`後面)按鈕
4. 這時候你將看到`Debugger: Not installed`變成`Xdebug 2.3.2`(版本號可能不同)
6. 進入`php`欄目下的`Server`,點擊`+`新建一個server:host填寫你本地的host(如127.0.0.1),點擊`apply`保存,並退出`perferences`對話框。
7. 點擊頂部導航`run`->點擊`+`->選擇`PHP Web Application`->選擇上一步新建的`server`,`start URL`填入,你要debug的php文件地址,下面會生成一個地址,這個地址在瀏覽器應該能正常瀏覽測試的;點擊`apply`進行保存。
## 開始愉快的使用
1. 在你要debug的文件行數字右側一列,點擊一下就會有一個斷點。
2. 點擊頂部導航`run`->debug,選擇你剛剛新建的`debug`名稱,這時候會彈出瀏覽器載入這個php文件了。
C. thinkphp怎麼開啟調試模式
thinkphp開啟調試模式的方法:
1、開啟調試模式,首先在入口文件打開調試開關:
//開啟調試模式
define('APP_DEBUG',true);
2、然後需要配置調試文件,該文件位於項目配置目錄下,默認名字為 debug.php:
<?php
return array(
// 開發環境配置信息
'DB_TYPE' =>'mysql',
'DB_HOST' =>'localhost',
'DB_NAME' =>'mydb',
'DB_USER' =>'root',
'DB_PWD' =>'root123',
'DB_PORT' =>'3306',
'DB_PREFIX' =>'my_',
);
?>
配置完調試配置文件之後,調試模式就配置成功了。
3、在 Index 模塊的 index 操作寫入如下測試代碼:
public function index(){
$Dao = M('User');
$user_list = $Dao->select();
$this->display();
}
4、在頁面上雖然沒有做任何邏輯輸出,但是卻有系統調試信息,下面是頁面 Trace 信息截圖:
D. 如何優雅的輸出PHP調試信息
不知道你是什麼意思,要調試顯示一個數組有很多方法。最簡單的就是直接將它mp出來。 tp把php的var_mp封裝成了mp,這兩個函數都可以使用。 mp($data); var_mp($data); 都可以
E. phpstorm 中是怎樣調試PHP
#在mac上用phpstorm里debug調試php
## 背景
最近為了完成某個需求,在看`smarty`源碼,當我嘗試直接看,痛苦的快吐血,工欲善其事必先利器,雖然之前一直使用phpstorm調試nodejs,但是還沒有用phpstorm來debug過php。
## 建議
先看看這個:PhpStorm 8.0.2 Help :: Configuring Xdebug
## 安裝xdebug
1. 打開:Xdebug: Downloads 點擊source來下載源碼包
2. 然後安裝
```bash
#解壓tar包
tar -xzf xdebug-2.2.5.tgz
#進入根目錄
cd xdebug-2.2.5
#執行phpize
phpize
#編譯安裝xdebug
./configure --enable-xdebug
make
make install
```
## 配置到php
1. 打開php.ini文件
```bash
cd /private/etc/
#默認沒有php.ini,需要拷貝一下
sudo cp php.ini.default php.ini
sudo vi php.ini
```
2. 在下面加入
```bash
[Xdebug]
zend_extension="/usr/local/php_user/xdebug.so"
xdebug.remote_enable = on
;xdebug.remote_handler=dbgp
xdebug.remote_host="127.0.0.1"
xdebug.remote_port=9000
xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = off
xdebug.profiler_output_name = cachegrind.out.%t.%p
xdebug.remote_autostart = on
```
3. 重啟`apache`
```bash
sudo apachectl restart
```
4. 查看phpinfo()信息裡面搜索一下`debug`如果有,你成功了。
## 配置phpstorm
1. 打開phpstorm,進入頂部導航`phpstrom->perferences..`
2. 點擊`php`項,點擊`interpreter`後面的`...`按鈕
3. 點擊`php home`後面的刷新(`...`後面)按鈕
4. 這時候你將看到`Debugger: Not installed`變成`Xdebug 2.3.2`(版本號可能不同)
6. 進入`php`欄目下的`Server`,點擊`+`新建一個server:host填寫你本地的host(如127.0.0.1),點擊`apply`保存,並退出`perferences`對話框。
7. 點擊頂部導航`run`->點擊`+`->選擇`PHP Web Application`->選擇上一步新建的`server`,`start URL`填入,你要debug的php文件地址,下面會生成一個地址,這個地址在瀏覽器應該能正常瀏覽測試的;點擊`apply`進行保存。
## 開始愉快的使用
1. 在你要debug的文件行數字右側一列,點擊一下就會有一個斷點。
2. 點擊頂部導航`run`->debug,選擇你剛剛新建的`debug`名稱,這時候會彈出瀏覽器載入這個php文件了。
作者:匿名用戶
鏈接:https://www.hu.com/question/20880724/answer/45008887
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。
F. php非同步調試和線上調試網站程序
php非同步調試和線上調試網站程序
php非同步調試和線上調試網站程序既方便網站程序錯誤調試,又不影響網站的正常運行的調試方法。下面是我為大家帶了的php非同步調試和線上調試網站程序,歡迎閱讀。
php非同步調試和線上調試網站程序
代碼如下
//ini_set('error_reporting',E_ALL ^ E_NOTICE);//顯示所有除了notice類型的錯誤信息
ini_set('error_reporting',E_ALL);//顯示所有錯誤信息
ini_set('display_errors',off);//禁止將錯誤信息輸出到輸出端
ini_set('log_errors',On);//開啟錯誤日誌記錄
ini_set('error_log','C:/phpernote');//定義錯誤日誌存儲位置
另外附加兩句比較常用的排除錯誤信息的PHP語句:
代碼如下
@ini_set('memory_limit','500M');//設置程序可佔用最大內存為500MB
@ini_set('max_execution_time','180');//設置允許程序最長的執行時間為180秒
補充
die()和exit()也是我們常用的php調試一個方法
die()和exit()函數都有終止線程的作用,是php斷點調試需要使用的最主要的函數,它們也是php程序員使用非常頻繁的函數。然而兩者又有什麼區別呢?在程序調試時需要注意什麼問題呢?
die()函數一般與「or」一並使用,寫作「or die()」,經常看到這樣的語句:
代碼如下
$file = fopen($filename, 'r') or die("抱歉,無法打開: $filename")
or在這里是這樣理解的,因為在PHP中並不區分數據類型,所以$file既可以是int也可以bool,所以這樣的語句不會報錯。但其處理過程可能有些朋友不大明白。其實在大多數的語言中, bool or bool這樣的語句中,如果前一個值為真後一個值就不會再判斷了。這里也是的,所以如果fopen函數執行正確的話,會返回一個大於0的int值(這其實就是"真"),後面的語句就不會執行了。如果fopen函數執行失敗,就會返回false,那麼就會判斷後面的表達式是否為真了。結果執行了die()之後,不管返回什麼,程序都已經停止執行了,並且顯示指定的.出錯信息,也就達到了調試的目的。就這樣。
實際上,die和exit是等價的,都是用來終止當前腳本。
php手冊對兩者的解釋如是說:
exit() 函數輸出一條消息,並退出當前腳本。該函數是 die() 函數的別名。
die() 函數輸出一條消息,並退出當前腳本。該函數是 exit() 函數的別名。
實例:
代碼如下
<?php $site = "http://www.111cn.net/"; fopen($site,"r") or exit("Unable to connect to $site"); ?>
<?php $site = "http://www.111cn.net/"; fopen($site,"r") or die("Unable to connect to $site"); ?>
var_mp()和print_r()
var_mp -- 列印變數的相關信息
void var_mp ( mixed expression [, mixed expression [, ...]] )
此函數顯示關於一個或多個表達式的結構信息,包括表達式的類型與值。數組將遞歸展開值,通過縮進顯示其結構。
提示: 為了防止程序直接將結果輸出到瀏覽器,可以使用輸出控制函數(output-control functions)來捕獲此函數的輸出,並把它們保存到一個例如 string 類型的變數中。
代碼如下
<?php
$a = array (1, 2, array ("a", "b", "c"));
var_mp ($a);
$b = 3.1;
$c = TRUE;
var_mp($b,$c);
?>
var_mp()可以輸出多個變數,如:var_mp($b,$c)
print_r -- 列印關於變數的易於理解的信息
bool print_r ( mixed expression [, bool return] )
注: 參數 return 是在 PHP 4.3.0 的時候加上的
print_r() 顯示關於一個變數的易於理解的信息。如果給出的是 string、integer 或 float,將列印變數值本身。如果給出的是 array,將會按照一定格式顯示鍵和元素。object 與數組類似。
記住,print_r() 將把數組的指針移到最後邊。使用reset() 可讓指針回到開始處。
代碼如下
<pre>
<?php
$a = array ('a' => 'apple',
'b' => 'banana',
'c' => array ('x','y','z'));
print_r ($a);
?>
</pre>
上邊的代碼將輸出:
<pre> Array ( [a] => apple [b] => banana [c] => Array ( [0] => x [1] => y [2] => z ) ) </pre>
如果想捕捉 print_r() 的輸出,可使用 return 參數。若此參數設為 TRUE,print_r() 將不列印結果(此為默認動作),而是返回其輸出。
例子:return 參數示例
代碼如下
<?php
$b = array ('m' => 'monkey',
'foo' => 'bar',
'x' => array ('x', 'y', 'z'));
$results = print_r ($b, true); //$results 包含了 print_r 的輸出結果
?>
注: 如果想在 PHP 4.3.0 之前的版本中捕捉 print_r() 的輸出,可使用輸出控制函數。
注: 在 PHP 4.0.4 之前的版本中,如果給出的 array 或 object 包含了直接或間接指向自身的引用,print_r() 將永遠繼續下去。print_r($GLOBALS) 就是一個例子,因為 $GLOBALS 自身即是全局變數,其包含了指向自身的引用。
下面的幾個函數可以讓你隨時查看程序中任何變數的類型及其值。
代碼如下
function ss_array_as_string (&$array, $column = 0) {
$str = "Array(
n";
while(list($var, $val) = each($array)){
for ($i = 0; $i < $column+1; $i++){
$str .= "&nbsp;&nbsp;&nbsp;&nbsp;";
}
$str .= $var. ==>; ;
$str .= ss_as_string($val, $column+1)."
n";
}
for ($i = 0; $i < $column; $i++){
$str .= "&nbsp;&nbsp;&nbsp;&nbsp;";
}
return $str.);
}
function ss_object_as_string (&$object, $column = 0) {
if (empty($object->;classname)) {
return "$object";
}
else {
$str = $object->;classname."(
n";
while (list(,$var) = each($object->;persistent_slots)) {
for ($i = 0; $i < $column; $i++){
$str .= "&nbsp;&nbsp;&nbsp;&nbsp;";
}
global $$var;
$str .= $var. ==>; ;
$str .= ss_as_string($$var, column+1)."
n";
}
for ($i = 0; $i < $column; $i++){
$str .= "&nbsp;&nbsp;&nbsp;&nbsp;";
}
return $str.);
}
}
function ss_as_string (&$thing, $column = 0) {
if (is_object($thing)) {
return ss_object_as_string($thing, $column);
}
elseif (is_array($thing)) {
return ss_array_as_string($thing, $column);
}
elseif (is_double($thing)) {
return "Double(".$thing.")";
}
elseif (is_long($thing)) {
return "Long(".$thing.")";
}
elseif (is_string($thing)) {
return "String(".$thing.")";
}
else {
return "Unknown(".$thing.")";
}
}
G. 怎麼優雅的輸出PHP調試信息
利用瀏覽器調試模式的Console
1,先定義一個php函數:
functionconsole($log='')
{
switch(empty($log)){
caseFalse:
$out=json_encode($log);
$GLOBALS['console'].='console.log('.$out.');';
break;
default:
echo'<scripttype="text/javascript">'.$GLOBALS['console'].'</script>';
}
}
2,在需要調試的地方直接調用它,遞交的參數可以是字元串,也可以是數組。
3,在適當的位置調用無參數的console,用來輸出調試信息,比如各類php框架入口文件的最底部
4,打開瀏覽器(比如chrome),載入頁面後進入調試模式(比如按F12鍵),點擊Console,你會發現所有數據都在這里等著你查閱。
5,其他用途
優秀的PHP開源框架ThinkPHP提供了輸出運行狀態的功能,你可以通過運行狀態來了解某個頁面在後台處理了多長時間。但是,很多人都注意到了,它是不準確的。
下面我們試著用剛剛加進來的自定義函數console在瀏覽器中輸出真正的運行時間。
所有工作都在入口文件中完成:
在所有代碼的最開頭,定義變數$s=microtime(true);
在console();的上面再增加console('exetime:'.round(microtime(true)-$s,4));
H. php websocket 如何調試bug哪裡查看報錯信息,var_mp哪裡看
要配置php.ini
xdebug.var_display_max_depth = 10xdebug.var_display_max_children = 256xdebug.var_display_max_data = 1024 ; with no limits
; (maximum nesting is 1023)
xdebug.var_display_max_depth = -1 xdebug.var_display_max_children = -1xdebug.var_display_max_data = -1
I. php如何單步調試
PHP本就是腳本語言,程序執行就是「單線程」。
要測試節點或者邏輯是否正確的話,只需要在你需要測試的節點echo一下信息,還可以file_put_contents()寫入日誌信息。
這樣程序執行的基本流程就可以了,這時候就可以判斷,你程序的節點邏輯是否執行正確。
J. 常用的PHP調試工具有哪些
Pinba:是個開源的 MySQL 存儲引擎,主要任務是幫助 web 開發者監控所有 PHP
腳本的性能。使用 MySQL 作為只讀介面,作為一個 PHP 的實時監控伺服器。PHP Dyn:是個令人驚奇的擴展,幫助調試 PHP
腳本。它的主要是能跟蹤執行腳本,也是一款提供給 PHP 開發者的開源軟體。Kint:是另一個調試 PHP 腳本的最好的調試工具,非常容易使用,強大,而且 PHP 的
web 開發者可以隨意定製。PHP MD:可以從源代碼中找到錯誤,並且使用一系列有限的定義規則就可以輕松解決問題。
PHP Debug Bar:是另一個非常棒的 PHP 調試工具,可以顯示
web 應用的 pst 數據。Whoops:是個更高效的 PHP
調試庫,幫助開發者構建和維護他們的項目,使其做得更好。Whoops 也是個開源軟體,有著許多傑出的特性。Xdebug:是提供給 PHP
用戶的一個擴展,有著許多高級的特性,每一時刻都有不同類型的更新。Krumo:是 PHP 調試工具的傑出代表,可以顯示任意的 PHP 變數的結構信息。