zoukankan      html  css  js  c++  java
  • PHP PDO prepare()、execute()和bindParam()方法详解

    每次将查询发送给MySQL服务器时,都必须解析该查询的语法,确保结构正确并能够执行。这是这个过程中必要的步骤,但也确实带来了一些开销。做一次是必要的,但如果反复地执行相同的查询,批量插入多行并只改变列值时会怎么样呢?预处理语句会在服务器上缓存查询的语法和执行过程,而只在服务器和客户端之间传输有变化的列值,以此来消除这些额外的开销。

    PDO为支持此特性的数据库提供了预处理语句功能。因为MySQL支持这个特性,所以可以在适当时使用预处理语句。

    预处理语句是使用两个方法实现的:prepare()方法负责准备要执行的查询,execute()方法使用一组给定的列参数反复地执行查询。这些参数可以显式地作为数组传递给execute()方法,也可以使用通过bindParam()方法指定的绑定参数提供给execute()方法。


    使用预处理语句——prepare()方法

    prepare()方法负责准备要执行的查询。语法格式如下:

    PDOStatement PDO::prepare(string statement[,array driver_options])

    但是,用作准备语句的查询与以住使用的查询略有区别,因为对于每次执行迭代中要改变的值,必须使用占位符而不是具体的列值。

    查询支持两种不同的语法:命名参数和问号参数。

    使用命名参数的查询如下:

    INSERT INTO tb_chengji SET xuesheng=:xuesheng,yuwen=:yuwen;

    其中,:xuesheng与:yuwen都是列占位符。

    使用问号参数的查询如下:

    INSERT INTO tb_chengji SET xuesheng=?,yuwen=?;

    其中,?也是列占位符。

    选择哪一种语法都可以,但是前者更明确一些。

    下面使用prepare()方法准备一个用于迭代执行的查询:

    <?php
    $pdo=new PDO($dsn,$user,$pwd);  // 连接数据库
    $query="INSERT INTO tb_chengji SET xuesheng=:xuesheng,yuwen=:yuwen";
    $result=$pdo->prepare($query);
    ?>

    上面的代码将查询准备好了。继续下面的操作。


    执行准备查询——execute()方法

    execute()方法负责执行准备好的查询。语法格式如下:

    bool PDOStatement::execute([array input_parameters])

    该方法需要有每次迭代执行中替换的输入参数。这可以通过两种方法实现:作为数组将值传递给方法,或者通过bindParam()方法把值绑定到查询中相应的变量名或位置偏移。

    下面介绍第一种方法,第二种方法在bindParam()方法中介绍。

    实例代码中准备了一条语句并通过execute()方法反复执行,每次使用不同的参数:

    <?php
    $pdo=new PDO($dsn,$user,$pwd);  // 连接数据库
    $query="INSERT INTO tb_chengji SET xuesheng=:xuesheng,yuwen=:yuwen";
    $result=$pdo->prepare($query);
    
    $result->execute(array(':xuesheng'=>'赵天平',':yuwen'=>'90'));  // 执行一次
    $result->execute(array(':xuesheng'=>'张冬雪',':yuwen'=>'115')); // 再执行一次
    ?>

    下面通过使用bindParam()方法进行绑定来传递查询参数。


    绑定参数——bindParam()方法

    execute()方法中的input_parameters参数是可选的,虽然很方便,但是如果需要传递多个变量时,以这种方式提供数组会很快变得难以处理(当数组元素过多时,也就是当数据表中的列过多时,代码设计会变得特别难以阅读或出错)。使用bindParam()方法可以解决这个问题。语法格式如下:

    boolean PDOStatement::bindParam(mixed parameter,mixed &variable[,int datatype
                                    [,int length[,mixed driver_options]]])

    parameter:当在prepare()方法中使用命名参数时,parameter是预处理语句中使用语法(例如:xuesheng)指定的列值占位符的名字;使用问号参数时,parameter是查询中列值占位符的索引偏移。

    variable:该参数存储将赋给占位符的值。它按引用传递,因为结合准备存储过程使用此方法时,可以根据存储过程的某个动作修改这个值。

    datatype:该参数显式地设置参数的数据类型,可以为以下值:

    • PDO_PARAM_BOOL:SQL BOOLEAN类型。
    • PDO_PARAM_INPUT_OUTPUT:参数传递给存储过程时使用此类型,因此,可以在过程执行后修改。
    • PDO_PARAM_INT:SQL INTEGER数据类型。
    • PDO_PARAM_NULL:SQL NULL数据类型。
    • PDO_PARAM_LOB:SQL大对象数据类型。
    • PDO_PARAM_STMT:PDOStatement对象类型,当前不可操作。
    • PDO_PARAM_STR:SQL CHAR、VARCHAR和其它字符串数据类型。

    length:该参数指定数据类型的长度。只有当赋为PDO_PARAM_INPUT_OUTPUT数据类型时才需要这个参数。

    driver_options:该参数用来传递任何数据库驱动程序特定的选项。

    下面修改前面的实例,使用bindParam()方法来赋列值:

    <?php
    $pdo=new PDO($dsn,$user,$pwd);  // 连接数据库
    $query="INSERT INTO tb_chengji SET xuesheng=:xuesheng,yuwen=:yuwen";
    $result=$pdo->prepare($query);
    
    $xuesheng='赵天平';
    $yuwen='90';
    $result->bindParam(':xuesheng',$xuesheng);
    $result->bindParam(':yuwen',$yuwen);
    $result->execute();
    
    $xuesheng='张冬雪';
    $yuwen='115';
    $result->bindParam(':xuesheng',$xuesheng);
    $result->bindParam(':yuwen',$yuwen);
    $result->execute();
    ?>

    如果使用问号参数,语句则如下所示:

    $query="INSERT INTO tb_chengji SET xuesheng=?,yuwen=?";

    因此对应的bindParam()方法调用如下:

    $xuesheng='赵天平';
    $yuwen='90';
    $result->bindParam(1,$xuesheng);
    $result->bindParam(2,$yuwen);
    ......
    $xuesheng='张冬雪';
    $yuwen='115';
    $result->bindParam(1,$xuesheng);
    $result->bindParam(2,$xuesheng);
    

    实例

    在执行下面的实例代码之前,tb_chengji数据表中的数据记录如下图所示:

    tb_chengji数据表中原来的记录

    执行下面的实例代码:

    复制代码
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>PHP PDO prepare()、execute()和bindParam()方法详解实例-www.baike369.com</title>
    </head>
    <body>
    <?php
    $dbms='mysql';
    $dbname='db_xuesheng';
    $user='root';
    $pwd='1234';
    $host='localhost';
    $dsn="$dbms:host=$host;dbname=$dbname";
    try{
      $pdo=new PDO($dsn,$user,$pwd);
      $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
      $query="INSERT INTO tb_chengji SET xuesheng = :xuesheng,yuwen = :yuwen,shuxue = :shuxue,yingyu = :yingyu";
      $result=$pdo->prepare($query);
    
      $result->execute(array(":xuesheng"=>"周一刚",":yuwen"=>"55",":shuxue"=>"80",":yingyu"=>"78"));
      $result->execute(array(":xuesheng"=>"胡伟",":yuwen"=>"107",":shuxue"=>"99",":yingyu"=>"113"));
    
      $xuesheng="孙维维";    // 可以接受<form>标签传递过来的值
      $yuwen="86";
      $shuxue="66";
      $yingyu="78";
      $result->bindParam(":xuesheng",$xuesheng);
      $result->bindParam(":yuwen",$yuwen);
      $result->bindParam(":shuxue",$shuxue);
      $result->bindParam(":yingyu",$yingyu);
      $result->execute();
    
    // 可以多次添加数据记录
      $xuesheng="王萍";
      $yuwen="116";
      $shuxue="45";
      $yingyu="69";
      $result->bindParam(":xuesheng",$xuesheng);
      $result->bindParam(":yuwen",$yuwen);
      $result->bindParam(":shuxue",$shuxue);
      $result->bindParam(":yingyu",$yingyu);
      $result->execute();
    
    }catch(Exception $exception){
      echo $exception->getMessage();
    }
    ?>
    </body>
    </html>

    上面的实例执行一次代码,可以添加多条数据记录。当然,执行一次代码,也可以添加一条记录。

    上面的实例代码,还可以写成下面的格式,效果是一样的:

    复制代码
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>PHP PDO prepare()、execute()和bindParam()方法详解实例-www.baike369.com</title>
    </head>
    <body>
    <?php
    $dbms='mysql';
    $dbname='db_xuesheng';
    $user='root';
    $pwd='1234';
    $host='localhost';
    $dsn="$dbms:host=$host;dbname=$dbname";
    try{
      $pdo=new PDO($dsn,$user,$pwd);
      $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
      $query="INSERT INTO tb_chengji SET xuesheng=?,yuwen=?,shuxue=?,yingyu=?";
      $result=$pdo->prepare($query);
    
      $result->execute(array("周一刚","55","80","78"));
      $result->execute(array("胡伟","107","99","113"));
    
      $xuesheng="孙维维";    // 可以接受<form>标签传递过来的值
      $yuwen="86";
      $shuxue="66";
      $yingyu="78";
      $result->bindParam(1,$xuesheng);
      $result->bindParam(2,$yuwen);
      $result->bindParam(3,$shuxue);
      $result->bindParam(4,$yingyu);
      $result->execute();
    
    // 可以多次添加数据记录
      $xuesheng="王萍";
      $yuwen="116";
      $shuxue="45";
      $yingyu="69";
      $result->bindParam(1,$xuesheng);
      $result->bindParam(2,$yuwen);
      $result->bindParam(3,$shuxue);
      $result->bindParam(4,$yingyu);
      $result->execute();
    }catch(Exception $exception){
      echo $exception->getMessage();
    }
    ?>
    </body>
    </html>

    执行实例代码以后,tb_chengji数据表中的数据记录如下图所示:

    执行实例代码后tb_chengji数据表中的数据记录


    提示

    当使用PHP中PDO的prepare()、execute()和bindParam()方法时,网页的编码一定要设置为utf-8:

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    否则,将不能输入中文汉字数据。

  • 相关阅读:
    《应用Yii1.1和PHP5进行敏捷Web开发》学习笔记(转)
    YII 小模块功能
    Netbeans代码配色主题大搜集
    opensuse 启动巨慢 解决方法 90s多
    opensuse 安装 网易云音乐 rpm netease music
    linux qq rpm deb opensuse
    openSUSE 安装 alien
    第一行代码 Android 第2版
    Android Studio AVD 虚拟机 联网 失败
    docker error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.29/containers/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuratio
  • 原文地址:https://www.cnblogs.com/caicaizi/p/4889647.html
Copyright © 2011-2022 走看看