echo
声明で考慮すべき点は次の 3 つです。
$name
は、HTMLの属性の JavaScript 内に文字列リテラルとして埋め込む文字列onclick
であるため、関数に渡す場所では、postMeet
引用符で囲む必要があります。JavaScript では、バランスが取れている限り、文字列リテラルを'
またはで引用できます。で属性を"
引用しているため (HTML では が許可されていないため)、 JavaScript 文字列を区切るのに最も簡単に使用できます。だから:それを置きます。onclick
"
'
'
'
postMeet
呼び出しは HTML 属性 ( ) 内にあります。onclick
これは、マークアップが読み取られるときに HTML テキストとして読み取られることを意味します。したがって、HTML にとって特別な文字 (たとえば、主に<
と&
、この場合は属性の区切り文字として"
使用しているため) は、、 、として正しくエンコードされていることを確認する必要があります。PHP には、そのための関数が用意されています。多分あなたは考えているかもしれません。それがバグが現れる方法です。これらを完全にエンコードする習慣を身につければ、もっと興味深いものを出力しているときを忘れることはありません。その上、人々はデータベースの「名前」フィールドにあらゆる種類のナンセンスを入力します。"
onclick
<
&
"
htmlspecialchars
$name
<
JavaScript 文字列リテラル内では、バックスラッシュと、文字列を区切るために使用したあらゆる種類の引用符 ('
または など"
)を(バックスラッシュで) エスケープする必要があります。したがって、何が入っているか、さらにはそれ以上のことを考慮し$name
、完全に防御する必要があります。文字列リテラル'T.J. Crowder'
は有効ですが、 inがエスケープされていない'Gerard 't Hooft'
ため、文字列リテラルは構文エラーになります。(二重引用符で区切る) または(単一引用符をエスケープする) のいずれかで記述する必要があります。PHP には、、、、および null バイトの前にバックスラッシュを挿入する便利な関数 が用意されています。'
't Hooft
"Gerard 't Hooft"
'Gerard \'t Hooft'
addslashes
'
"
\
これらをすべてまとめると、変数の値を に出力するときに何らかの引用符で囲むpostMeet
必要があり、特別な HTML 文字をエンコードする必要があり、引用符などをバックスラッシュでエスケープする必要があります。
// +--- start string literal with single quote
// |
// vv
onclick="postMeet(\''. addslashes(htmlspecialchars($name)) .'\')"
// ^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^
// | | |
// escape ", ', and \ -----+ | |
// encode special HTML chars --+ |
// end literal with single quote ---------+
例えば:
echo('
<li>
<a href="#" onclick="window.open(\'http://www.facebook.com/' . $id . '\')">
<img src="https://graph.facebook.com/' . $id . '/picture?type=square" alt="' . $name . '">'. $name . '
</a>
<form>
<input type="button" value="Meet" onclick="postMeet(\''. addslashes(htmlspecialchars($name)) .'\')"/>
</form>
</li>');
解釈の 3 つの層が進行していることを覚えておくことが重要です。PHP は PHP コードを解釈し、マークアップを HTML ページに出力します。onclick
ブラウザは、属性のコンテンツを含む HTML マークアップを解釈しています。JavaScript インタープリターは、onclick
有効な JavaScript コードである必要がある属性の文字列コンテンツを解釈します (クリックが発生したときにブラウザーがそれを渡します)。
簡単にコピーしてテスト ページに貼り付けることができる、より分離された例を次に示します。テスト ページで「ソースを表示」を使用して、ブラウザーが何を表示したかを確認します。もちろん、 をクリックしdiv
て、すべてが正しく機能することを確認します。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>PHP Escape Test</title>
</head>
<body>
<?php
$stuff = "Gerard 't Hooft says <<\"theoretical physics is FUN & a great way to aid humankind!\">>";
echo('<div onclick="foo(\'' . addslashes(htmlspecialchars($stuff)) . '\')">Click me</div>');
?>
<script>
function foo(stuff) {
alert(stuff);
}
</script>
</body>
</html>