2

データベース クラスに問題があります。1 つの準備済みステートメントと任意の数のパラメーターを取り、それらをステートメントにバインドし、ステートメントを実行し、結果を多次元配列にフォーマットするメソッドがあります。パラメータの1つに電子メールアドレスを含めようとするまで、すべてが正常に機能します。電子メールに @ 文字が含まれており、その文字がすべてを壊しているように見えます。パラメータを指定すると:

$types = "ss" and $parameters = array("email@domain.com", "testtest")

エラーが発生します:

警告: mysqli_stmt_bind_param() へのパラメータ 3 は参照であると予想されます。値は 63 行目の ...db/Database.class.php で指定されています

メソッドは次のとおりです。

private function bindAndExecutePreparedStatement(&$statement, $parameters, $types) {
    if(!empty($parameters)) {
        call_user_func_array('mysqli_stmt_bind_param', array_merge(array($statement, $types), &$parameters));
        /*foreach($parameters as $key => $value) {
            mysqli_stmt_bind_param($statement, 's', $value);
        }*/
    }

    $result = array();

    $statement->execute() or debugLog("Database error: ".$statement->error);

    $rows = array();

    if($this->stmt_bind_assoc($statement, $row)) {
        while($statement->fetch()) {
            $copied_row = array();
            foreach($row as $key => $value) {
                if($value !== null && mb_substr($value, 0, 1, "UTF-8") == NESTED) { // If value has a nested result inside
                    $value = mb_substr($value, 1, mb_strlen($value, "UTF-8") - 1, "UTF-8");
                    $value = $this->parse_nested_result_value($value);
                }
                $copied_row[$ke<y] = $value;
            }
            $rows[] = $copied_row;
        }
    }

    // Generate result
    $result['rows'] = $rows;
    $result['insert_id'] = $statement->insert_id;
    $result['affected_rows'] = $statement->affected_rows;
    $result['error'] = $statement->error;

    return $result;
}

私は次のような 1 つの提案を得ました。

array_merge は、マージでパラメーターを文字列にキャストしているため、参照のままになるように &$parameters に変更します

だから私はそれを試しました(メソッドの3行目)が、何の違いもありませんでした。

どうすればいいですか?call_user_func_array なしでこれを行うより良い方法はありますか?


更新:これを解決するあまりきれいではない方法を見つけました。私がしたことは、ループを使用して新しい参照配列を作成し、代わりにそれを使用することでした。

private function bindAndExecutePreparedStatement($statement, $parameters, $types)
{
    if(!empty($parameters)) {
        $parameters_references = array();
        foreach($parameters as $key => $parameter) {
            $parameters_references[] = &$parameters[$key]; 
        }
        call_user_func_array('mysqli_stmt_bind_param', 
            array_merge(array($statement, $types), $parameters_references)); 
    } 
    .... 

私はまだ PDO でこれを解決することに興味があります。他にも多くの機能があるようです。私はまだそれを使用することを学んでいません。

4

1 に答える 1

1

Zend Framework の MySQLi アダプターにパラメーター バインディング コードを記述しました。MySQLi のパラメータ バインディング API は使いにくいと思います。参照する必要があるのは配列ではなく、配列の各要素です。

_execute()このクラスのメソッドで 私が書いたコードを見ることができます: http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Db/Statement/Mysqli.php

PDOをチェックすることをお勧めします。はるかに使いやすいです。パラメーターをバインドできますが、パラメーター値の配列を配列として PDOStatement のexecute()メソッドに渡すだけの方が簡単です。

于 2010-05-29T17:18:05.497 に答える