10

SQL クエリと mysqli 準備済みステートメントがあります。

$sql = 'SELECT photographers.photographer_id, photographers.photographer_name
    FROM photographers';

$stmt = $conn->stmt_init(); 
if ($stmt->prepare($sql)) { 
    $stmt->bind_result($photographer_id, $photographer_name);  
    $OK = $stmt->execute(); 
    $stmt->fetch();
}

結果を連想配列に保存して、後でループして、SQL 文字列によって返されるすべてのデータを取得するにはどうすればよいですか?

4

7 に答える 7

29

次のことを試してください。

$meta = $statement->result_metadata(); 

while ($field = $meta->fetch_field()) { 
    $params[] = &$row[$field->name]; 
} 

call_user_func_array(array($statement, 'bind_result'), $params);            
while ($statement->fetch()) { 
    foreach($row as $key => $val) { 
        $c[$key] = $val; 
    } 
    $hits[] = $c; 
} 
$statement->close(); 

最初にクエリ メタデータを取得し、そこから取得したすべてのフィールドを取得します (これは手動で行うこともできますが、このコードは手動で構築するのではなく、すべてのクエリで機能します)。関数は、これらのパラメーターごとに関数をcall_user_func_array()呼び出します。mysqli_stmt::bind_result()

その後、各行を実行し、各行の連想配列を作成し、それを配列に追加してすべての結果を得るだけです。

于 2009-06-14T23:56:13.667 に答える
1

奇妙なことに、できません。mysqli_stmt インスタンスから mysqli_result オブジェクトを取得する方法はありません。私はいつもこれを重大な欠陥と考えてきました。そして、これが mysqli が真の人気に達しなかった主な理由の 1 つだと推測します。最近では、労力をかけずに必要なことを行う PDO にほとんど取って代わられています。

編集:私の答えは、デフォルトではできないということだけを意味します。もちろん、クリスが提案したように、自分で実装することもできます。それでも、可能であれば、代わりに PDO を使用する必要があると思います。

于 2009-06-14T23:48:58.503 に答える
1

mysqlnd を使用せずに MySQLi の準備済みステートメントからデータを取得するための解決策を見つけるために、この議論に出くわしました。私は、MySQLi で準備済みステートメントを便利な方法で処理するためのクラスを開発しています。コードを確認するか、単純に使用して (コードの末尾にある使用例を参照)、準備済みステートメントをすばやく作成してその結果を取得してください。

class DbUtils {

    private $host;
    private $user;
    private $pass;
    private $database;
    private $connection;

    public function __construct($host, $user, $pass, $database) {

        $this->host = $host;
        $this->user = $user;
        $this->pass = $pass;
        $this->database = $database;
        $this->connection = new mysqli($host, $user, $pass, $database);

    }

    public function query(Array $params) {

        $args = array();

        // 0. Correct the input function parameters
        if (array_key_exists("query", $params)) {
            $args["query"] = $params["query"];
        } else {
            throw new Exception("Parameter not found: 'query'.");
        }
        if (array_key_exists("types", $params)) {
            $args["types"] = $params["types"];
        } else {
            $args["types"] = '';
        }
        if (array_key_exists("input", $params)) {
            $args["input"] = $params["input"];
        } else {
            $args["input"] = array();
        }

        // 1. Check the connection:
        if ($this->connection->connect_errno) {
            echo "Connection to MySQL failed: [" . $this->connection->connect_errno . "]: " . $this->connection->connect_error . "<br/>";
        }

        // 2. Prepare the sentence:
        if (!($stmt = $this->connection->prepare($args["query"]))) {
            echo "Prepared statement failed: [" . $stmt->errno  . "]: " . $stmt->error . "<br/>";
        }

        // 3. Bind the input parameters:
        if ( ( 0 != sizeof( $args["input"] ) ) && !(call_user_method_array("bind_param", $stmt, array_merge(array($args["types"]), $args["input"])))) {
            echo "Binding parameters failed: [" . $stmt->errno . "]: " . $stmt->error . "<br/>";
        }

        // 4. Execute the sentence
        if (!($stmt->execute())) {
            echo "Sentence execution failed: [" . $stmt->errno . "]: " . $stmt->error . "<br/>";
        }

        // 5. Bind the results:
        $data = array();
        $meta = $stmt->result_metadata();
        $row = array();
        while( $field = $meta->fetch_field() ) {
            $argos[] = &$row[$field->name];
        }
        call_user_method_array('bind_result', $stmt, $argos);

        // 6. Collect the results:
        while ($stmt->fetch()) {
            foreach($argos as $key => $val) { 
                $dataItem[$key] = $val; 
            } 
            $data[] = $dataItem;
        }

        // 7. Close the sentence:
        $stmt->close();

        // 8. Return interesting data properly ordered:
        return $data;
    }

}

// 1. Instantiate it:
$dbUtils = new DbUtils(
    "127.0.0.1", 
    "user", 
    "password", 
    "database"
);

// 2. Query prepared statements like this:
$users = $dbUtils->query(array(
    "query" => "SELECT * FROM user WHERE name LIKE ? AND pass LIKE ?;",
    "input" => array('%', '%'),
    "types" => 'ss'
));

// 3. Enjoy securely CRUD Ops!
于 2016-01-28T00:11:59.323 に答える
1

実際に驚くほど機能するシンプルなもの。私はそれが手続き型であることを知っていますが、それでも:

$query = "SELECT * FROM foo WHERE bar = ?;";

$stmt = mysqli_prepare($dbc, $query);

mysqli_stmt_bind_param($stmt, "s", $bar);

mysqli_stmt_execute($stmt);

$result = mysqli_stmt_get_result($stmt);

return mysqli_fetch_assoc($result);
于 2016-08-01T07:39:05.390 に答える
0

PDO 拡張機能を使用できない場合。または、準備済みステートメントを使用してデータベース クラスを構築する際に問題が発生しています。挿入、更新、削除、および挿入の使用方法:

    $db = new database();
    $db->query = "INSERT INTO blabla (name,date,number) VALUES(?,?,?)";
    $db->params = array($name,$date,$number);
    $db->type = 'ssi'; //s=string,i=integer
    if($db->insert())
        echo 'success';

フェッチは少し異なります

    $array = array();
    $db = new database();
    $db->query = "SELECT * FROM blabla WHERE id=? and someother=?";
    $db->params = array($id,$other);
    $db->type = 'is';
    $r = $db->fetch(); 
    //$r[0]['id'] for row 1
    //$r[0]['name'] for row 1
    //$r[1] .... For row 2
    //$r[2] .... For row 3
    //etc...

データベースクラスについて

    class database {

        private $stmt;
        private $mysqli;
        private $query;
        private $params = array();
        private $type;

        public function __set($name, $value) {
            switch ($name) {
                case 'params':
                    $this->params = $value;
                    break;
                case 'query':
                    $this->query = $value;
                    break;
                case 'type':
                    $this->type = $value;
                    break;
                default:
                    break;
            }
        }

        public function __get($name) {
            if ($name !== "mysqli" && $name !== "stmt")
                return $this->$name;
        }

        public function __construct() {
            $this->mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
            $this->stmt = $this->mysqli->stmt_init();
        }

        private function close_con($bool) {
            if ($bool) {
                $this->stmt->free_result();
            }
            $this->stmt->close();
            $this->mysqli->close();
        }

        private function nofetch() {
            $this->stmt->prepare($this->query);
            $bind_names[] = $this->type;
            for ($i = 0; $i < count($this->params); $i++) {
                $bind_name = 'bind' . $i;
                $$bind_name = $this->params[$i];
                $bind_names[] = &$$bind_name;
            }
            call_user_func_array(array($this->stmt, "bind_param"), $bind_names);

            if ($this->stmt->execute()) {

                $this->close_con(false);
                return true;
            }
            $this->close_con(false);
            return false;
        }

        public function insert() {
            if ($this->nofetch()) {
                return true;
            }
            return false;
        }

        public function update() {
            if ($this->nofetch()) {
                return true;
            }
            return false;
        }

        public function delete() {
            if ($this->nofetch()) {
                return true;
            }
            return false;
        }

        public function fetch() {
            $result_out = array();
            $this->stmt->prepare($this->query);
            $bind_names[] = $this->type;
            if (count($this->params) > 0) {
                for ($i = 0; $i < count($this->params); $i++) {
                    $bind_name = 'bind' . $i;
                    $$bind_name = $this->params[$i];
                    $bind_names[] = &$$bind_name;
                }
                call_user_func_array(array($this->stmt, "bind_param"), $bind_names);
            }
            if ($this->stmt->execute()) {
                $result = $this->stmt->result_metadata();
                $cols = $result->fetch_fields();
                foreach ($cols as $col) {

                    $name = str_replace("-", "_", $col->name);

                    $$name = null;
                    if ($name == null)
                        $name = 'name';
                    $bindarray[$name] = &$$name;
                }

                call_user_func_array(array($this->stmt, 'bind_result'), $bindarray);
                $this->stmt->store_result();
                $copy = create_function('$a', 'return $a;');
                while ($this->stmt->fetch()) {
                    $result_out[] = array_map($copy, $bindarray);
                }
            }
            $this->close_con(true);
            return $result_out;
        }

    }

これが役立つことを願っています

于 2012-04-25T08:31:12.267 に答える
0

https://stackoverflow.com/users/5849505/carl-gentleman

彼の答えは、「call_user_method_array」が PHP 4.1.0 で廃止され、PHP 7.0.0 で削除されたため、以前のバージョンの php の 1 つの方法です。

したがって、少なくともPHP7については、更新された回答を投稿することが適切であることがわかりました。最近、転送先の新しいホストでMYSQLIエクステンションのMYSQLNDネイティブドライバーがないことに気付いたからです。わーい!...

注: ここには 2 つの機能があります。最後の 1 つは必須です。それが私がすべてを知っている唯一の方法です。(編集 答えは連想配列を生成しません...修正済み)

    public function arr($query, $data, $format) { // Some parts have been used from others. I don't know who.
                                        $d = array();
                                        $row = array();
            // 1. Connect to the database // This is how I do it
                                        $db = $this->con;
            // 2. Prepare the sentence:
            if( !($stmt = $db->prepare($query)) ) { 
                                        echo "Prepared statement failed: [" . $stmt->errno  . "]: " . $stmt->error . "<br>";
                                        $d[0] = false;// I return an object array so [0] I can check later. It is true or false however I define it.
                                        return $d; 
            }

                                        // cast to array
                                        $data = (array) $data; 
                                        $format = (array) $format; 

                                        //Normalize format
                                        $format = implode('', $format); 
                                        $format = str_replace('%', '', $format);

                                        // Prepend $format onto $values
                                        array_unshift($data, $format);

            // 3. Bind the input parameters: (note "call_user_func_array" is not depriciated)
            if ( !(call_user_func_array( array( $stmt, 'bind_param'), $this->ref_values($data) )) ) {
                                        echo "Binding parameters failed: [" . $stmt->errno . "]: " . $stmt->error . ";<br>";
            }

            // 4. Execute the sentence
            if ( !($stmt->execute()) ) {
                                        echo "Sentence execution failed: [" . $stmt->errno . "]: " . $stmt->error . ";<br>";
            }

            // 5. Prepare to Bind the results:
                                        $meta = $stmt->result_metadata();
            while( $field = $meta->fetch_field() ) {
                                        $argos[] = &$row[$field->name];
                                        $fld_nms[] = $field->name;
            }

            // 6. Bind the results to the argos array:
                                        call_user_func_array( array( $stmt, 'bind_result'), $argos);

                                        /* // I left some debuging tools that are helpful
                                        echo "<br>argos<br>";
                                        print_r($argos);
                                        echo "<br><br>";

                                        $class_methods = get_class_methods($stmt);

            foreach ($class_methods as $method_name) {
                echo "$method_name<br>";
            }
                                        */

            // 7. Collect the results:
            while ($ftch = $stmt->fetch()) {
                                        $dataItem = array();
                                        /*
                                        echo "<br>ftch<br>";
                                        print_r($ftch);
                                        echo "<br><br>";
                                        */
                foreach($argos as $key => $val) { 

                                        echo "Args: k:" . $key . "; v:" . $val . ";<br>";
                                        $nme = $fld_nms[$key];
                                        $dataItem[$nme] = $val; 
                                        //$dataItem[$key] = $val; 
                } 
                                        $d[] = $dataItem; // I am not interested in returning the multi level array yet but I left it
            }

            // 8. Close the sentence:
                                        $stmt->close();

            // 9. Return interesting data properly ordered:
                                        return $d;

    }
    private function ref_values($array) { 
                                        $refs = array();
        foreach ($array as $key => $value) {
                                        $refs[$key] = &$array[$key]; 
        }
                                        return $refs; 
    }
于 2019-01-16T22:35:41.580 に答える