1

次のコードを実行して、最初の試行でテーブルに挿入することができました。次に、PHPMyAdminでその行を削除して、コードをさらにテストしました。また、1回目の試行で削除されなかったことにも気づきました。数回試した後でのみ。これは、クエリが完了した後、$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です。

コードに問題がありますか、それともデータベースに問題がありますか?

更新/解決策:

PDO :: exec()に関するPHPドキュメントを読みましたが、ユーザーが投稿したメモの1つに、SELECTステートメント(上記ではカウント値のみが返される場合でも)および行を返す可能性のあるステートメントは使用できないと記載されています。 。PDO :: exec()の戻り値は、影響を受ける行(整数)の数であるため、PDOStatement :: closeCursor()を使用して解決することはできません。PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY => trueを設定しても、機能しません。

したがって、SELECTにはPDO :: exec()を使用しないでください。以下のように、コードを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ドキュメントを読むことを忘れないでください。

4

2 に答える 2

1

答えではないかもしれませんが、明らかなエラーが表示されない場合にできることをいくつか示します。

execute が false を返す場合、次の方法で発生したエラーに関する詳細情報を取得できます。

$arr = $statement->errorInfo(); 
print_r($arr);

または、別のエラー報告モードを設定できます(たとえば、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 を設定してクエリのバッファリングを有効にすることができます」

この場合、次の 2 つのオプションがあります。

バッファリングされたクエリを使用するオプションを設定できます

$dbh = new PDO(’mysql:host=localhost;dbname=test’, ‘root’, ” ,array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)) 

または、コードを変更して開いているカーソルを閉じます (使用している db ドライバーに依存する場合があります)。多くのデフォルトの問題をカバーするドキュメントを常に読む必要があります。

お役に立てれば。

于 2012-07-15T18:47:06.723 に答える
0

メソッドがUserAccessクラス内にあり、渡す接続がローカルに設定されていると想定しています$this->connObject

レコードを削除した後、selectステートメントを使用した興味深いdo-whileループで$customerIdがnullに設定されていると思われます。DBのid列がnull以外の主キーフィールドであり、明示的なnullを挿入しようとすると、失敗します。

また、DB接続をnullに設定し続ける必要はありません...これはCではなく、接続は永続的ではありません(明示的に宣言しない限り)。

于 2012-07-15T17:59:51.573 に答える