• 欢迎访问伊栖物联网社区,聚焦物联网技术和解决方案QQ群:735553309
  • ,从传感器到片上嵌入式系统,无线接入,边缘计算,在这里您可以讨论一切
  • 参加最新的物联网研讨会报名
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏伊栖Eccee

web程序开发如何调试PHP代码?

软件和平台 wqsj 3年前 (2021-04-24) 1159次浏览 0个评论

在web开发中,PHP,Python,Ruby都是比较常见的开源语言工具,有很多开源的框架和平台可以使用,从效率来说,PHP无疑是一种最高效的web语言。但配置PHP开发调试环境并不容易。

开发调试的方法

PHP调试可分为使用PHP调试器和不用PHP调试器两种方式。前者是指用PHP debugger和IDE来进行断点调试,后者则是利用PHP的错误报告和浏览器等方式来进行调试。Xdebug和Zend Debugger是两种常用的调试器,但在使用调试器的方式,难点在于生产和测试环境的分离,以及调试器的安装配置。非调试器的方式则比较灵活,本文将探索不用PHP调试器的代码调试的方法,不论你是个人开发者还是生产环境的运维人员,都将受益于这次实战记录。

  • 使用PHP错误报告

当发现代码有错时,PHP引擎能生成非常有用的调试信息,可分为三大类:Error,Warning,Notice。举例来说:当有语法错误时,这将是个Error信息,当数据库连接不上时,这会是一个Warning信息,当变量名拼写错误等,这会是一个Notice信息。不过出于安全考虑,在生产环境中,你并不希望除你之外,还有其它用户可以看到这类信息。因此可以按下面方法处理 :

  1. 启用错语报告 :在php.ini中搜索error_reporting,设置为error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT ,这一般也是生产环境的默认设置
  2. 关闭全局的HTML错误输出  设置display_errors = Off 和 log_errors = On  这样不会在浏览器中看到PHP的错误报告,而是记录到php的log
  3. 使HTML错误输出仅自己看到,一般要用到运行时的ini_set()函数,有几种方法:

拷贝法: 复制一份代码到安全的测试环境,然后在要调试的文件中加入:


ini_set('display_errors', '1');

IP限制法: 可直接在生产环境中备份好原始代码,然后加入调试代码:


$myIP = '1.1.1.1'; 

/* Check the request IP address. */
if ($_SERVER['REMOTE_ADDR'] == $myIP)
{
/* Enable HTML error reporting. */
ini_set('display_errors', '1');
}

除此之外,还可以用指定用户法(可参见后续代码示例一并使用),或使用请求参数等方法配合init()在运行时显示仅自己可见的错误信息,这里不再敖述。

 

  • 调试代码变量

用echo打印变量

虽然错误报告能给代码语法错误的解决带来帮助,但我们更常用的是查看变量情况来修复代码,最简单的做法就是直接用echo打印变量,比如下面这个例子,当以debug用户访问页面时打印domain变量:

getName() == 'debug')
{
  /* Debugging. */
  echo $domain;
}

get_defined_vars()函数
echo的方式只适用于知道要检查哪个变量,有时我们需要检查脚本中的所有变量,这时可以用这个函数,它会返回所有已经定义的数组,例如

$addr = 'www.google.com';
$dotPos = mb_strpos($addr, '.');
$domainPos = $dotPos + 1;
$domain = mb_substr($addr, $domainPos);

/* Debug. */
echo '< pre>';
print_r(get_defined_vars());
echo '< /pre>;';

get_defined_vars函数显示用户定义的变量和系统变量,包括$_SERVER和web请求变量($_POST, $_GET…),这使得它成为非常强大的工具。上面的输出示例如下,出于可读性,我删除一些东西

Array
(
    [_GET] => Array
        (
        )

    [_POST] => Array
        (
        )

    [_COOKIE] => Array
        (
        )

    [_FILES] => Array
        (
        )

    [_REQUEST] => Array
        (
        )

    [_SERVER] => Array
        (
            [MIBDIRS] => C:/xampp/php/extras/mibs
            [MYSQL_HOME] => \xampp\mysql\bin
            [OPENSSL_CONF] => C:/xampp/apache/bin/openssl.cnf
            [PHP_PEAR_SYSCONF_DIR] => \xampp\php
            ....
            [PHP_SELF] => /test.php
            [REQUEST_TIME_FLOAT] => 1595999862.718
            [REQUEST_TIME] => 1595999862
        )

    [addr] => www.google.com
    [dotPos] => 3
    [domainPos] => 4
    [domain] => google.com
)

如果您需要调试的是某个函数或类,可以在该函数或类中调用,如:

function myFunction($arg1, $arg2, $arg3)
{
  $var1 = $arg1 + $arg2;
  $var2 = $arg1 * $arg2;
  $arrayVar = [$arg1, $arg2, $arg3, $var1, $var2];
  
  /* This prints all the variables in the current scope. */
  echo '< /pre>';
  print_r(get_defined_vars());
  echo '</pre>';
}

/* Call myFunction() */
myFunction(5, 10, 15);
  • 使用debug_backtrace()调试函数

这个方法会显示函数调用的全部历史,比如:

function f1(int $arg)
{
  $a = f2($arg + 1);
  $b = $a + 2;

  return $b;
}


function f2(int $arg)
{
  $a = f3($arg);
  $b = $a * 3;
  
  return $b;
}


function f3(int $arg)
{
  $a = $arg * 10;
  
  echo '< /pre>';
  print_r(debug_backtrace());
  echo '< /pre>';

return $a;
}

$val = f1(5);

上面f1里调用f2,f2里调用f3,f3处插入debug_backtrace,上面f1里调用f2,f2里调用f3,f3处插入debug_backtrace,返回的是一个数组,依次由后到前的函数调用,即先显示f3函数 ,再显示f2,再显示f1,如下所示:

Array
(
    [0] => Array
        (
            [file] => C:\xampp\htdocs\test.php
            [line] => 15
            [function] => f3
            [args] => Array
                (
                    [0] => 6
                )

        )

    [1] => Array
        (
            [file] => C:\xampp\htdocs\test.php
            [line] => 6
            [function] => f2
            [args] => Array
                (
                    [0] => 6
                )

        )

    [2] => Array
        (
            [file] => C:\xampp\htdocs\test.php
            [line] => 33
            [function] => f1
            [args] => Array
                (
                    [0] => 5
                )

        )

)

每个数组包括:
file:被调用函数所在的文件路径,如果函数是在include包含的文件,显示的是include文件的路径;
line:被调用函数所在行;
function:函数名称;
arg:函数参数;

您也可以使用 debug_print_backtrace()来替代debug_backtrace(),这样会更方便一些,例如:

function f3(int $arg)
{
  $a = $arg * 10;
  
  echo '< /pre>';
  debug_print_backtrace();
  echo '< /pre>';

return $a;
}

对应的输出结果是:

#0  f3(6) called at [C:\xampp\htdocs\test.php:15]
#1  f2(6) called at [C:\xampp\htdocs\test.php:6]
#2  f1(5) called at [C:\xampp\htdocs\test.php:33]
  • 记录debug数据

上面讲了如何在HTML输出中显示调试信息,下面说说如何记录这些数据到log文件中,调试数据log不仅可以长久保存,你也无需使用技巧以防止其它访客可以看到,并且还能记录特定用户的活动。
把调试数据写到log文件中,最简单的办法是用fopen()函数,如:

>
/* Open the log file. */
$handle = fopen('c:\xampp\debug.log', 'ab');

function addLog($handle, string $log)
{
/* Datetime to add at the beginning of the log line. */
$date = date('d/m/Y H:i:s');

/* Complete log line. */
$line = $date . ' ' . $log . "\n";

/* Add the new line to the log file. */
fwrite($handle, $line);
}

上面fopen第一个参数是log文件路径,第二个参数是标记符,”a”代表添加到文件尾,“b”防止自动新行。
当然,需要log文件所在路径允许php写入。

上面函数用法示例:

$addr = 'www.google.com';
$domain = mb_substr($addr, mb_strpos($addr, '.') + 1);

/* Log the $domain variable */
addLog($handle, 'domain is: ' . $domain);

或是记录前面说的get_defined_vars函数,打印的所有变量到log文件中,

付费查看内容

已有1人支付


ECCEE版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:web程序开发如何调试PHP代码?
喜欢 (1)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址