【问题标题】:Content creation through javascript and php - avoiding double work通过 javascript 和 php 创建内容 - 避免重复工作
【发布时间】:2022-01-01 20:56:07
【问题描述】:

让我们假设一个简单的例子,一个通过 html、php 和 javascript 运行的博客。加载页面时,我运行一个 php 脚本,例如迭代地将所有 cmets 放在一篇博文下。 cmets 的打印是以面向对象的方式完成的,其中评论由一个类和一个成员函数 print_comment() 表示,它与评论字段相呼应,包括发布日期、作者、文本等:

// in the comment class declaration

class comment
{
  $id; // unique identifier of comment
  $dateSubmission; // date when comment was submitted
  $text; // content of comment
  $author; // who wrote it

  function __construct($id)
  {
    $this->load($id);
  }

  function load($id)
  {
    // here i load all info from mysql database for the defined id
  }

  function print_comment($id)
  {
    echo "<div class=\"comment-container\">";
      echo "<div class=\"comment-author\">";
      // etc etc
      echo "</div>";
    echo "</div>";

  }
}


// in the blog.php file
$ids = getCommentIds($postId); // returns comment ids for current blog post
$nComments = length($ids);
for ($iComment = 0; $iComment < $nComments; $iComment++)
{
  $currComment = new comment($ids[iComment]); // loads content for comment
  $currComment->print_comment(); // prints comment
}

现在用户添加了另一个评论,在单击提交按钮并通过 ajax 调用处理所有数据库内容后,我想在现有评论列表下添加新评论。理想情况下,我现在喜欢使用我已经准备好的 php 类来创建文本,但到目前为止,我总是需要用 javascript 重写内容创建。

处理这种情况的最佳方法是什么?在 javascript 中重写 print_comment 函数是一种方法,但它是双重工作,并且每当我更新布局时都需要更改两个函数。

这种情况的最佳做法是什么?

P.S.:我知道重新加载整个页面是一种解决方案,但不是我想要的:)。

【问题讨论】:

  • 什么意思,“需要用javascript重写内容创建”?如果您的 AJAX 请求获得了返回评论的 HTML,那么此时您需要做的就是获取该 HTML,并将其附加到文档的某个位置。 “重写 [ing] javascript 中的内容创建”到底是怎么回事?
  • 我并没有真正关注您的代码,您似乎首先从某个地方获取所有评论 id,然后遍历它们并从 MySQL 中一个一个地获取它们?如果您已经拥有它们(来自您的getComment()-function),则无需向数据库执行 x 次额外请求以再次获取它们。
  • getComment(现在是getCommentIds)仅从查找表中获取评论 ID。我将 cmets 存储在一个表中,将帖子存储在另一个表中,然后我有一个映射表告诉我哪个评论属于哪个帖子。我更正了上述问题中的措辞。上面的代码只是试图说明问题背后的想法。
  • @CBroe 如果我想为新创建的评论添加 php 函数 print_comment() 生成的输出而不重新加载到我的 html 内容,我需要一个 javascript 函数来创建它或以某种方式从ajax调用对吗?在这种情况下,你将如何从 php 函数返回和重定向?
  • 而不是获取评论 ID,然后遍历它们并逐个获取每个评论(这对性能非常不利),只需一次获取所有 cmets(在查找之间进行 JOIN 语句表和 cmets 表)。然后,您可以遍历 cmets 以填充对象,或使用 PDO 和 fetch 模式 FETCH_CLASS。您应该避免在循环中进行查询,除非出于某种原因,这是绝对必要的。

标签: javascript php mysql ajax


【解决方案1】:

不幸的是,您最终总是需要在 JavaScript 中编写动态加载内容。 PHP 在服务器上运行并提供静态文件。如果你想更新页面的一部分(而不是提供一个全新的页面),这必须在客户端完成,这意味着使用 JavaScript。

【讨论】:

    【解决方案2】:

    解决方案有多种途径。

    1. 在表单提交时刷新页面,这是使用PHP的标准方式,这种方式没有问题。
    2. 功能重复,因此您不必刷新整个页面,只需使用 javascript 添加评论者回复即可。除了代码重复之外,缺点是在您硬刷新页面之前,您不会收到其他新的 cmets。
    3. 前端只用JS,API后端只用PHP。这样您就可以加载部分数据而无需进行完整的页面刷新。不利的一面是,您仍然需要复制代码,因为您需要前端和后端验证。
    4. 现在我们正在进行一些极端的重写,但您也可以考虑使用 nodeJS 作为后端,并用 javascript 编写整个应用程序。这使您可以选择在前端和后端之间共享库,从而完全消除代码重复。作为额外的好处,添加 websocket 相对容易,这意味着您可以在发送新 cmets 到每个连接的阅读器时推送它们。
    5. 不要费心编写自己的博客,而要依赖久经考验的平台。

    最后一个可能是最好的解决方案。

    但是,如果您只是为了练习而编写博客应用程序,我会选择选项 4,我认为这为您提供了最灵活的理由来推动自己。在 nodeJS 中开始编写 REST-api 很容易,并且有很多库可以帮助您完成繁重的工作。一旦你有一个完整的 API,你可以使用 vanilla javascript 编写一个简单的前端,或者你可以选择任何前端框架。您可以添加 socketIO 以启动和运行一些实时评论,并且您可以使用不同的框架创建另一个前端。

    【讨论】:

    • 我不是在写博客,但它作为我正在尝试做的事情的一个例子;)但是我建立的网站需要提到的从其他用户推送新 cmets 的功能。因此,我将研究选项 4,如果它解决了上述问题,则接受答案。非常感谢您的详细解答!
    • 关于选项1:我认为如果很少使用需要刷新的功能就可以了。但这不是 a) 显着增加服务器负载 b) 通过等待时间降低用户体验吗?
    • 是的,在这两个方面。但这主要取决于页面大小和复杂性。假设您有一个包含大量验证和多连接查询的复杂页面。服务器上的压力以毫秒为单位,页面加载时间也是如此。不采用标准的 PHP 方式显然是更好的体验,但是您只会从毫秒的加载时间中减少几毫秒。不要误会我的意思,优化总是一个好主意,但归根结底就是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多