2

这个问题与我大约 15 分钟前提出的这个SO 问题直接相关。这并不是要成为该帖子的重复帖子,而是希望这更多是一种学习体验。

在提出的问题中,我试图找出导致 preg_match no deliminator found 错误的原因。代码(不是我的)可在此处获得。该错误最终成为 Windows 3.11 数组中缺少的“/i”。

重要的是要注意,为了这个问题,我使用浏览器部分。

第一个问题,理所当然地提出了 $regex 的价值是什么。但是,我仍然无法找到获得该值的方法。

我最初尝试的是在函数外部声明一个全局变量,并且在 preg_match 行之前将全局变量设置为正则表达式。然后我尝试回显全局变量。迎接我的是一个空白页。

我还应该提到我(在提出原始问题时)删除了这段代码:

$user_agent     =   getBrowserOS();
$device_details =   "<strong>Browser: </strong>".$user_agent['browser']."<br />    <strong>Operating System: </strong>".$user_agent['os_platform']."";
print_r($device_details);
echo("<br /><br /><br />".$_SERVER['HTTP_USER_AGENT']."");

因此我唯一应该看到的是全局变量的值。相反,我什么也没看到。

有人可以解释这应该如何调试吗?

编辑:根据 John C 的回答

<?php
$user_agent     =   $_SERVER['HTTP_USER_AGENT'];
function getOS() { 
global $user_agent;
$os_platform    =   "Unknown OS Platform";
$os_array       =   array(
                        '/windows nt 6.2/i'     =>  'Windows 8',
                        '/windows nt 6.1/i'     =>  'Windows 7',
                        '/windows nt 6.0/i'     =>  'Windows Vista',
                        '/windows nt 5.2/i'     =>  'Windows Server 2003/XP x64',
                        '/windows nt 5.1/i'     =>  'Windows XP',
                        '/windows xp/i'         =>  'Windows XP',
                        '/windows nt 5.0/i'     =>  'Windows 2000',
                        '/windows me/i'         =>  'Windows ME',
                        '/win98/i'              =>  'Windows 98',
                        '/win95/'               =>  'Windows 95',
                        '/win16'                =>  'Windows 3.11',
                        '/macintosh|mac os x/i' =>  'Mac OS X',
                        '/mac_powerpc/i'        =>  'Mac OS 9',
                        '/linux/i'              =>  'Linux',
                        '/ubuntu/i'             =>  'Ubuntu',
                        '/iphone/i'             =>  'iPhone',
                        '/ipod/i'               =>  'iPod',
                        '/ipad/i'               =>  'iPad',
                        '/android/i'            =>  'Android',
                        '/blackberry/i'         =>  'BlackBerry',
                        '/webos/i'              =>  'Mobile'
                    );

foreach ($os_array as $regex => $value) { 
var_dump($regex);
var_dump($value);
    if (preg_match($regex, $user_agent)) {
        $os_platform    =   $value;
    }

}   
return $os_platform;
}
?>
4

1 回答 1

3

我将尝试专注于这个实例而不是一般调试,因为我确信有更好的指南可以帮助您入门。

1.查看错误信息。 大多数时候,PHP 在告诉你哪里出了问题和哪里(在几行之内)方面并不算太差。在这种情况下,你会有一些类似的东西

Warning: preg_match() [function.preg-match]: No ending delimiter '/' found in /var/www/html/whatever.php on line 36

所以问题是第 36 行缺少斜线。第 36 行(属于getOS()):

if (preg_match($regex, $user_agent)) {

我们可以推断这是 $regex 的问题 - 在这种情况下,快速查看有问题的数组会发现/其中一行缺失,但可能数据在数据库中或无法轻松检查。

2. 开始转储变量 如果有什么不对劲的地方,检查你的变量是一个好的开始。您希望尽可能接近错误地执行此操作,这样您就知道两者之间没有发生任何事情。我们知道问题$regex出在上面,所以就在问题行的上方:

var_dump($regex);
if (preg_match($regex, $user_agent)) {

新结果:

...
string '/win95/' (length=7)
string '/win16' (length=6)

Warning: preg_match() [function.preg-match]: No ending delimiter '/' found in /var/www/html/whatever.php on line 36

一旦我们得到错误,PHP 就会停止,所以最后转储的行将显示问题变量。你好,一个缺少斜杠的正则表达式!

关于您的方法: PHP 在遇到错误时会停止,这就是为什么我建议尽可能接近问题转储变量的部分原因。在您的情况下,脚本从未达到您的回声语句。

奖金笔记!

  • I prefer var_dump() for checking variables because it is better at showing an empty/null variable (echo will just print a blank) plus it handles arrays and objects.
  • If you find yourself doing a lot of debugging, have a look at getting XDebug running. Immensely useful.
于 2012-07-05T01:25:12.417 回答