bindParam()

1. 定义

该方法将一个变量名绑定到预处理 SQL 语句的指定参数的占位符。 成功时返回 TRUE,失败则返回 FALSE。

注:

  • 该方法为引用绑定,只能绑定变量而不能直接绑定常量,要绑定常量可使用PDOStatement::bindValue()方法
  • 某些驱动支持调用存储过程(通过CALL语句调用)并将绑定参数作为输出参数返回数据,某些驱动则既发送数据又接受更新后的数据

2. 语法

PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] ) : bool

3. 参数说明

参数 可选性 数据类型 描述
$parameter 必需 mixed 占位符标识,类似:name的参数名或从 1 开始的参数索引位置
&$variable 必需 mixed 绑定到 SQL 语句参数的变量名称,注意,这里只能是变量,而不能是常量或其他值
$data_type 可选 整型或常量 默认为PDO::PARAM_STR,通过PDO::PARAM_*常量明确指定的参数数据类型
$length 可选 整型 数据类型的长度值
$driver_options 可选 mixed 数据库驱动可选值

其中,若是需要从一个存储过程返回一个INOUT参数,则需要$data_type参数使用按位或操作符|)搭配PDO::PARAM_INPUT_OUTPUT设置。 如果需要从存储过程返回一个OUT参数,则必须明确指定$length的长度值。

4. 示例

<?php

// PDOStatement::bindParam()
// 将一个变量名绑定到预处理 SQL 语句的指定参数的占位符

try {
    $config = ['driver' => 'mysql', 'host' => 'localhost', 'dbname' => 'test', 'charset' => 'utf8', 'user' => 'root', 'pwd' => 'mysql'];
    $dsn = sprintf('%s:host=%s;dbname=%s;charset=%s', $config['driver'], $config['host'], $config['dbname'], $config['charset']);
    $conn = new PDO($dsn, $config['user'], $config['pwd']);
} catch (PDOException $e) {
    error_log($e->getMessage());
    echo $e->getMessage();
}

try {
    $sql = 'SELECT `name`,`rate`,`cover` FROM `movie` WHERE `rate` > :small AND `rate` < :big';
    $stmt = $conn->prepare($sql);
    $small = 9.5;
    $big = 10.0;
    $stmt->bindParam(':small', $small, PDO::PARAM_STR);// 注意,PDO::PARAM_* 类常量中没有关于浮点数的定义,使用 PDO::PARAM_INT 会造成失误,故此这里还是使用 PDO::PARAM_STR
    $stmt->bindParam(':big', $big, PDO::PARAM_STR);
    $stmt->execute();
    var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
    /* 输出:
    array(1) {
      [0]=>
      array(3) {
        ["name"]=>
        string(12) "霸王别姬"
        ["rate"]=>
        string(3) "9.6"
        ["cover"]=>
        string(74) "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2561716440.jpg"
      }
    }
    */
} catch (Exception $e) {
    echo "发生了错误:", $e->getMessage();
}

题外注:

关于 SQL 的“存储过程”,这里给出一个示例(获取某一段评分区间的结果集),它其实和函数类似:

-- 临时修改语句分隔符为双斜线
DELIMITER //

-- 创建存储过程
CREATE PROCEDURE movie_level(IN low INT, IN high INT)
BEGIN
--  SELECT * FROM `movie` WHERE `rate` < high;
    SELECT * FROM `movie` WHERE `rate` < high AND `rate` > low;-- 查询评分大于 low 且小于 high 的记录
END //

-- 改回语句分隔符为分号
DELIMITER ;

以上语句只需运行一次,重复运行会造成重复定义的错误。

然后我们可以使用CALL movie_level(7, 9);语句来执行上面定义的存储过程(函数)。

这是一个简单的定义,实际上可以往存储过程中添加更多需要的 SQL 语句,这往往是用来完成某个特定的功能,向外可隐藏复杂的逻辑,可以传值也可以回值,端看你如何定义了。

5. 延展阅读