简体   繁体   English

用 PHP 的 mysqli 做准备好的语句的正确和最简单的方法是什么?

[英]What is the correct and easiest way to do prepared statements with PHP's mysqli?

I have been using the old mysql api in PHP for a long time and want to start using mysqli for both speed and security with a new project I'm working on. I have been using the old mysql api in PHP for a long time and want to start using mysqli for both speed and security with a new project I'm working on. I've looked through the manual and read several tutorials, but I'm finding a lot of conflicting and somewhat confusing information on how to do prepared statements in mysql.我浏览了手册并阅读了几个教程,但是我发现了很多关于如何在 mysql 中执行准备好的语句的相互矛盾且有些令人困惑的信息。

Is there anything in this code that doesn't need to be there, and is there anything that is missing?这段代码中是否有不需要的内容,是否缺少任何内容? Also, is this the easiest way to do something simple like this (seems somewhat involved for such a simple task)?另外,这是做这样简单的事情的最简单方法吗(对于这样一个简单的任务似乎有点涉及)?

Procedural:程序:

// build prepared statement
$query = mysqli_prepare($link, "SELECT email FROM users WHERE id = ?");

// bind parameters to statement
mysqli_stmt_bind_param($query, 's', $_GET['id']);

// execute statement
mysqli_stmt_execute($query);

// bind the variables to the result
mysqli_stmt_bind_result($query, $email);

// print the results
while (mysqli_stmt_fetch($query)) {
    echo $email;
}

// close the statement
mysqli_stmt_close($query);

// close connection
mysqli_close($link);

Object-Oriented:面向对象:

// build prepared statement
$query = $link->prepare("SELECT email FROM users WHERE id = ?");

// bind parameters to statement
$query->bind_param('s', $_GET['id']);

// execute statement
$query->execute();

// bind the variables to the result
$query->bind_result($email);

// print the results
while ($query->fetch()) {
    echo $email;
}

// close the statement
$query->close();

// close connection
$link->close();

Here's the guts of a semi-self-explanatory class that encapsulates mysqli, including prepared statements, which are quite tricky.这是一个半不言自明的 class 的内容,它封装了 mysqli,包括准备好的语句,这非常棘手。 It's pretty well tested - I've been using it for a year now without change.它经过了很好的测试 - 我已经使用它一年了,没有任何变化。

It only implements prepared statements to Execute SQL commands because they change data and often require nasty encoding tricks otherwise.它只实现准备好的语句来执行 SQL 命令,因为它们会更改数据并且通常需要讨厌的编码技巧。 If you want SELECTs, it's left as an exercise for the reader - it's easier.如果你想要 SELECT,它留给读者作为练习——它更容易。 :) :)

<?php

class Db
{
    var $_mysqli;
    var $_result;
    var $_error_msg;

    public function __construct($server, $user, $password, $name)
    {
        $this->_mysqli = new mysqli("p:".$server, $user,
                                    $password, $name);
        if($this->_mysqli->connect_errno) 
        {
            $this->_error_msg = $this->_mysqli->connect_error;
        }
    }

    public function __destruct()
    {
    }

    private function sql_select($sql)
    {
        $this->_mysqli->query("SET NAMES 'utf8'"); // a little help for UTF8 io
        $this->_result = $this->_mysqli->query($sql);
    }

    private function sql_close()
    {
        $this->_mysqli->close();
    }


    public function ErrorMessage()
    {
        return $this->_error_msg;
    }

    public function SqlRows($sql)
    {
        $rows = array();
        $result = $this->sql_select($sql);
        if($this->IsError())
        {
            return $rows;
        }
        while($row = $result->fetch_array()) 
        {
            $rows[] = $row;
        }
        $result->free();
        return $rows;
    }

    public function SqlObjects($sql)
    {
        $objects = array();
        $result = $this->sql_select($sql);
        while($object = $this->_result->fetch_object()) 
        {
            $objects[] = $object;
        }
        $result->free();
        return $objects;
    }

    public function SqlOneObject($sql)
    {

        $result = $this->sql_select($sql);
        $obj = $result->fetch_object();
        $result->free();
        return $obj;
    }

    public function SqlOneRow($sql)
    {
        $result = $this->sql_select($sql);
        if(! is_object($result))
            return null;
        if($result->num_rows > 0)
            $row = $result->fetch_array();
        else
            $row = null;
        $result->free();
        return $row;
    }

    public function SqlOneValue($sql)
    {
        $result = $this->sql_select($sql);
        if(!empty($result))
        {
            $row = $result->fetch_array();
        }
        $result->free();
        return empty($row) ? null : $row[0] ;
    }

    // returns number of affected rows
    public function SqlExecute($sql)
    {
        $this->_result = $this->_mysqli->query($sql);
        return $this->affected_rows();
    }

    private function affected_rows()
    {
        return $this->_mysqli->affected_rows;
    }

    private function IsError()
    {
        if(empty($this->_mysqli))
            return false;
        return !empty($this->_mysqli->error);
    }

    // arguments are sql and an array of 
    // argument references (not values).
    public function SqlExecutePS($sql, $args)
    {
        $stmt = $this->_mysqli->prepare($sql);

        // make the type-string
        $typestr = make_typestring($args);
        $params = array($typestr);
        $params = array_merge($params, $args);

        call_user_func_array(array($stmt, 'bind_param'), $params);
        $stmt->execute();

        $ret = $this->affected_rows();
        $stmt->close();
        return $ret;
    }

    public function SqlExists($sql)
    {
        $result = $this->SqlOneRow($sql);
        return !empty($result[0]);
    }


    function make_typestring($args)
    {
        assert(is_array($args));
        $ret = "";
        foreach($args as $arg)
        {
            switch(gettype($arg))
            {
                case "boolean":
                case "integer":
                    $ret .= "i";
                    break;
                case "double":
                    $ret .= "d";
                    break;
                case "string":
                    $ret .= "s";
                    break;
                case "array":
                case "object":
                case "resource":
                case "NULL":
                default:
                    // call it a blob and hope
                    // you know what you're doing.
                    $ret .= "b";
                    break;
            }
        }
        return $ret;
    }
} 

?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM