【问题标题】:Is echoing Javascript code condtionally based on server-side logic considered harmful?基于服务器端逻辑的有条件地回显 Javascript 代码是否被认为是有害的?
【发布时间】:2025-12-03 15:50:01
【问题描述】:

像这样:

<script>
    setSomeStuffUp();

    <?php if ($otherStuffNeedsToBeDone === true) { ?>

         doSomeOtherStuff();

    <?php } ?>

    breakSomeStuffDown();
</script>

在工作中遇到了类似的东西——用模板(Smarty)完成,所以它看起来有点干净——但不是很多!还呼应了一些用于诸如 jQuery 选择器之类的模板变量,以及其他看起来不愉快的小东西。

这样做的正确方法是什么?通过AJAX将JS中需要用于逻辑的数据加载为JSON? HTML 数据属性?

它只是闻起来很糟糕,很糟糕,很糟糕。

谢谢大家。

【问题讨论】:

  • 我自己通常不会做这样的事情,但一直都在看,据我所知,使用服务器端语言输出 javascript 或其他任何事情都没有错,一个在服务器上,另一个在客户端,它们并没有真正交互。
  • 看不出有什么问题。
  • 我看不出有什么问题,但是我尽我所能远离它以保持客户端和服务器端之间的分离。
  • 只要doSomeOtherStuff()中的块;代码量不是很大我觉得可以接受。
  • 没有错。但是,我倾向于逃避这些事情。正如 Oscar Jara 所说,使用语言 X 生成语言 Y 的代码是不好的做法。尝试将 PHP 和 JS 解耦,甚至 HTML 和 JS 更好。

标签: php javascript jquery html


【解决方案1】:

使用语言 X 生成语言 Y 的代码是不好的做法。

尝试将两种语言“解耦”,例如,像这样:

<script type="text/javascript">
  var data = {
    id: "<?php echo $id ?>",
    ...
  };

  $(document).ready(function(){
     $("#" + data.id).on("click", function(){
       /*do something*/
     });
  });
</script>

这样,PHP 只关心填充数据结构,而 JavaScript 只关心消费数据结构。

【讨论】:

  • +1 基本上是这个问题的最佳和最简洁的答案。尽可能多地保持你的 JS 代码是静态的,并且在可能的情况下,只动态生成数据结构。
  • 严格来说,这根本不是两种语言的解耦。
  • @Mahn 这就是我使用引号的原因。
  • 但它仍然依赖于 PHP。你可以给一匹马化妆,但这不会让它变得不像一匹马。
  • @Mahn 只是一种表达方式,不要那么严格。这样你就可以减少混乱。
【解决方案2】:

从服务器回显配置变量和一些 javascript 初始化代码通常听起来还不错,但如果这样的 js-injection-from-server 片段到处都是,那么你是对的,很丑,至少因为这样的代码很难管理。

只需尝试集中任何类型的初始化,然后在静态定义的客户端 JavaScript 逻辑中完成其余的工作。

UPD。 @Oscar Jara 正在谈论同样的事情并提供了一个很好的说明。但是,如果服务器端逻辑通过 HTML 为 JavaScript 处理提供数据,则通常甚至可以避免这种情况(毕竟,这就是 HTML 的用途)。

这是您经常遇到的一个小例子。假设您要输出一个画廊,该画廊将通过 JavaScript 增强为轮播。

服务器生成的 HTML:

<ul id="myGallery">
  <li><img src="img1.jpg /></li>
  <li><img src="img2.jpg /></li>
  <li><img src="img3.jpg /></li>
  ...
</ul>

然后,当 DOM 准备好时,您的静态 JavaScript 代码会初始化轮播:

// when DOM ready...
AwesomeCarousel.init($('#myGallery'));

这里由服务器准备的数据是这段带有图像列表的 HTML,不需要生成 JavaScript 显式加载每个图像。您可以通过data-* 属性传递任意数据。

【讨论】:

    【解决方案3】:

    就个人而言,我在很多情况下都在 JS 中使用 PHP。有时是用 JSON 数据、页面 id 或类似性质的东西填充变量。就我而言,PHP 旨在编写出现在页面上的代码,而 JS 旨在在内容出现后与用户进行交互。

    我确实明白你在说什么,因为可能有更清洁的方法可以做到这一点。您提到了 AJAX,它可能会更简洁,并且肯定会帮助输出文档的流程。唯一的问题是您必须向服务器发出第二个请求,以获得一些非常简单和无意义的变量。几毫秒不是很大,但在生产网站中,您可能不希望发出额外的请求并占用服务器资源。

    如果有这么大的交易,最干净的方法是什么...我将使用该代码创建一个单独的 JS 文件,然后在需要时使用服务器包含该单个文件。同样,我不这样做,但我认为它在模板中看起来最干净。

    【讨论】:

      【解决方案4】:

      如果你想真正走出去,你可以让 HTML 页面请求一个 .js 文件,加上他们的 session-id 或其他一些他们是谁的指标,将 .js 调用作为 PHP 调用来操作,根据会话要求动态构建 JS,然后将其作为 .js 文件类型输出回浏览器。

      但这是很多工作。

      如果您想要味道更淡的东西,请让 PHP 在文件末尾转储 JSON 字符串:

      var cfg_string = "{\"username\":\"Norguard\", \"new_messages\":[......]}";  // client
      
      $cfg_obj = array(); // whole lot o'PHP
      $json_encoded_cfg = json_encode($cfg_obj);
      echo "var cfg_string = {$json_encoded_cfg};" //server-side
      

      然后在客户端解析它以增加安全性...

      ...或者直接在模板中创建地图:

      $cfg_string = "var dataMap = {";
      foreach ($cfg_obj as $key => $val) {
         // print key:val all pretty-like,
         // handle commas (ie: no trailing comma at the end), indent with tabs or spaces
         // if you want, count the number of items so that the object closes ({})
         // without any newline operator, if there are no config settings 
      }
      echo $cfg_string;
      

      这两者都是干净且不引人注目的,并且将所有内容分开。 配置数据/文本可以直接位于您的初始化/加载代码的上方,并作为参数传递给该初始化逻辑。

      【讨论】:

        【解决方案5】:

        如果您所做的只是将数据从服务器端语言传递到 JavaScript 代码,那很好。很多 CMS 包都可以做到这一点。

        我并不认为需要在服务器端有条件地生成 JavaScript 代码。也许它有一个用例,但 JavaScript 本身就是一门语言,那么为什么不把逻辑放在 JavaScript 代码中呢?

        【讨论】:

          最近更新 更多