How can I put the results of a MySQLi prepared statement into an associative array?

后端 未结 7 1377
清酒与你
清酒与你 2020-12-01 09:54

I have a sql query and a mysqli prepared statement:

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


        
相关标签:
7条回答
  • 2020-12-01 10:23

    Try the following:

    $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(); 
    

    First you get the query metadata and from that obtain all the fields you've fetched (you could do this manually, but this code works for all queries rather than building by hand). The call_user_func_array() function calls the mysqli_stmt::bind_result() function for you on each of those parameters.

    After that it is just a matter of running through each row and creating an associative array for each row and adding that to an array resulting in all the results.

    0 讨论(0)
  • 2020-12-01 10:28

    Update: Since PHP 5.3.0 you can get a mysqli_result object that provides a fetch_array method.

    $sql = 'SELECT photographers.photographer_id, photographers.photographer_name
        FROM photographers';
    $data = null;
    
    $stmt = $conn->stmt_init(); 
    if ($stmt->prepare($sql)) { 
        $stmt->bind_result($photographer_id, $photographer_name);  
        $OK = $stmt->execute();
        $result = $stmt->get_result();
        $data = $result->fetch_array();
    }
    

    Documentation: http://php.net/manual/en/mysqli-stmt.get-result.php

    0 讨论(0)
  • 2020-12-01 10:31

    I came across this discussion in order to find a solution for getting data from MySQLi prepared statements without the mysqlnd. I have been developing a class for handling prepared statements with MySQLi in a handy way. Please, take a look to the code, or simply use it (see an example of usage at the end of the piece of code) to fastly write prepared statements and get its results.

    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!
    
    0 讨论(0)
  • 2020-12-01 10:39

    Oddly enough, you can't. There's simply no way to get a mysqli_result object from a mysqli_stmt instance. I've always considered this a major flaw, and would guess that this is one of the major reasons that mysqli never reached any real popularity. These days it's been pretty much superseded by PDO, which does what you want with out effort.

    Edit: My answer only means that you can't do it by default. Of course you can implement it yourself, like Chris suggested. Still, I think you should use PDO instead, if it's at all possible.

    0 讨论(0)
  • 2020-12-01 10:41

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

    His answer is one way for previous versions of php as "call_user_method_array" was DEPRECATED in PHP 4.1.0, and REMOVED in PHP 7.0.0.

    So I find it relevant to post an updated answer, for at least PHP7, since I have recently found myself without the MYSQLND native driver for the MYSQLI extention on a new host I've transferred to. Yay!...

    Note: There are 2 functions here. The last one is required. It is the only way I know it all to work. (EDITING The answer doesn't produce an associative array... Fixed)

        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; 
        }
    
    0 讨论(0)
  • 2020-12-01 10:44

    A simple one that actually surprisingly works. I know it's procedural, but still:

    $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);
    
    0 讨论(0)
提交回复
热议问题