В вашем выражении echo
необходимо учесть три вещи:
$name
- это строка, которую вы собираетесь встроить как строковый литерал внутри JavaScript в атрибуте onclick
вашего HTML, поэтому при передаче его в функцию postMeet
вы должны заключать в кавычки.JavaScript позволяет заключать строковые литералы в кавычки либо '
, либо "
, если они сбалансированы.Поскольку мы цитируем атрибут onclick
с помощью "
(поскольку HTML не допускает '
), проще всего использовать '
для разграничения строки JavaScript.Итак: поместите вокруг него '
.
Вызов postMeet
находится внутри атрибута HTML (onclick
), что означает, что когда читается разметка, она читается какHTML текст.Следовательно, вы должны убедиться, что любые символы, которые являются специальными для HTML (например, в основном <
и &
, плюс в этом случае "
, потому что вы использовали "
в качестве разделителя для вашего атрибута onclick
)правильно кодируются как <
, &
и "
.PHP предоставляет функцию htmlspecialchars
для этого.Может быть, вы думаете "но $name
никогда не будет иметь <
в нем".Вот как появляются ошибки.Привыкайте полностью кодировать эти вещи, и вы не забудете, когда будете выводить что-то более интересное.Кроме того, люди заполняют всякую ерунду для поля «имя» в базах данных.
Внутри строкового литерала JavaScript, обратной косой черты и любых других кавычек, которые вы использовали для разделения строкинапример, '
или "
) должен быть экранирован (с обратной косой чертой).Поэтому вы должны подумать о том, что может быть в $name
или, что еще лучше, полностью защитить себя.Строковый литерал 'T.J. Crowder'
является допустимым, но строковый литерал 'Gerard 't Hooft'
приводит к синтаксической ошибке, поскольку '
в 't Hooft
не экранируется.Он должен быть написан либо "Gerard 't Hooft"
(разделение двойными кавычками), либо 'Gerard \'t Hooft'
(экранирование одинарной кавычки).PHP предоставляет удобную функцию, 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>');
Важно помнить, что происходит три уровня интерпретации: PHP интерпретирует ваш код PHP и выводит разметку на страницу HTML;браузер интерпретирует разметку HTML, включая содержимое атрибута onclick
;а интерпретатор JavaScript интерпретирует строковое содержимое атрибута onclick
(браузер передает его при щелчке), который должен быть допустимым кодом JavaScript.
Вот более изолированный пример, который легко скопировать и вставитьна тестовую страницу.Используйте «View Source» на тестовой странице, чтобы увидеть то, что увидел браузер, и, конечно, нажмите 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>