كيف يمكنني وضع نتائج بيان mysqli المعدة في صفيفا مشتركا؟

StackOverflow https://stackoverflow.com/questions/994041

سؤال

لدي استعلام 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؟

هل كانت مفيدة؟

المحلول

حاول القيام بما يلي:

$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() وظيفة بالنسبة لك على كل من تلك المعلمات.

بعد ذلك مجرد مسألة تشغيل من خلال كل صف وإنشاء صفيفا مشتركا لكل صف وإضافة ذلك إلى مجموعة مما يؤدي إلى كل النتائج.

نصائح أخرى

تحديث: نظرا لأن PHP 5.3.0 يمكنك الحصول على كائن mysqli_result الذي يوفر طريقة Fetch_array.

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

توثيق: http://php.net/manual/ar/mysqli-stmt.get-result.php.

صادفت هذه المناقشة من أجل إيجاد حل للحصول على بيانات من بيانات MySQLI المعدة دون MySQLND. لقد قمت بتطوير فئة للتعامل مع البيانات المعدة مع 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!

الغريب بما فيه الكفاية، لا يمكنك ذلك. ببساطة لا توجد طريقة للحصول على كائن MySQLI_RESULT من مثيل MySQLI_STMT. لقد اعتبرت دائما هذا عيبا كبيرا، وأعتقد أن هذا هو أحد الأسباب الرئيسية التي لم تصل mysqli إلى أي شعوب حقيقي. في هذه الأيام، تم حل محلها إلى حد كبير من قبل شركة تنمية نفط عمان، والذي يفعل ما تريد بهذه الجهد.

تعديل: جوابي يعني فقط أنه لا يمكنك القيام بذلك بشكل افتراضي. بالطبع يمكنك تنفيذها بنفسك، مثل كريس المقترح. ومع ذلك، أعتقد أنه يجب عليك استخدام PDO بدلا من ذلك، إذا كان ذلك ممكنا.

إذا لم تتمكن من استخدام امتداد 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;
        }

    }

آمل أن يكون هذا مفيدا

واحد بسيط يعمل في الواقع بشكل مدهش. أعلم أنه إجرائي، ولكن لا يزال:

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

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

إجابته هي إحدى طرق الإصدارات السابقة من PHP كما تم إهمال "Call_User_Method_array" في PHP 4.1.0، وإزالتها في PHP 7.0.0.

لذلك أجد أنه مناسب لنشر إجابة محدثة، ل PHP7 على الأقل، لأنني عثرت على نفسي مؤخرا بدون برنامج تشغيل MySQLND الأصلي لمقزز MySqli على مضيف جديد قمت بنقله إليه. ياي!...

ملاحظة: هناك 2 وظائف هنا. آخر واحد مطلوب. هذه هي الطريقة الوحيدة التي أعرفها كل شيء للعمل. (تحرير الإجابة لا ينتج صفيفا مشاركا ... ثابت)

    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; 
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top