我如何使用 PHP 对包含引号的字符串进行编码以使其对于内联 'onclick' 是安全的?

How do I use PHP to encode a string containing quotes to make it safe for inline 'onclick'?

我在数据库中有一个可能包含单引号或双引号的变量。当我从数据库中检索变量时,它用 PHP 写入内联 "onclick" 处理程序:

echo '<li><a onClick="a4e.duplicate_assignment('.$this_assignment['id'].',\''.htmlspecialchars($this_assignment['title'],ENT_QUOTES).'\',\'/assignments/'.$type.'/\');" href="javascript:void(0);">';echo '<i class="fa fa-copy"></i> Duplicate assignment</a></li>';

这会产生 HTML 在页面源代码中看起来像这样:

<li><a onClick="a4e.duplicate_assignment(92,'ELLLO - &#039;If I had a million dollars&#039;','/assignments/cloze/');" href="javascript:void(0);"><i class="fa fa-copy"></i> Duplicate assignment</a></li>

但是,单击 link 会在控制台中产生以下错误:

Uncaught SyntaxError: missing ) after argument list

我认为使用 PHP 函数 "htmlspecialchars" 可以缓解这个问题,但它似乎不起作用。

非常感谢任何帮助。

P.S。在这种情况下不可能使用 Javascript "onclick" 处理程序 - 它必须是内联的 HTML。还有,不能禁止在变量值中使用引号。

尝试使用函数:

addslashes()

编辑:此方法将处理字符串本身中的引号,但如果您需要为 HTML 插入保留引号,则可能不适合。仔细阅读文档。

http://php.net/manual/en/function.addslashes.php

这是因为您的 Unicode (') 也被视为'

使用这个

<li><a onClick="a4e.duplicate_assignment(92,'ELLLO - \'If I had a million dollars\'','/assignments/cloze');" href="javascript:void(0);"><i class="fa fa-copy"></i> Duplicate assignment</a></li>

使用 json_encode 将值转换为 JavaScript 文字(进行所有必要的转义)。

使用 htmlspecialchars 将值(例如 JavaScript 程序)转换为可以安全放置在 HTML 属性值中的值。

$id = $this_assignment['id'];
$title = $this_assignment['title'];
$url = "/assignments/$type/";

$js_id = json_encode($id);
$js_title = json_encode($title);
$js_url = json_encode($url);
$js = "a4e.duplicate_assignment($js_id, $js_title, $js_url); 

$html_js = htmlspecialchars($js, ENT_QUOTES);
?>
<li>
    <a href="javascript:void(0);" onclick="<?php echo $html_js; ?>">
        <i class="fa fa-copy"></i>
        Duplicate assignment
    </a>
<li>

更好的方法是使用渐进增强和非内联 JS。您已经排除了这种可能性,但您应该尝试取消该限制。

$id = $this_assignment['id'];
$title = $this_assignment['title'];
$url = "/assignments/$type/";

$html_id = htmlspecialchars($id, ENT_QUOTES);
$html_title = htmlspecialchars($title, ENT_QUOTES);
$html_url = htmlspecialchars($url, ENT_QUOTES);
?>
<li>
    <a href="<?php echo $html_url; ?>" data-title="<?php echo $html_title; ?>" data-id="<?php echo $html_id; ?>">
        <i class="fa fa-copy"></i>
        Duplicate assignment
    </a>
<li>
<!-- and later -->
<script>
    document.querySelector("a").addEventListener("click", duplicate_assignment_handler);

    function duplicate_assignment_handler(e) {
        e.preventDefault();
        a4e.duplicate_assignment(this.dataset.id, this.dataset.title, this.href);
    }
</script>
</script>