PHP和MySQL选择一个值[重复]

Posted

技术标签:

【中文标题】PHP和MySQL选择一个值[重复]【英文标题】:PHP and MySQL Select a Single Value [duplicate] 【发布时间】:2014-01-19 14:44:22 【问题描述】:

我想知道如何从我的 mysql 表中选择一个值。该表包括 usernameid 列等(id 是自动递增的,username 是唯一的)。给定用户名,我想设置一个会话变量$_SESSION['myid'] 等于与给定用户名对应的id 列中的值。这是我已经尝试过的代码:

session_start();
$name = $_GET["username"];
$sql = "SELECT 'id' FROM Users WHERE username='$name'";
$result = mysql_query($sql);
$value = mysql_fetch_object($result);
$_SESSION['myid'] = $value;

到目前为止,我得到了:

可捕获的致命错误:stdClass 类的对象无法转换为字符串。

$value 转换为字符串类型并不能解决问题。

【问题讨论】:

只是提醒... mysql 扩展已弃用,将来将被删除:改用 mysqli 或 PDO 这存在严重的安全问题。正如@WesC 指出的那样,不要使用 mysql_* 函数。此外,您很容易受到 SQL 注入攻击。 【参考方案1】:

    不要在查询中的字段名或表名中使用引号。

    获取对象后,您需要通过属性/属性名称访问对象属性/属性(在您的情况下为 id)。

注意:请使用 mysqli_* 或 PDO,因为 mysql_* 已弃用。这里使用的是 mysqli:

session_start();
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = new mysqli('localhost', 'username', 'password', 'db_name');
$link->set_charset('utf8mb4'); // always set the charset
$name = $_GET["username"];
$stmt = $link->prepare("SELECT id FROM Users WHERE username=? limit 1");
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
$value = $result->fetch_object();
$_SESSION['myid'] = $value->id;

额外提示:在这种情况下使用限制 1,它将节省执行时间:)

【讨论】:

这可以消除错误消息,但在屏幕上打印 $_SESSION['myid'] 现在会显示“id”而不是特定的 int。 @user3055501 :试试上面的代码。我已更改 $sql 行并提供您的反馈。它应该工作:) ...并且永远不要在查询中使用原始用户输入。【参考方案2】:

mysql_* 函数已弃用且不安全。 您问题中的代码容易受到injection attacks 的攻击。强烈建议您改用 PDO 扩展,如下所示:

session_start();

$query = "SELECT 'id' FROM Users WHERE username = :name LIMIT 1";
$statement = $PDO->prepare($query);
$params = array(
    'name' => $_GET["username"]
);
$statement->execute($params);
$user_data = $statement->fetch();

$_SESSION['myid'] = $user_data['id'];

$PDO 是您的 PDO 对象变量。有关 php 和 PDO 的更多信息,请参阅https://www.php.net/pdo_mysql。

如需额外帮助:

下面是如何使用 PDO 连接到数据库的快速入门:

$database_username = "YOUR_USERNAME";
$database_password = "YOUR_PASSWORD";
$database_info = "mysql:host=localhost;dbname=YOUR_DATABASE_NAME";
try

    $PDO = new PDO($database_info, $database_username, $database_password);

catch(PDOException $e)

    // Handle error here

【讨论】:

感谢韦斯的回答。当我有更多时间时,我一定会研究 PDO。 从个人经验来看,我建议你早点而不是晚点。您使用mysql_* 函数编写的代码越多,您就越会发现需要完全重写。此外,它实际上非常方便,并且在其他领域更有条理。 如果其他人看到这个并惊慌失措,您可以改为使用 mysqli 更好。注意mysql末尾的i 就像@AndersM 说的 - 我还发现 mysqli 比 PDO 更易于使用/阅读,用于简单查询。但是请注意,Wes 提出了一个非常重要的观点:如果您的查询的任何部分包含不是 100% 受您控制的文本,则使用准备好的语句。在mysqli中,即prepare,manual discussion of prepared statements【参考方案3】:

您可以使用mysqli_fetch_field 方法来做到这一点。

session_start();
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
$name = $_GET["username"];
$sql = "SELECT 'id' FROM Users WHERE username='$name' limit 1";
$result = mysqli_query($link, $sql);
if ($result !== false) 
    $value = mysqli_fetch_field($result);
    $_SESSION['myid'] = $value;

注意:您也可以使用mysql_fetch_field() 方法来做到这一点,但它将在 php v5.5 中被弃用

【讨论】:

mysqli_fetch_field "返回一个包含字段定义信息的对象,如果没有可用的字段信息,则返回 FALSE。所以这不会像答案所建议的那样工作。 -1 因为这个。 @GusstavvGil:在调用mysqli_fetch_field 之前,我已通过确保存在有效的$result 来更正代码。我还添加了缺少的 $link 参数。 @ToolmakerSteve mysqli_fetch_field 不返回值。它返回字段定义,如名称、表、标志。 -1 因为这个...php.net/manual/en/mysqli-result.fetch-field.php 不应使用此答案,因为它不安全/不稳定。 警告: 这个答案是完全错误的。 mysqli_fetch_field() 返回有关表列的元数据,而不是值本身。【参考方案4】:

试试这个

$value = mysql_result($result, 0);

【讨论】:

警告: mysql_* 扩展自 PHP 5.5.0 起已弃用,自 PHP 7.0.0 起已被删除。相反,应该使用mysqli 或PDO_MySQL 扩展名。在选择 MySQL API 时,另请参阅 MySQL API Overview 以获得更多帮助。 “试试这个”答案在 *** 上的价值很低,因为它们在教育/授权 OP 和成千上万的未来研究人员方面做得很差。即使您觉得您的解决方案是超基本的/不言自明的,所有答案都应该包含某种形式的简单英语支持文本。告诉研究人员它是如何工作的,它为什么起作用,它与其他答案有何不同,为什么你认为这是一个好主意,提供文档链接等。当你回答的目的是帮助人们和为他人树立良好答案的榜样。【参考方案5】:

mysql_* 扩展已于 2013 年弃用,并于 2018 年从 PHP 中完全删除。您有两种选择 PDO 或 MySQLi。

PDO

更简单的选择是 PDO,它有一个简洁的辅助函数 fetchColumn()

$stmt = $pdo->prepare("SELECT id FROM Users WHERE username=?");
$stmt->execute([ $_GET["username"] ]);
$value = $stmt->fetchColumn();

Proper PDO tutorial

MySQLi

你可以用 MySQLi 做同样的事情,但它更复杂:

$stmt = $mysqliConn->prepare('SELECT id FROM Users WHERE username=?');
$stmt->bind_param("s", $_GET["username"]);
$stmt->execute();
$data = $stmt->get_result()->fetch_assoc();
$value = $data ? $data['id'] : null;

fetch_assoc() 如果数据库没有返回任何行,则可能返回 NULL,这就是为什么我使用三元检查是否有任何数据返回。

从 PHP 8.1 开始你也可以使用fetch_column()

$stmt->execute();
$value = $stmt->get_result()->fetch_column();

【讨论】:

***.com/questions/59893254/…(很难找到安全的查询来关闭新问题。)【参考方案6】:

当您使用mysql_fetch_object 时,您将获得一个对象(属于stdClass 类),其中包含该行的所有字段。

使用mysql_fetch_field 而不是mysql_fetch_object,这将为您提供结果集的第一个字段(在您的情况下为id)。文档是here

【讨论】:

警告: 这个答案是完全错误的。 mysql_fetch_field() 返回有关表列的元数据,而不是值本身。【参考方案7】:

试试这个

session_start();
$name = $_GET["username"];
$sql = "SELECT 'id' FROM Users WHERE username='$name' LIMIT 1 ";
$result = mysql_query($sql) or die(mysql_error());
if($row = mysql_fetch_assoc($result))

      $_SESSION['myid'] = $row['id'];

【讨论】:

警告: mysql_* 扩展自 PHP 5.5.0 起已弃用,自 PHP 7.0.0 起已被删除。相反,应该使用mysqli 或PDO_MySQL 扩展名。在选择 MySQL API 时,另请参阅 MySQL API Overview 以获得更多帮助。【参考方案8】:

很明显,只有一个id对应一个username,因为username是唯一的。

但实际问题在于查询本身-

$sql = "SELECT 'id' FROM Users WHERE username='$name'";

O/P

+----+
| id |
+----+
| id |
+----+

'id' 实际上被视为字符串而不是id 属性。

正确的语法:

$sql = "SELECT `id` FROM Users WHERE username='$name'";

即使用重音(`)代替单引号(')。

$sql = "SELECT id FROM Users WHERE username='$name'";

完整代码

session_start();
$name = $_GET["username"];
$sql = "SELECT `id` FROM Users WHERE username='$name'";
$result = mysql_query($sql);
$row=mysql_fetch_array($result)
$value = $row[0];
$_SESSION['myid'] = $value;

【讨论】:

需要一个 ;在第五行。 警告: mysql_* 扩展自 PHP 5.5.0 起已弃用,自 PHP 7.0.0 起已被删除。相反,应该使用mysqli 或PDO_MySQL 扩展名。在选择 MySQL API 时,另请参阅 MySQL API Overview 以获得更多帮助。

以上是关于PHP和MySQL选择一个值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

PHP MYSQL如何在选择时计算项目[重复]

当php函数从mysql数据值中选择时,“未定义的变量”

使用 PDO 选择 MYSQL 中的 PHP 变量 [重复]

mysql - 为列中的每个值选择不重复的[重复]

PHP MYSQL选择最后插入的ID [重复]

mysql php从2个表中选择字段,具有相同的字段名称[重复]