PHP中对mysql预编译查询语句的一个封装

原文地址:http://chen-shan.net/?p=474

为了防止sql注入,我们都使用过mysqli这个类,但是每次都需要绑定参数,绑定结果等,比较麻烦,所以可以把这些重复的语句封装成一个函数.

一.封装前.

传统的一个预编译方式的”select”查询代码:

$id = "1";
$name = "test_name";

$db_obj = new mysqli("localhost", "db_user", "db_passwd", "db");
$db_obj->set_charset("utf8");

$query = "SELECT column1, column2, column3, column4 FROM tb_test WHERE id = ? and name = ?";
$stmt = $db_obj->prepare($query);
$stmt->bind_param("is", $id, $name);
$stmt->execute();

$stmt->bind_result($column1, $column2, $column3, $column4);
while ($stmt->fetch()) {
    $result = array();
    $result[‘column1‘] = $column1;
    $result[‘column2‘] = $column2;
    $result[‘column3‘] = $column3;
    $result[‘column4‘] = $column4;
    $results[] = $result;
}

/* The result stored in array $results */
print_r($results);

二.封装后.

封装函数 (忘了是根据php手册中哪条评论修改得来的了) 如下:

/*
 * 执行预编译形式的mysql语句
 *
 * @$query       (string)  --  查询语句,例如:"SELECT * FROM table WHERE id = ?"
 * @$params     (array)  --  绑定参数,例如:array(‘i‘, $id)
 * @$resultFlag (string)  --  是否为含有返回结果的查询,注意!!!: 为“select”查询时为“false”,为“insert”,"delete" 与 "update" 时为“true”
 * @$closeFlag  (string)  --  是否关闭数据库连接句柄, 关闭为 "ture", 不关闭为 "false"
 */

function _queryStmt($db_obj, $query, $params, $resultFlag, $closeFlag) {
    $mysqli = $db_obj;

    $stmt = $mysqli->prepare($query);
    call_user_func_array(array($stmt, ‘bind_param‘), _refValues($params));   //绑定参数
    $stmt->execute();

    //$resultFlag为true,则为“insert”,"delete" 与 "update"操作,无需绑定结果;false则为 “select”操作,需要绑定查询结果.
    if ($resultFlag) {

        $result = $mysqli->affected_rows;   //进行了修改的行数

    } else {

        $meta = $stmt->result_metadata();

        //将结果绑定数组元素设置为引用状态,因为call_user_func_array(array($stmt, ‘bind_result‘), $parameters)中的回调函数参数$parameters需要引用状态.
        while ($field = $meta->fetch_field()) {
            $parameters[] = &$row[$field->name];
        }

        call_user_func_array(array($stmt, ‘bind_result‘), _refValues($parameters));  //绑定结果

        //有多行记录时将多行记录存入$results数组中.
        while ($stmt->fetch()) {
            $x = array();
            foreach ($row as $key => $val) {
                $x[$key] = $val;
            }
            $results[] = $x;
        }

        $result = $results;
    }

    $stmt->close();

    //$closeFlag为true则需要关闭数据库句柄
    if($closeFlag) {
        $mysqli->close();
    }

    return $result;
}

/*
 * 作用:把返回的数组中的元素变为引用状态.
 * (如果$arr为含有引用状态元素的数组,则会影响调用者的参数数组,反之则反)
 */

function _refValues($arr) {
    if (strnatcmp(phpversion(), ‘5.3‘) >= 0) { //Reference is required for PHP 5.3+
        $refs = array();
        foreach ($arr as $key => $value) {
            $refs[$key] = &$arr[$key];
        }
        return $refs;
    }
    return $arr;
}

封装函数中有两点需要注意:一个是mysqli_stmt::bind_param方法与mysqli_stmt::bind_result方法都为可变函数,所以需要使用call_user_func_array()这个函数进行回调;第二个是以上两个方法所需要的参数都为引用形式,所以在使用call_user_func_array()函数进行回调时要特别小心,所以才有封装函数中_refValues()的必要.

调用如下:

$id = "1";
$name = "test_name";

$db_obj = new mysqli("localhost", "db_user", "db_passwd", "db");
$db_obj->set_charset("utf8");

$query = "SELECT column1, column2, column3, column4 FROM tb_test WHERE uid = ? and name = ?";
$params = array("is", $id, $name);
$results = _queryStmt($db_obj, $query, $params, FALSE, TRUE);

/* The result stored in array $results */
print_r($results);

这里只是举例了 “SELECT” 语句,此函数还可以应用于 “INSERT”, “DELETE”, “UPDATE”等, 只是要注意把函数_queryStmt()中的第四个参数设为 TRUE,因为没有记录数据的返回.

封装的函数也可以当作你mysql操作类中的一个方法.使用形式可以多种多样!

时间: 2024-10-04 05:50:36

PHP中对mysql预编译查询语句的一个封装的相关文章

hibernate预编译SQL语句中的setParameter和setParameterList

使用预编译SQL语句和占位符参数(在jdbc中是?),能够避免因为使用字符串拼接sql语句带来的复杂性.我们先来简单的看下,使用预编译SQL语句的好处.使用String sql = "select * from Student where name=" + name;如果name的值是1或 "aty"或"aty'aty",就会产生下面错误的sql --ORA-01722 invalid number select * from student w

python 3 mysql sql逻辑查询语句执行顺序

python 3 mysql sql逻辑查询语句执行顺序 一 .SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN <right_table> ON <join_condition> WHERE <where_condition> GROUP BY <group_by_list> HAVING <havin

跟王老师学MySQL: 基本查询语句

跟王老师学MySQL: 基本查询语句 主讲教师:王少华   QQ群号:483773664 学习内容 查询语句的基本语法 查询数据指从数据库中获取所需要的数据.MySQL中是使用SELECT语句来查询数据的 一.select的基本语法形式如下 1 2 3 4 5 SELECT  属性列表  FROM  表名 [ WHERE  条件表达式1 ] [ GROUP BY  属性名1  [ HAVING 条件表达式2 ] ] [ ORDER BY  属性名2  [ ASC | DESC ] ] 属性列表:

mysql单表查询语句优化

Mysql语句优化 范例1:优化语句SELECT * FROM `tbl_order_buy_eta` WHERE `id_order`=1843 #通过explain分析语句结果如下 mysql> explain SELECT * FROM `tbl_order_buy_eta` WHERE `id_order`=1843\G *************************** 1. row ***************************            id: 1   se

MySQL知识树-查询语句

在日常的web应用开发过程中,一定会涉及到数据库方面的操作,其中查询又是占绝大部分的.我们不仅要会写查询,最好能系统的学习下与查询相关的知识点,这篇文章我们就来一起看看MySQL查询知识相关的树是什么样的. MySQL查询知识树: 一.查询的种类 二.查询的原理 三.查询的应用场景 四.查询的效率比较 五.如何进行查询优化 六.与查询相关的知识扩展 一.查询的种类 MySQL的查询可以分为内连接查询.左连接查询.右连接查询.联合查询. ①内连接是通过关联表中共有的列来匹配出记录,查询出来的数据是

转载《mysql 一》:mysql的select查询语句内在逻辑执行顺序

原文:http://www.jellythink.com/archives/924 我的抱怨 我一个搞应用开发的,非要会数据库,这不是专门的数据库开发人员干的事么?话说,小公司也没有数 据库开发人员这么个职位吧.好吧,对数据库最深的印象还停留在大学<数据库原理>这堂课上,什么第一范式,第二范式…,这些理论的东西,多多少少还是记得 点,至于更深层次的,我不会.所以呢,撸起袖子,开始学习吧. 干程序员,最不怕的就是学习,如果你连学习都怕了,那还是早点退出这行吧.你说是吧.而我今天这篇文章,既不总结

mysql预编译处理(mysqli、PDO)

DML语句预编译: MysqLi: <?php $mysqli = new mysqli("localhost","root","root","dbname"); $mysqli->query("set names utf8"); $sql = 'insert into user(id,name,age,email) values (?,?,?,?)'; $mysqli_stmt = $mysq

MySQL学习——SQL查询语句(连接查询&amp;子查询)(三)

一:连接查询: 连接查询是将俩个或者俩个以上的表按照某个条件连接起来,从中选择需要的数据,连接查询同时查询俩个或者俩个以上的表时使用,当不同的表中存在表示相同意义的字段时,可以通过该字段来连接这几个表,例如,学生表中有course_id字段来表示所学课程的课程号,课程表中有num字段来表示课程号,那么可以通过学生表中的course_id字段与课程表中的num字段来进行连接查询,连接查询包括内连接查询和外连接查询. 1.1 内连接查询 内连接查询是一种常用的连接查询,内连接查询可以查询俩个或者以上

MySQL的逻辑查询语句的执行顺序

阅读目录 一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析 一 SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN <right_table> ON <join_condition> WHERE <where_condition>