在数据库中插入记录后输出数据的最佳方式是使用ajax/JSON/php


Best way to output datas after insert record on database with ajax / JSON / php

我正在做一个项目,我想知道在数据库上插入一个记录后,显示数据的最佳方式是什么,在php或jQuery中使用结构之间使用复杂的html结构,为什么?。

场景示例:

我正在建立一个帖子和评论系统。当用户编写并发布帖子时,调用ajax会触发函数php,并将信息插入数据库。直到这里一切都好,但我必须在用户的墙上显示消息插入,那么显示帖子插入的最佳方式是什么?

有很多不同的方式,但在速度、安全性和兼容性方面,哪种方式最好?

一些例子,建议是受欢迎的:

<script> // default example of call ajax
        $.ajax({
            type: "POST",
            url:  'http://localhost/ajax_ouput_post',
            dataType: 'json',
            data: { id_user : 1, title : "Hello everyone", content : "Good morning" },
            success: function(html) {
              // output under php example
            },
            error: function(){
                  alert('Error on ajax call');
            }
        });
    </script>

1-我在php中创建了输出的模板。

<?php 
 function ajax_output_post() {
   $title = $_POST['title'];
   $content = $_POST['content'];
   $id_user = $_POST['id_user'];
   
   // all the check for the input
  
   $query = // insert data on mysql @return id_post;
   $select_last_post_mysql = // select the last query from the db using id_user and id_post
   foreach ($select_last_post_mysql as $post) {
      $template = // html structure;
      $template .= // continue html structure;
        if ($post->photo == 1) {
           $template .= // <div>photo user</div>
        }
      $template .= // ecc...
   }
   echo json_encode(array('template' => $template));
 }
?>

jquery输出

<script>
  $(#wall).append(html.template);
</script>

php输出jQuery模板的第二个示例

<?php 
     function ajax_output_post() {
       $title = $_POST['title'];
   $content = $_POST['content'];
   $id_user = $_POST['id_user'];
   
   // all the check for the input
  
   $query = // insert data on mysql @return id_post;
   $select_last_post_mysql = // select the last query from the db using id_user and id_post
   foreach ($select_last_post_mysql as $post) {
        $title_json = $post->title;
        $content_json = $post->content;
        if ($post->photo == 1) {
          $photo_user_json = $post->photo_user;
        } else {
          $photo_user_json = "";
        }
        $id_post = $post->id_post;
   }
   echo json_encode(array('title' => $title_json, 'content' => $content_json, 'id_post' => $id_post));
 }
?>

jquery

<script>
// in jquery
        var Template = {
           main_container: "<div class='post_container' data-post='" + html.id_post + "'>",
              title: "<div class='title'>" + html.title + "</div>",
              content: "<div class='content'>" + html.content + "</div>",
           close_main: "</div>",
           run: function() {
                return Template.main_container + Template.content + Template.close_main;
           }
       };
     $('#wall').append(Template.run());
</script>

好吧,并没有真正的"最佳"方法来做到这一点,它总是取决于具体情况。

在您的情况下,您可以:

  • 只需通过javascript将用户帖子附加到DOM,而不知道它是否插入到数据库中(因为您在客户端有帖子的所有数据,所以不需要再次选择它)

  • 在您知道用户帖子已插入(在成功处理程序中,但仍然没有来自php的响应数据)之后,通过javascript(如上文所述)附加用户帖子

我建议不要再选择插入的数据,除非你需要一个自动生成的值,比如id或插入的时间戳,相反,你可以在插入后的响应中返回请求的值。

希望这能有所帮助。

有几种方法可以实现这一点,并且每种方法都需要权衡。

实现这一点的最简单方法是保留上面Nico所回答的javascript中的用户输入。这种方法的优点是,它很容易完成并转移到其他问题上,由于这种简单性,很少有移动部件被滥用。这种方法的主要缺点是,它意味着前端对后端逻辑处理数据时发生的事情做出了盲目的假设,如果后端默默地失败,这就有可能误导用户发生了什么,而这种错误通常很难抓住,直到它咬到了人并引起他们的抱怨。对于简单的用例来说,这可能是最好的答案,但如果你打算扩展它或引入显著的复杂性,这会使出现错误的可能性很高,应该进行替换。

根据你给出的例子,你似乎已经在这个思路上了。因此,为了解决您所关心的每一个问题,首先我要说的是,兼容性最好通过通常不被排斥来解决。这适用于用于一般消费的库,但对于需要意见才能执行特定期望结果的私人项目或内部业务逻辑来说,这并不一定是优选的。兼容性方面的主要警告是,前端处理模板的频率至少与后端一样高。在某些情况下,它可能在ReactJS或Angular中完成,也可能在后台由Twig完成,或者其他任何事情。如果您想要广泛的兼容性,那么应该有一些配置来决定是以原始格式传递响应还是附带模板。对于私人业务逻辑或您正在为特定目的构建的应用程序,其根本目的是实现特定的结果,最好使用系统的现有模板结构,或者选择一个并坚持下去,这样您就可以专注于最终目标,而不会分心。但无论哪种方式,github库的作者和应用程序开发人员都可能以完全不同的方式解决同样的问题,而且他们都没有错。

在安全方面,典型的问题都适用。如果用户输入被输出、输入到模板内容中或存储在数据库中,那么单个方法大多是任意的,前提是您涵盖了这些基础。

就速度而言,JavaScriptDOM选项总是最快的。然而,您可以使它几乎同样快,这取决于您对优化的容忍度。您也许可以使用客户端存储来缓存未修改的模板客户端,只需使用模板内容的哈希作为其标识密钥,这样当您在服务器上更改模板时,它就会自动刷新。如果随后将密钥发送到服务器并且匹配,则不需要在响应体中提供模板,因为客户端已经有了正确的模板。如果后端上的模板散列不同,则提供新的散列,破坏该模板的存储缓存,并用新的散列替换密钥和值。这将使模板主体(几乎可以肯定是响应中最长的部分)只需要在进行更改时发送。您需要将这些值注入到静态模板客户端中才能以这种方式执行此操作,并且仍然在每次请求时从服务器获取这些值。在后端,您不希望生成单独的SELECT语句。您希望将值存储在array中,如果INSERT查询成功,则只返回这些值,例如:

<?php
// List of keys that MUST be present for the query to succeed. Don't bother calling the db if any of these did not come in the request.
$expected_keys = [
    'id_user',
    'title',
    'content' // add whatever else has to be passed
];
// key/val for db insert
$vals = [];
try {
    // verify expected keys are provided
    foreach ( $expected_keys as $k => $expected ) {
        if !(array_key_exists ( $expected, $_POST ) ) {
            // not a valid post, return an error
            throw new 'InvalidArgumentException( sprintf( 'Expected field [%1$s] was not provided. ', $expected ) );
        }
        // retain the field in $vals for insert
        $vals[ $expected ] = $_POST[$expected];
    }
    
    $dsn = "mysql:host=localhost;dbname=myDatabase;charset=utf8mb4";
    $options = [
        'PDO::ATTR_EMULATE_PREPARES   => false,
        'PDO::ATTR_ERRMODE            => 'PDO::ERRMODE_EXCEPTION,
        'PDO::ATTR_DEFAULT_FETCH_MODE => 'PDO::FETCH_ASSOC
    ];
    $pdo = new 'PDO($dsn, "username", "password", $options);
    $stmt = $pdo->prepare(
        'INSERT INTO `myTable` ( `:' .
            implode( '`, `:', array_keys( $vals ) ) .
        '` ) VALUES (' .
            implode( '", ":', $vals ) .
        ');'
    );
    $stmt->execute( $vals );
    $stmt = null;
    
}
// User error
catch 'InvalidArgumentException $e {
    // return 400 Bad Request and $e->getMessage() as the error message
}
// Server error
catch 'Exception $e {
    // log or whatever and return a 500 error
}
// return success with whatever you need to send back from $vals or $_POST