使用ajax / json / php在数据库上插入记录后输出数据的最佳方法

时间:2013-12-06 11:46:17

标签: php jquery ajax json

我正在研究一个项目,我想知道这是在数据库中插入具有复杂结构的记录后显示数据的最佳方式html使用php或jquery中的结构以及为什么? / p>

方案示例:

我正在建立一个帖子和评论系统。当用户编写帖子并发布它时,调用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第二个exmaple与输出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>

2 个答案:

答案 0 :(得分:1)

嗯,实际上没有'最好'的方法,它总是取决于具体情况。

在你的情况下你可以:

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

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

我建议不要再次选择插入的数据,除非你需要一个自动生成的值,比如id或inserted-timestamp,而只需在插入后返回响应中的请求值。

希望这有帮助。

答案 1 :(得分:0)

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

完成此操作的最简单方法是将用户输入保留在 javascript 中,如上面 Nico 所回答的那样。这种方法的优点是完成和处理其他问题非常简单,并且由于这种简单性,很少有活动部件会被误用。这种方法的主要缺点是,它意味着前端对后端逻辑处理数据时正在发生的事情做出盲目假设,如果后端静默失败,这存在将发生的情况误导用户的风险,以及这种虫子通常很难被抓住,直到它咬到人并且他们抱怨为止。对于简单的用例,这可能是您的最佳答案,但如果您打算对其进行扩展或引入显着的复杂性,则出现错误的可能性很高,应该予以更换。

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

在安全性方面,the typical concerns all apply。如果用户输入被输出、输入到模板内容中或存储在数据库中,则个别方法大多是任意的。

就速度而言,javascript DOM 选项总是最快的。但是,根据您对优化的容忍度,您可以使其几乎一样快。您也许可以使用 client side storage 来缓存未修改的模板客户端,并仅使用模板内容的哈希作为其标识键,以便在您更改服务器上的模板时自动刷新。如果您随后将密钥发送到服务器并且它匹配,则您不需要在响应正文中提供模板,因为客户端已经拥有正确的模板。如果后端的模板哈希不同,则提供新的哈希,破坏该模板的存储缓存并将键和值替换为新的。这将使模板主体(几乎可以肯定是响应的最长部分)仅在进行更改时才需要发送。您需要将值注入静态模板客户端才能以这种方式执行此操作,并且仍然在每次请求时从服务器获取这些值。在后端,您不想创建单独的 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