gpt4 book ai didi

php - SQLSTATE[42000] : Syntax error or access violation: 1064

转载 作者:行者123 更新时间:2023-11-29 03:03:50 54 4
gpt4 key购买 nike

我现在正在写一些软件。读者摘要版本:用户选择一个包,输入他们的姓名、电子邮件和所需的子域。然后检查子域以查看是否有人已经注册了它,以及它是否只是字母数字。我使用 OO mysqli 完成了所有这些工作,但我决定转向 PDO。

错误的确切措辞:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '->subdomain' at line 1

当我开始实例化我的 Admin 对象时,一切都很好。然而,当我调用 createAccount() 函数时,一切都乱套了。堆栈跟踪到处都是,我几乎不知道什么时候开始解决这个问题。我在这里检查了其他答案,它们似乎都太本地化了,所以这里是生成它的代码,然后是所有包含错误的方法。我们开始吧....

首先是产生错误的代码:

include 'classes/Admin.class.php';
$admin = new Admin('test@test.com');

try {
$admin->createAccount('John', 'Smith', 'test', 'pro');
}
catch(Exception $e) {
echo '<pre />';
echo $e->getMessage();
die(print_r($e->getTrace()));
}

管理类构造函数

public function __construct($email) {
$this->email = $email;

include 'Database.class.php';
include 'PasswordHash.php';

define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASS", "");
define("DB_NAME", "ems");

$this->data = new Database;
$this->hasher = new PasswordHash(8, false);
}

在 Admin 类中,检查子域

private function checkSubdomain() {
$this->data->query('SELECT * FROM clients WHERE subdomain = :subdomain');
$this->data->bind(':subdomain', $this->subdomain);
$this->data->execute();

return ($this->data->rowCount() == 0) && (ctype_alnum($this->subdomain));
}

PDO 类执行、绑定(bind)和查询

public function execute() {
return $this->stmt->execute();
}

public function query($query) {
$this->stmt = $this->dbh->prepare($query);
}

public function bind($param, $value, $type = null) {
if(is_null($type)) {
switch(true) {
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
default:
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}

这个错误在我的代码中很普遍,所以我认为它只出现在 PDO 类中,但我的 Session 类工作得很好。此外,我的查询只使用 mysqli 就可以完美地工作,所以我对我的语法很有信心。非常感谢任何帮助。

根据请求,创建帐户功能:

public function createAccount($firstname, $lastname, $subdomain, $package)
{
$this->firstname = $firstname;
$this->lastname = $lastname;
$this->subdomain = $subdomain;
$this->package = $package;
//does the subdomain exist, or is it invalid?
if(!$this->checkSubdomain())
throw new Exception('This domain is not available. It can only contain letters and numbers and must not already be taken.');

//now comes the table creation, provided everything is in order
$this->setup();
}

这是由 createAccount 调用的设置函数(没有所有表结构):

private function setup() {
$isError = false;
$queries = array(
//all of these are CREATE statements, removed for security reasons
);

//need a database that matches with the client subdomain
$this->data->query('CREATE TABLE $this->subdomain');
$this->data->bind(':subdomain', $this->subdomain);

//PDO secured...execute
$this->data->execute();

$this->data->beginTransaction();
foreach($queries as $query) {
$this->data->query($query);
if(!$this->data->execute()) { //we hit some sort of error, time to GTFO of here
$isError = true;
$this->data->cancelTransaction();
//die('Error with: ' . $query);
break;
}
}

if(!$isError) {
$this->data->endTransaction();
mkdir('a/' . $this->subdomain, 0755);
$this->generatePass();
//this is where I insert the user into the admin table using PDO, removed for security
$this->data->execute();
}

$this->data->close();

}

最佳答案

这是导致错误的原因:

$this->data->query('CREATE TABLE $this->subdomain');
$this->data->bind(':subdomain', $this->subdomain);

正如 Michael Berkowski 和 andrewsi 在评论中指出的那样,您不能将值绑定(bind)到 :subdomain 占位符,因为它在查询中没有注明,即使它是 PDO 占位符也只能使用对于不是数据库、表或列名称的值

如果您想要动态创建那种 SQL 查询,您需要用反引号将数据库、表或列名称括起来(以防您的列和名称包含可能破坏 SQL 保留关键字的query) 和 escape values,但如果已经使用 PDO,则不能使用 MySQLi

因为 PDO 没有带有 real_escape_string() 方法来做到这一点,实际上不需要像那样转义值(除非你真的有像 Ye 这样命名的列'name 这完全是愚蠢的恕我直言),所以使用 preg_match()preg_replace() 的简单过滤器就足够了:

if (preg_match('/^[\w_]+$/i', $this->subdomain)) {
// note the ` (backtick), and using " (double quotes):
$this->data->query("CREATE TABLE `{$this->subdomain}`");
} else {
// throw exception or error, do not continue with creating table
}

在 PHP 中使用 '(单引号 - 撇号)对 "(双引号)字符串的几个例子:

$a = 1;
$b = 2;
echo '$a + $b'; // outputs: $a + $b
echo "$a + $b"; // outputs: 1 + 2
$c = array(5, 10);
echo '\$c[0] = {$c[0]}'; // outputs: \$c[0] = {$c[0]}
echo "\$c[0] = {$c[0]}"; // outputs: $c[0] = 5

双引号字符串内的 {} 用于数组和对象属性访问,可用于常规变量。
在双引号中转义 $ 是由 \$ 完成的,否则它将假设一个变量调用。

关于php - SQLSTATE[42000] : Syntax error or access violation: 1064,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18988935/

54 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com