我设法在第一次尝试时运行以下代码插入到我的表中。然后,我在PHPMyAdmin中删除了该行以进一步测试我的代码。我也注意到它在第一次尝试时没有被删除。只有经过几次尝试。这可能是因为我在完成查询后没有将$ pdoHandle设置为NULL。
然后,遗憾的是我无法在后续运行中插入新行。我甚至试图改变输入值,但是我无法插入新行。以下是我的PHP代码:
public function CreateNewCustomer($userId,$password,$name,$email)
{
$userId = filter_var($userId,FILTER_SANITIZE_STRING);
$password = filter_var($password,FILTER_SANITIZE_STRING);
$password = sha1($password);
$name = filter_var($name,FILTER_SANITIZE_STRING);
$email = filter_var($email,FILTER_SANITIZE_EMAIL);
do{
$customerId = hexdec(bin2hex(openssl_random_pseudo_bytes(4,$isStrong)));
echo $customerId;
$result = $this->connObject->exec("SELECT COUNT(id) FROM customer_tbl WHERE id=$customerId");
var_dump($result);
}while($result>0);
$statement = $this->connObject->prepare("INSERT INTO customer_tbl (id,name,email) VALUES ($customerId,:name,:email)");
$result = $statement->execute(array(':name'=>$name,':email'=>$email ));
var_dump($result);
$statement = $this->connObject->prepare("INSERT INTO login_tbl (username,password,customer_id) VALUES (:userName,PASSWORD(:password),$customerId)");
$result = $statement->execute(array(':userName'=>$userId,':password'=>$password ));
var_dump($result);
}
我使用以下代码访问上述方法。
function Test($userName,$password,$name,$email)
{
try
{
$dbConnect = new DbConnect();
$pdoHandle = $dbConnect->Connect();
$userAccess = new UserAccess($pdoHandle);
$userAccess->CreateNewCustomer($userName,$password,$name,$email);
}
catch(PDOException $e)
{
$pdoHandle = null;
var_dump($e);
}
$pdoHandle = null;
}
Test('tester','password','TestX','test@example.com');
结果的var_dump始终为false。
我的代码有问题,或者数据库有问题吗?
UPDATE /溶液
我刚刚阅读了关于PDO :: exec()的PHP文档,并提到了一个用户提供的注释,提到你不能使用任何SELECT语句(即使你上面只返回计数值)和任何可能的语句返回一行。 PDO :: exec()的返回值是受影响的行数(整数),因此PDOStatement :: closeCursor()不能用于解决它。即使我将PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY =>设置为true,它仍然无效。
因此,不要将PDO :: exec()用于任何SELECT。我将我的代码更改为PDO :: query(),如下所示,
do{
$customerId = hexdec(bin2hex(openssl_random_pseudo_bytes(4,$isStrong)));
$statement = $this->connObject->query("SELECT COUNT(id) FROM customer_tbl WHERE id=$customerId");
$statement->execute();
}while($statement->fetchColumn(0)>0);
希望这对于寻找具有类似问题的解决方案的任何人都有帮助,并且始终记得首先阅读PHP文档,包括用户贡献。
答案 0 :(得分:1)
也许不是答案,但如果你不能看到一个明显的错误,你可以做一些事情:
如果execute返回false,您可以获取有关发生的错误的更多信息:
$arr = $statement->errorInfo();
print_r($arr);
或者您可以设置不同的error reporting modes(例如,抛出异常而不是defaultsilent模式):
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
这可以帮助您找到“真正的”错误。
事实证明(见问题下面的评论),在这种情况下,真正的错误是:
“当其他无缓冲的查询处于活动状态时,无法执行查询。 考虑使用PDOStatement :: fetchAll()。或者,如果您的代码 只会对mysql运行,你可以启用查询 通过设置PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY“
进行缓冲
在这种情况下,您有两个选择:
您可以设置使用缓冲查询的选项
$dbh = new PDO(’mysql:host=localhost;dbname=test’, ‘root’, ” ,array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true))
或更改您的代码并关闭一个打开的游标(可能取决于您正在使用的数据库驱动程序)。你总是应该阅读涵盖很多默认问题的documentation。
希望这有帮助。
答案 1 :(得分:0)
我假设该方法在UserAccess类中,并且您传入的连接设置为本地$this->connObject
。
我怀疑在你删除记录之后,$ customerId在你有趣的do-while循环中被设置为null并带有select语句。如果DB中的id列是非null主键字段,并且您尝试插入显式null,则它将失败。
此外,无需继续将数据库连接设置为null ...这不是C,连接不是持久的(除非您明确声明它们)。