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

时间:2011-04-30 04:06:38

标签: php mysql mysqli prepared-statement

我已经在PHP中使用旧的mysql api很长一段时间了,并希望开始使用mysqli来提高速度和安全性,我正在开发一个新项目。我查看了手册并阅读了几个教程,但是我发现了很多关于如何在mysql中编写预处理语句的冲突和有些混乱的信息。

此代码中是否有任何内容不需要存在,是否有任何遗漏?另外,这是做这样简单的事情最简单的方法(对于这么简单的任务来说似乎有些参与)?

程序:

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

面向对象:

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

1 个答案:

答案 0 :(得分:-1)

这是一个包含mysqli的半自解释类的内容,包括准备好的语句,这些都非常棘手。它经过了相当好的测试 - 我已经使用它一年了,没有变化。

它只实现执行SQL命令的预处理语句,因为它们会更改数据,否则通常需要讨厌的编码技巧。如果你想要SELECTs,它只是作为读者的练习 - 它更容易。 :)

<?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;
    }
} 

?>