首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 與 JavaScript 變量交互實戰:模板引擎輸出、數據類型轉換、XSS 防護與假分支編譯陷阱

     編輯:PHP 綜合知識

PHP 服務端渲染頁面時,常需將變量傳遞給前端 JavaScript。核心機制是 PHP 在輸出階段將變量值「內插」到 JS 代碼字符串中,瀏覽器接收到的是純文本 JS。本文詳細講解安全輸出模式、數據類型對應、條件分支編譯陷阱與現代最佳實踐。

一、基本輸出模式

<?php
$title = '首頁 & 儀表盤';
$userCount = 12345;
$tags = ['php', 'js', 'ajax'];
$flags = true;
?>
<script>
// 字符串:必須用 json_encode 自動加引號、轉義
var title = <?= json_encode($title, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP) ?>;
// 數字/布爾:直接輸出
var userCount = <?= $userCount ?>;
var flags = <?= $flags ? 'true' : 'false' ?>;
// 數組/對象:json_encode 輸出 JS 字面量
var tags = <?= json_encode($tags) ?>;
console.log(title, userCount, flags, tags);
</script>

二、為什麼必須用 json_encode?

PHP 類型直接 echo 後果json_encode 結果說明
字符串含引號/換行JS 語法錯誤"Hello \"World\""自動轉義、加雙引號
關聯數組Array to string notice{"key":"val"}轉為 JS 對象
索引數組同上["a","b"]轉為 JS 數組
null/false/true空字符串/0/1null/false/true保留 JS 原生字面量
浮點數科學計數法風險1.23精度穩定

三、經典陷阱:假分支也會被編譯

<?php
$flag = true;
if ($flag) {
    $arr = ['a', 'b'];
} else {
    $str = 'fallback';
}
?>
<script>
var flag = <?= $flag ? 'true' : 'false' ?>;
if (flag) {
    var data = <?= json_encode($arr) ?>; // 正常
} else {
    // 雖然不執行,但 PHP 編譯階段仍會解析此行
    var data = <?= json_encode($str) ?>; // 若 $str 未定義或類型不符,這裡可能報錯
}
</script>

解決:確保所有分支變量在 PHP 端都已定義且類型兼容,或用三元運算符統一輸出:

var data = <?= json_encode($flag ? $arr : ['fallback']) ?>;

四、現代最佳實踐:數據層與視圖層分離

方案 A:內聯 JSON 數據島(推薦中小頁面)

<script id="page-data" type="application/json"><?= json_encode([
    'user' => $currentUser,
    'config' => $siteConfig,
    'csrfToken' => $_SESSION['csrf_token'],
], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP) ?></script>
<script>
const pageData = JSON.parse(document.getElementById('page-data').textContent);
console.log(pageData.user.name);
</script>

優點:HTML 與 JS 解耦、CSP 友好(script[type="application/json"] 不執行)、易維護。

方案 B:API 端點 + 前端異步獲取(SPA/大型頁面)

// /api/page-init.php
header('Content-Type: application/json');
echo json_encode(['user' => $user, 'config' => $config]);
// 前端
fetch('/api/page-init.php').then(r => r.json()).then(data => { /* ... */ });

五、XSS 防護清單

  1. 輸出編碼:json_encode($val, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP) 防止 </script>、單雙引號、& 注入。
  2. CSP 標頭:Content-Security-Policy: script-src 'self'; object-src 'none'; 禁止內聯腳本執行(需配合 Nonce/Hash)。
  3. 避免 eval()/new Function() 解析服務端數據。
  4. 敏感數據不進前端:密碼哈希、內部 ID、權限位掩碼等僅後端使用。

六、模板引擎集成示例

  • Blade (Laravel):@json($var) 自動帶安全標誌。
  • Twig:{{ var|json_encode(constant('JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP')) }}。
  • Smarty:{$var|json_encode}(需註冊修飾器)。

總結:永遠用 json_encode 輸出 JS 變量,採用數據島模式分離關注點,配合 CSP 構建安全的 PHP-JS 交互邊界。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved