2

この質問は、私が約15分前に提起したこのSO質問に直接関連しています。これは、その投稿の複製を意図したものではなく、より多くの学習体験になることを願っています。

提起された質問では、preg_matchnodeliminatorがエラーを検出しなかった原因を突き止めようとしていました。コード(私のものではありません)はここから入手できます。エラーは、Windows3.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']."");

したがって、私が見るべきだったのは、グローバル変数の値だけでした。代わりに、私は何も見ませんでした。

誰かがこれをどのようにデバッグすべきか説明できますか?

編集:ジョン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の問題であると推測できます。この場合、問題の配列をざっと見ると/、行の1つが欠落していることがわかりますが、データがデータベースにあるか、簡単に確認できない可能性があります。

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はエラーが発生すると停止します。これが、問題にできるだけ近い変数をダンプすることをお勧めする理由の1つです。あなたの場合、スクリプトはエコーステートメントまで到達しませんでした。

ボーナスノート!

  • var_dump()空/null変数(echoは空白を出力するだけです)を表示するのに優れているだけでなく、配列とオブジェクトを処理するため、変数のチェックを好みます。
  • 多くのデバッグを行っていることに気付いた場合は、 XDebugを実行する方法を確認してください。非常に便利です。
于 2012-07-05T01:25:12.417 に答える