9

INSERT と SELECT を実行すると、affected_rows の取得に問題があるようですが、何らかの理由で -1 が返されるだけですか? 私は、SQL インジェクションを回避するために MYSQLI prepare ステートメントを使用するプロジェクトで常に使用するデータベース クラスを使用しています。

常に -1 を返す理由を知っている人はいますか? 私が読んだことから、INSERTとSELECTの両方で影響を受ける行を返すことができるはずです。

データベース クラス

class database {
    protected $_mysqli;
    protected $_debug;
 
    public function __construct($host, $username, $password, $database, $debug) {
        $this->_mysqli = new mysqli($host, $username, $password, $database);
        $this->_debug = (bool) $debug;
        if (mysqli_connect_errno()) {
            if ($this->_debug) {
                echo mysqli_connect_error();
                debug_print_backtrace();
            }
            return false;
        }
        return true;
    }
 
    public function q($query) {
        if ($query = $this->_mysqli->prepare($query)) {
            if (func_num_args() > 1) {
                $x = func_get_args();
                $args = array_merge(array(func_get_arg(1)),
                    array_slice($x, 2));
                $args_ref = array();
                foreach($args as $k => &$arg) {
                    $args_ref[$k] = &$arg; 
                }
                call_user_func_array(array($query, 'bind_param'), $args_ref);
            }
            $query->execute();
            
            if ($query->errno) {
              if ($this->_debug) {
                echo mysqli_error($this->_mysqli);
                debug_print_backtrace();
              }
              return false;
            }
 
            if ($query->affected_rows > -1) {
                return $query->affected_rows;
            }
            $params = array();
            $meta = $query->result_metadata();
            while ($field = $meta->fetch_field()) {
                $params[] = &$row[$field->name];
            }
            call_user_func_array(array($query, 'bind_result'), $params);
 
            $result = array();
            while ($query->fetch()) {
                $r = array();
                foreach ($row as $key => $val) {
                    $r[$key] = $val;
                }
                $result[] = $r;
            }
            $query->close(); 
            return $result;
        } else {
            if ($this->_debug) {
                echo $this->_mysqli->error;
                debug_print_backtrace();
            }
            return false;
        }
    }
 
    public function handle() {
        return $this->_mysqli;
    }
    
    public function last_insert_id()
    {
        return $this->_mysqli->insert_id;
    }

    public function found_rowss()
    {
        return $this->_mysqli->affected_rows;
    }
}
4

1 に答える 1

6

prepare で作成された Select ステートメントには、$query->num_rows() またはを使用する必要がありますmysqli_stmt_num_rows($query)

を実行すると、Insert-Statement によって抑制されたエラーが発生"INSERT IGNORE"し、-1 が発生する可能性があり$query->affected_rows()ます。

php.net のコメント (2 番目のリンク) は$query->sqlstate=="00000"、エラーのチェックに使用することを提案しています。


php.net (manual/en/mysqli-stmt.affected-rows)を参照してください:

「この関数は、テーブルを更新するクエリでのみ機能します。SELECT クエリから行数を取得するには、mysqli_stmt_num_rows()代わりに使用してください。」

およびphp.net (manual/en/mysqli.affected-rows) :

「mysqli->affected_rowsが-1に等しいかどうかを確認することは、"INSERT IGNORE"ステートメントの成功を判断するための良い方法ではありません.例:指定された一意の制約に一致する場合にのみ、ユーザーが提供したデータを含むいくつかの行を挿入するときに重複キーエラーを無視すると、 -1mysqli->affected_rows行が挿入された場合でも値を返します (MySQL 5.0.85 linux および php 5.2.9-2 ウィンドウで確認)。ただしmysqli->sqlstate 、ステートメントが正常に実行された場合はエラーを返しません。"

于 2011-11-23T14:49:02.277 に答える