0、准备工作,创建数据表 users
CREATE DATABASE IF NOT EXISTS `test`;
USE `test`;
CREATE TABLE IF NOT EXISTS `users`(
id int unsigned auto_increment,
email varchar(255) not null default '',
password varchar(255) not null default '',
primary key(`id`)
)auto_increment=1,charset=utf8,engine=innodb;
PDO::__construct ( string $dsn
[, string $username
[, string $password
[, array $driver_options
]]] )
$driver_options 数组 长连接设置 PDO::ATTR_PERSISTENT=>true
$dsn = 'mysql://host=127.0.0.1;port=3306;dbname=test;charset=utf8'; // dsn
$user = 'root'; // 帐号
$pass = ''; // 密码
$dbh = new PDO($dsn,$user,$pass);
// $dbh = new PDO($dsn,$user,$pass,[PDO::ATTR_PERSISTENT=>1]); // 长连接
var_dump($dbh);
2、执行sql语句 exec() 执行非查询语句的sql(select ...) 返回影响的行数或者false
int PDO::exec ( string $statement
)
// 正常的非查询操作返回影响行数
$sql = 'insert into users(email,password) value(\'[email protected]\',\''.md5('dsfsadsafasf').'\')';
$rt = $dbh->exec($sql);
var_dump($rt); // int(1)
如下代码:
// 执行查询sql语句
$sql = 'select * from users';
// 没有满足wher条件的记录 更新了0行 也就是影响了0行
$sql = 'update users set email=\'[email protected]\' where id>10000';
$rt = $dbh->exec($sql);
var_dump($rt); // int(0)
// user表不存在 sql存在语法错误 返回false
$sql = 'update user set email=\'[email protected]\' where id>10000';
$rt = $dbh->exec($sql);
var_dump($rt); // bool(false)
3、执行所有的sql PDOStatement query($sql) http://php.net/manual/zh/pdo.query.php
可以执行所有类型的sql 执行成功返回PDOStatement 对象执行 若执行错误返回false
public PDOStatement PDO::query ( string $statement
)
// 返回PDOStatement 插入更新等操作返回的不是false就是执行成功 并返回PDOStatement
$sql = 'select * from users';
$sql = 'insert into user(email,password) value(\'[email protected]\',\''.md5('123456').'\')';
$sql = 'select * from user'; // sql执行错误 表user不存在 返回false
$rt = $dbh->query($sql);
var_dump($rt);
foreach($rt as $key=>$val){
print_r($val);
}
执行insert update等非查询sql 执行成功返回PDOStatement
执行失败query 会返回false
4、预处理的形式执行sql 这样可防止sql注入
预处理带有占位符的sql字符串
select * from users where id>?
select * from users where id>:id
public PDOStatement PDO::prepare ( string $statement
[, array $driver_options
= array() ] )
$sql = 'select * from users where id>:id';
$stmt = $dbh->prepare($sql);
var_dump($stmt);
下面的方法是 PDOStatement类的:
绑定参数到占位符
bool PDOStatement::bindValue ( mixed $parameter
, mixed $value
[, int $data_type
= PDO::PARAM_STR ] )
bool PDOStatement::bindParam ( mixed $parameter
, mixed &$variable
[, int $data_type
= PDO::PARAM_STR [, int $length
[, mixed $driver_options
]]] )
设置查询结果的组织形式
参数可以是 PDO::FETCH_* 的常量 PDO常量可以在这里查看 http://php.net/manual/zh/pdo.constants.php
bool PDOStatement::setFetchMode ( int $mode
)
执行预处理函数
bool PDOStatement::execute ([ array $input_parameters
] )
查询执行
获取一条
mixed PDOStatement::fetch ([ int $fetch_style
[, int $cursor_orientation
= PDO::FETCH_ORI_NEXT[, int $cursor_offset
= 0 ]]] )
获取所有条
array PDOStatement::fetchAll ([ int $fetch_style
[, mixed $fetch_argument
[, array $ctor_args
= array() ]]] )
示例代码:
$sql = 'select * from users where id>:id';
$stmt = $dbh->prepare($sql);
// bindPatam参数绑定形式
$id=1;
$stmt->bindParam('id',$id);
// 直接绑定
$stmt->bindValue('id',1);
$stmt->execute(); // 执行预处理sql
// 设置结果集数据形式
$stmt->setFetchMode(PDO::FETCH_ASSOC);
// 查询一条数据
$rt1 = $stmt->fetch();
// 查询全部
$rt2 = $stmt->fetchAll();
var_dump($rt1);
var_dump($rt2);
关于参数绑定:
bindValidate(key,val); 直接指定绑定的参数
a、?作为占位符的情况
$stmt = $dbh->prepare('select * from user where id>? and email!=?');
$stmt->bindValue(1,1);
$stmt->bindValue(2,'[email protected]');
$stmt->execute();
print_r($stmt->fetchAll());
b、以 :field 作为占位符
$stmt = $dbh->prepare('select * from user where id>:id and email!=:email');
$stmt->bindValue('id',1);
$stmt->bindValue('email','[email protected]');
$stmt->execute();
print_r($stmt->fetchAll());
c、? 与 :key 混合的形式作为占位符
$stmt = $dbh->prepare('select * from user where id>? and email!=:email');
$stmt->bindValue(1,1);
$stmt->bindValue('email','[email protected]');
$stmt->execute();
print_r($stmt->fetchAll());
可参照php官网的一个例子 @link http://php.net/manual/en/pdostatement.bindparam.php#98715
bindParam(key,$value) 绑定变量到sql中
第二个参数必须是变量的引用,像bindValue一样传递常量会报错。
php5.3以后 在函数调用传递一用变量不用加 & 符了,只用在函数定义的时候对参数进行引用声明即可
function func(&$arg){......} func('aaa');
使用方法与bindValue类似,
$stmt = $dbh->prepare('select * from user where id>? and email!=?');
$id = 1;
$email = '[email protected]';
$stmt->bindParam(1,$id);
$stmt->bindParam(2,$email);
$stmt = $dbh->prepare('select * from user where id>:id and email!=:email');
$id = 1;
$email = '[email protected]';
$stmt->bindParam('id',$id);
$stmt->bindParam('email',$email);
在两种不同的占位符的情况下的绑定形式如下:
?占位符
$stmt = $dbh->prepare('select * from user where id>? and email!=?');
$stmt->execute([1,'[email protected]']);
print_r($stmt->fetchAll());
$stmt = $dbh->prepare('select * from user where id>:id and email!=:email');
$stmt->execute(['id'=>1,'email'=>'[email protected]']);
print_r($stmt->fetchAll());
这个是鸟哥的解释 http://www.laruence.com/2012/10/16/2831.html
当我们这样使用bindParam的时候
$stmt=$dbh->prepare('select * from users where title=:title and name=:name');
$params = [':title'=>'head of artical',':name'=>'fantasy'];
foreach($params as $key=>$val){
$stmt->bindParam($key,$val);
}
分析原因 bindParam 的第二个参数是引用型变量
分解上面的foreach 相当于:
$val = $params[':id'];
$dbh->bindParam(':id',&$val);
$val = $params[':name'];
$dbh->bindParam(':name',&$val);