使用php最佳选项处理数据库

时间:2017-08-04 16:22:17

标签: php mysql database-design

我正在做一个社交网络的迷你项目,我对桌子有疑问。    让我们看看,我需要在他们的页面中提供帖子。要做到这一点,我是否必须为每个用户创建表,或者只创建一个表并将其用于多个用户(可以通过选择特定用户名并在其页面中显示数据来获取数据)。  哪种方式最好?   我的PHP代码:

<?php
  $query="select * from table_name where user=$username order by time desc;";
?>

1 个答案:

答案 0 :(得分:3)

回答你的问题

最好只使用1个用户表,并为您的帖子分别设置。您的users表应具有每个特定用户的所有信息,其中包含由MySQL数据库自动生成的1个唯一值。 (使用自动增量)在posts表中,您应该拥有每个帖子的所有数据,其中user_id列保存来自users表的唯一值,这样您就知道是谁发布了它。

这是一个模型表结构:

Users table:    
uid | name | email

Posts table:
uid | user_id | message
posts表中的

user_id应始终等于users表中的某些uid

  

每个表都应该始终具有一些赋予其主要值的唯一值

我真正关心的是

我非常关心您的应用程序的安全性。准备好的陈述更容易使用,而且更安全。

在您分享的代码段中:

<?php
  $query="select * from table_name where user=$username order by time desc;";
?>

这个查询非常不安全,正如Bobby Tables会告诉你的那样。我不确定您使用的数据库连接类型,但我建议PDO。我写了一个函数,使这非常容易,这是它的代码片段:

这是我通常称为connection.php的文件,您可以在需要使用数据库的任何页面上导入该文件。

<?php
    $host = 'localhost';
    $db   = '';
    $user = '';
    $pass = '';
    $charset = 'utf8';

    $dsn = "mysql:host={$host};dbname={$db};charset={$charset}";
    $opt = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ];
    $pdo = new PDO($dsn, $user, $pass, $opt);

    function pdoQuery($query, $values = []) {
        global $pdo;
        if(!empty($values)) {
            $stmt = $con->prepare($query);
            $stmt->execute($values);
        } else {
            $stmt = $con->query($query);
        }
        return $stmt;
    }
?>
  

此函数允许您轻松使用预准备语句   包括connection.php页面和以一种方式编写查询   可读清洁安全。我确信很多读这篇文章的人不习惯准备陈述或知道如何   工作,这篇文章的其余部分将解释这一点。

     

这里最大的区别之一是,而不是使用String Interpolation   您的查询,您将变量设置为问号?,所以您的   查询看起来像这样:UPDATE table SET user=?而不是UPDATE table SET user='$user' - 变量将在稍后发送   安全,所以这可以防止SQL注入。

这就是你的查询现在的样子:

pdoQuery("SELECT * FROM `table_name` WHERE user=? ORDER BY `time` DESC", [$username]);

这基本上是它的工作原理:

pdoQuery(string $query, array $variables)

如果没有传递变量,它会自动使用query()函数,如果你传递变量,它会自动绑定并执行语句。无论您执行什么查询,该函数始终将查询作为对象返回,因此您可以使用在执行后通常可用于PDO查询的任何方法对其执行操作。

  

如果你知道这些是如何工作的,你可以在这里停止阅读:)我放了一些   下面列出了一些可以操作返回数据的方法   做你需要做的事。

此函数返回您请求的查询对象,因此如果您想循环查询查询的所有结果,请按以下方式使用它:

$stmt = pdoQuery("SELECT * FROM `table_name` WHERE `user`=? ORDER BY time DESC", [$username])->fetchAll();
foreach($stmt as $row) {
    $row['name']."<br>";
}

或者,如果您只想从特定行获取单个列,则可以像这样使用它:

$username = pdoQuery("SELECT `username` FROM `users_table` WHERE uid=? ORDER BY `time` DESC", [$uid])->fetchColumn();

这将从username作为字符串

的用户返回uid=$uid

或者如果您想要来自1个特定行的多个值,则可以执行

$user = pdoQuery("SELECT `username`,`name`,`email` FROM `users_table` WHERE uid=? ORDER BY time DESC", [$uid])->fetch();

将返回$ user作为包含用户的用户名,名称和电子邮件的数组。

您还可以使用此函数来INSERT,UPDATE或基本上您能想到的任何类型的查询。这是你插入的方式:

pdoQuery("INSERT INTO `table_name` (`name`,`col2`, `col3`) VALUES (?,?,?)", [$name, $col1, $col2]);

我的PDO课程

自写这篇文章以来,我创建了一个名为GrumpyPDO (Hosted on Github)的新数据库包装类。

此类方法返回您请求的查询的对象,因此如果您想循环查询的所有结果,请使用它:

全部取消

GrumpyPDO长语法

$stmt = $db->run("SELECT * FROM `table_name` WHERE `user`=? ORDER BY time DESC", [$username])->fetchAll();

GrumpyPDO短语法

$stmt = $db->all("SELECT * FROM `table_name` WHERE `user`=? ORDER BY time DESC", [$username]);

循环:

foreach($stmt as $row) {
    $row['name']."<br>";
}

单列返回

或者,如果您只想从特定行获取单个列,则可以像这样使用它:

//Long Syntax
$username = $db->run("SELECT `username` FROM `users_table` WHERE uid=? ORDER BY `time` DESC", [$uid])->fetchColumn();

//Short
$username = $db->cell("SELECT `username` FROM `users_table` WHERE uid=? ORDER BY `time` DESC", [$uid]);

这将从username作为字符串

的用户返回uid=$uid

整行返回

或者如果您想要来自1个特定行的多个值,则可以执行

//Long Syntax
$user = $db->run("SELECT `username`,`name`,`email` FROM `users_table` WHERE uid=? ORDER BY time DESC", [$uid])->fetch();

//Short Syntax
$user = $db->row("SELECT `username`,`name`,`email` FROM `users_table` WHERE uid=? ORDER BY time DESC", [$uid]);

将返回$ user作为包含用户的用户名,名称和电子邮件的数组。

DML查询

您还可以使用此函数来INSERT,UPDATE或基本上您能想到的任何类型的查询。这就是你插入的方式(所有DML都是相似的):

$db->run("INSERT INTO `table_name` (`name`,`col2`, `col3`) VALUES (?,?,?)", [$name, $col1, $col2]);