mindplay / escape
一些全局(是的,全局!)函数,用于在模板中转义HTML/JS
Requires
- php: >=5.4
Requires (Dev)
- mindplay/testies: ^0.3
This package is auto-updated.
Last update: 2024-08-25 19:39:54 UTC
README
此包提供了一组小型的全局函数,用于在纯PHP模板中使用。
我使用此工具与 kisstpl 和纯PHP模板一起使用,但任何包(或纯PHP脚本)都应该是可以的。
这与其说是代码,不如说是文档(或许更确切地说是一种哲学)——它包含详细的内联文档和示例。
这些只是封装了 htmlspecialchars()
和 json_encode()
的微小简写函数,但假设你总是想使用 HTML 5 和 UTF-8 编码——如果你不这样,这个包不适合你。
源文件通过Composer进行引导式自动加载,这意味着这些函数总是可用,无需使用 require
或 include
。
目前包含以下函数
html($value)
~htmlspecialchars((string) $value, ENT_HTML5, 'UTF-8', true)
attr($value)
~htmlspecialchars((string) $value, ENT_QUOTES | ENT_HTML5, 'UTF-8', true)
js($value)
用来在JavaScript字符串字面量上下文中转义json($value)
~json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
请注意,由于这些函数是全局的,任何新函数的添加都将被视为一个破坏性变更,并且会增加主版本号。
为什么?
因为这些函数的PHP默认值已经过时。
为什么是全局的?因为我们不能自动加载函数,在模板中导入命名空间函数很麻烦,而我们也没有在任何地方使用全局命名空间。
转义和编码值
每个函数都旨在在单一上下文中使用——例如,在HTML标签、HTML属性值、JavaScript字符串字面量或JavaScript代码中内联。(注意,上下文通常是 嵌套的,如以下“嵌套上下文”部分的示例所示。)
以下是一些常见示例来说明这一点。
HTML标签
在HTML标签的上下文中输出一个 string
值时,使用 html()
函数
<h1><?= html($title) ?></h1>
HTML属性
在HTML属性的上下文中输出一个 string
值时,使用 attr()
函数
<div id="<?= attr($id) ?>">
JavaScript
以下示例假设是纯JSON或JavaScript上下文,例如,一个模板输出具有 Content-Type
为 application/json
或 application/javascript
的响应——与嵌套上下文,例如 <script>
标签内的JavaScript进行对比。
在JSON或JavaScript代码的上下文中输出JSON兼容的(string
、int
、float
、bool
、null
或 array
)值时,使用 json()
函数
function welcome() { alert(<?= json($message) ?>); }
在JavaScript字符串字面量的上下文中输出一个 string
时,使用 js()
函数
function welcome() { alert('Welcome, <?= js($username) ?>'); }
注意区别:json()
会给字符串值添加引号,而 js()
假设你正在输出带有引号的字符串内容。
嵌套上下文
出于安全考虑,始终考虑你输出内容的上下文很重要——并且将某些上下文视为嵌套在另一个上下文中是有帮助的。
最常见嵌套上下文示例是HTML上下文中嵌入的 <script>
标签——例如
<script> function welcome() { alert(<?= html(json($message)) ?>); } </script>
在这个例子中,内部上下文是JavaScript代码,而外部上下文是HTML,因此内部函数调用是json()
,外部函数调用是html()
。
另一个例子是HTML属性内的JavaScript字符串字面量上下文。
<button onclick="alert('Hello, <?= attr(js($username)) ?>')">
在这个例子中,内部上下文是JavaScript字符串字面量,外部上下文是HTML属性。
结合两个(或更多)上下文有许多可能的用例——但是如果你能够理解嵌套上下文的概念,选择正确的函数组合应该相对简单。