PHP和MySQL选择一个值[重复]
Posted
技术标签:
【中文标题】PHP和MySQL选择一个值[重复]【英文标题】:PHP and MySQL Select a Single Value [duplicate] 【发布时间】:2014-01-19 14:44:22 【问题描述】:我想知道如何从我的 mysql 表中选择一个值。该表包括 username
和 id
列等(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选择一个值[重复]的主要内容,如果未能解决你的问题,请参考以下文章