【问题标题】:What is the correct and easiest way to do prepared statements with PHP's mysqli?用 PHP 的 mysqli 做准备好的语句的正确和最简单的方法是什么?
【发布时间】:2011-04-30 04:06:38
【问题描述】:

我在 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();

【问题讨论】:

  • 我的建议是跳过 MySQLi 直接进入 PDO。 PDOStatement 类有一个非常清晰一致的界面
  • 你应该跳过mysqli直接去PDO。你为什么坚持使用程序代码?!
  • @Phil,谢谢,我会看看 PDO。
  • @teresko,我一直在做程序,所以我不知道在这个项目上跳入 OO 是否是一个好主意(有点时间紧迫)。
  • 哦,刚刚注意到 PDO 只是 OO,所以也许我应该继续尝试一下。不过,从学习的角度来看,我仍然对我原来的问题感兴趣。

标签: php mysql mysqli prepared-statement


【解决方案1】:

这是一个封装了 mysqli 的半不言自明的类的内容,包括准备好的语句,这非常棘手。它经过了很好的测试 - 我已经使用了一年了,没有任何变化。

它只实现准备好的语句来执行 SQL 命令,因为它们会更改数据并且通常需要讨厌的编码技巧。如果你想要 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;
    }
} 

?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 2011-07-09
    相关资源
    最近更新 更多