我有一个简单的问题。我还不太擅长编程,但这安全正确吗?
目前我正在使用函数来获取用户名、头像等。
看起来像这样:
try {
$conn = new PDO("mysql:host=". $mysql_host .";dbname=" . $mysql_db ."", $mysql_username, $mysql_password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
配置.php ^^
function getUsername($userid) {
require "config/config.php";
$stmt = $conn->prepare("SELECT username FROM accounts WHERE id = ? LIMIT 1");
$stmt->execute([$userid]);
$name = $stmt->fetch();
return $name["username"];
}
function getProfilePicture($userid) {
require "config/config.php";
$stmt = $conn->prepare("SELECT profilepicture FROM accounts WHERE id = ? LIMIT 1");
$stmt->execute([$userid]);
$image = $stmt->fetch();
return $image["profilepicture"];
}
这是否正确,更重要的是,这安全吗?
最佳答案
是的,对于 SQL 注入(inject)来说它是安全的。
其他一些答案偏离了 XSS 保护的主题,但您显示的代码没有回显任何内容,它只是从数据库中获取并从函数返回值。我建议您不要在从函数返回值时对值进行预转义,因为不确定您是否会调用该函数来将结果回显到 HTML 响应。
没有必要使用is_int()
,因为当您在数字上下文中使用参数时,MySQL 会自动转换为整数。非数字字符串被解释为零。换句话说,以下谓词给出相同的结果。
WHERE id = 0
WHERE id = '0'
WHERE id = 'banana'
我建议不要在每个函数中连接到数据库。 MySQL 的连接代码相当快(特别是与其他一些 RDBMS 相比),但为每个 SQL 查询建立新连接仍然很浪费。相反,连接到数据库一次并将连接传递给函数。
当您连接到数据库时,您会捕获异常并回显错误,但随后您的代码将被允许继续运行,就像连接成功一样。相反,如果出现问题,您应该让脚本终止。另外,不要向用户输出系统错误消息,因为他们无法使用该信息执行任何操作,并且可能会泄露太多有关您的代码的信息。记录错误以便您自己进行故障排除,但输出更一般的内容。
您还可以考虑为您的连接定义一个函数,并为您的用户定义一个类。这是一个例子,虽然我没有测试过:
function dbConnect() {
try {
$conn = new PDO("mysql:host=". $mysql_host .";dbname=" . $mysql_db ."", $mysql_username, $mysql_password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch(PDOException $e)
{
error_log("PDO connection failed: " . $e->getMessage());
die("Application failure, please contact administrator");
}
}
class User {
protected $row;
public function __construct($userid) {
global $conn;
if (!isset($conn)) {
$conn = dbConnect();
}
$stmt = $conn->prepare("SELECT username, profilepicture FROM accounts WHERE id = ? LIMIT 1");
$stmt->execute([$userid]);
$this->row = $stmt->fetch(PDO::FETCH_ASSOC);
}
function getUsername() {
return $this->row["username"]
}
function getProfilePicture() {
return $this->row["profilepicture"]
}
}
用法:
$user = new User(123);
$username = $user->getUsername();
$profilePicture = $user->getProfilePicture();
关于php - 使用函数从数据库中获取内容。这安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39377763/