【问题标题】:handling database with php best option用php最佳选项处理数据库
【发布时间】:2017-08-04 16:22:17
【问题描述】:

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

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

【问题讨论】:

  • 你应该有一个用户表,如果你为每个用户创建一个不同的表,那将是一个非常糟糕的设置。特别是因为您不能以安全的方式使用Prepared Statements 使用动态表名,并且如果您不打算使用准备好的语句,请告诉我您的项目名称是什么,这样我才能记住永远不要使用它?
  • 而且您不应该使用他们的用户名来获取数据,而是在创建他们的帐户时自动生成的唯一值。
  • @GrumpyCrouton 谢谢你,我现在明白了。很多对新手有用的信息

标签: php mysql database-design


【解决方案1】:

回答你的问题

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

这是一个模型表结构:

Users table:    
uid | name | email

Posts table:
uid | user_id | message

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

每个表都应该始终有一些唯一的值,并为其分配主值


我真正关心的

我非常关心您的应用程序的安全性。准备好的语句更容易使用,也更安全。

在您分享的代码 sn-p 中:

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

这个查询非常不安全,Bobby Tables 会告诉你。我不确定您使用的数据库连接类型,但我建议PDO。我写了一个函数让这变得非常简单,这里是 sn-p:

这是我通常称为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 页面并以如下方式编写查询 可读干净安全。我敢肯定,很多阅读这篇文章的人不习惯准备好的陈述,也不知道他们是怎么做的 工作,这篇文章的其余部分将解释这一点。

这里最大的区别之一是在 你的查询,你将变量设置为问号?,所以你的 查询看起来像这样: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,其中包含用户的用户名、姓名和电子邮件。

您还可以使用此功能来插入、更新或基本上任何您能想到的查询类型。这就是你插入的方式:

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 查询

您还可以使用此功能来插入、更新或基本上任何您能想到的查询类型。这是您插入的方式(所有 DML 都相似):

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

【讨论】:

  • 可以给表结构
  • @jasinthpremkumar 我不是在为你写你的陈述。
  • 怎么样? @jasinthpremkumar
  • @jasinthpremkumar 你读过我的帖子吗?我已经从字面上解释了如何从表中提取数据
  • 通过使用prepared statement会阻止sql注入和过滤器的值吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
相关资源
最近更新 更多