1、预处理基础(预处理方法1:匿名参数? + 索引数组)
<?php
//PDO:预处理
//预处理的本质:sql语句中的数据,是动态绑定的
//动态绑定:只有在执行sql时,才绑定真实的数据
//静态绑定:数据直接写道sql中
//1.静态:select * from staff where id >10
//2.动态(预处理):select * from staff where id > ?
//1.匿名参数? + 索引数组
namespace pdo_edu;
use PDO;
//连接
//!简单一点写,数据源,默认用户名和密码,只预处理这三个就可以了,其它的可以暂时不管
$db = new PDO('mysql:dbname=phpedu','root','root');
//CURD:INSERT
//匿名参数:? + 索引数组
$sql = "INSERT `staff` SET `name`=?,`sex`=?,`email`=?";
//sql语句->sql语句模板对象->预处理对象
$stmt=$db->prepare($sql);
//sql语句中的占位符?,给他绑定真实数据
$data=['杨过',1,'yangguo@qq.com'];
//执行sql
$stmt->execute($data);
//验证:打印sql预处理命令
$stmt->debugDumpParams();
echo '新增成功,id = '.$db->lastInsertId() . '<hr>';
上述运行结果:
2、预处理基础(预处理方法2:命名参数:":name" + 关联数组)
<?php
//PDO:预处理
//预处理的本质:sql语句中的数据,是动态绑定的
//动态绑定:只有在执行sql时,才绑定真实的数据
//静态绑定:数据直接写道sql中
//1.静态:select * from staff where id >10
//2.动态(预处理):select * from staff where id > ?
//1.匿名参数? + 索引数组
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu','root','root');
//CURD:INSERT
//命名参数:":name" + 关联数组
$sql = "INSERT `staff` SET `name`=:name,`sex`=:sex,`email`=:email";
//sql语句->sql语句模板对象->预处理对象
$stmt=$db->prepare($sql);
//sql语句中的占位符?,给他绑定真实数据
//关联数组
//data里的所有赋值全部视为字符串
$data=['name'=>'小龙女','sex'=>0,'email'=>'xiaolongnv@qq.com'];
//执行sql
$stmt->execute($data);
//验证:打印sql预处理命令
$stmt->debugDumpParams();
//新增成功后的数据会获得一个新增id,可以用lastInsert方法查看新增数据的id号.
echo '新增成功,id = '.$db->lastInsertId() . '<hr>';
/**
* 用哪个?
* 1. ?:代码少,结合上下文才知道语义
* 2. ":name" :语义化,可读性
*
* 一般用第一个:?
*/
上述运行结果:
3、参数绑定 :值绑定 bindValue()
<?php
//!使用数组行也不行,因为数组里所有的数据默认都是字符串
//!所以引入参数绑定的概念
//3.参数绑定 :值绑定 bindValue()
/**
* 为什么要单独设置参数,而不是再execute()时传参?
* 1.execute()默认参数都是字符类型
* 2.通常数字型字符写入数据表时,会转换成正确类型,并不会有问题
* 3.但是在分页操作时,会导致错误
* 4.所以,在参数绑定时,强制类型限制,就很有必要
*/
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu','root','root');
//CURD:INSERT
//命名参数:":name"
//对于太长的语法,用heredoc
$sql = <<< SQL
INSERT `staff`
SET `name`=?,`sex`=?,`email`=?;
SQL;
//sql语句->sql语句模板对象->预处理对象
$stmt=$db->prepare($sql);
//bindValue(): 值绑定,静态绑定,所有参数必须要有一个确定的值
//bindValue(): 匿名占位符,索引从1开始
$stmt->bindValue(1,'悟空',PDO::PARAM_STR);
$stmt->bindValue(2,1,PDO::PARAM_INT);
$stmt->bindValue(3,'wukong@qq.com',PDO::PARAM_STR);
list($name,$sex,$email) = ['洪七公',1,'hongqigong@qq.com'];
$stmt->bindValue(1,$name,PDO::PARAM_STR);
$stmt->bindValue(2,$sex,PDO::PARAM_INT);
$stmt->bindValue(3,$email,PDO::PARAM_STR);
//!静态绑定无法实现对模板的实时更新
//!如果不想每一次都重新进行静态绑定,则需要进行引用绑定
list($name,$sex,$email) = ['欧阳克',1,'hongqigong@qq.com'];
$stmt->bindValue(1,$name,PDO::PARAM_STR);
$stmt->bindValue(2,$sex,PDO::PARAM_INT);
$stmt->bindValue(3,$email,PDO::PARAM_STR);
//执行sql
$stmt->execute();
echo '新增成功,id = '.$db->lastInsertId() . '<hr>';
上述运行结果:
4、参数绑定:引用绑定 bindParam()
<?php
//3.参数绑定:引用绑定 bindParam()
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu','root','root');
//CURD:INSERT
//命名参数:":name"
//对于太长的语法,用heredoc
$sql = <<< SQL
INSERT `staff`
SET `id`=?,`name`=?,`sex`=?,`email`=?;
SQL;
//sql语句->sql语句模板对象->预处理对象
$stmt=$db->prepare($sql);
//引用绑定:动态绑定,绑定的不是数据本身,而是它的地址/引用/别名
$stmt->bindParam(1,$id,PDO::PARAM_INT);
$stmt->bindParam(2,$name,PDO::PARAM_STR);
$stmt->bindParam(3,$sex,PDO::PARAM_INT);
$stmt->bindParam(4,$email ,PDO::PARAM_STR);
list($name,$sex,$email) = ['郭靖',1,'guojing@qq.com'];
//执行sql
$stmt->execute();
list($name,$sex,$email) = ['杨康',1,'yangkang@qq.com'];
//执行sql
$stmt->execute();
//引用绑定优势极大,sql模板对象只需要编译一遍,以后只要传入不同数据,就可以执行不同的操作
//以后我们尽量只用引用绑定
// echo '新增成功,id = '.$db->lastInsertId() . '<hr>';
上述运行结果:
5、值绑定同时新增多条数据(二维数组模拟)
<?php
//3.引用绑定bindParam()一次绑定多条数据
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu','root','root');
//CURD:INSERT
//命名参数:":name"
//对于太长的语法,用heredoc
$sql = <<< SQL
INSERT `staff`
SET `name`=?,`sex`=?,`email`=?;
SQL;
//sql语句->sql语句模板对象->预处理对象
$stmt=$db->prepare($sql);
//引用绑定:动态绑定,绑定的不是数据本身,而是它的地址/引用/别名
$stmt->bindParam(1,$name,PDO::PARAM_STR);
$stmt->bindParam(2,$sex,PDO::PARAM_INT);
$stmt->bindParam(3,$email ,PDO::PARAM_STR);
$data = [
['武松',1,'wusong@qq.com'],
['金莲',0,'jinlian@qq.com'],
['西门',1,'ximen@qq.com'],
];
foreach ($data as list($name,$sex,$email)) {
$stmt->execute();
echo '新增成功,id = '.$db->lastInsertId() . '<hr>';
}
//引用绑定优势极大,sql模板对象只需要编译一遍,以后只要传入不同数据,就可以执行不同的操作
//以后我们尽量只用引用绑定
// echo '新增成功,id = '.$db->lastInsertId() . '<hr>';
上述运行结果:
6.失败检测与处理
<?php
//6.失败检测与处理
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu', 'root', 'root');
//CURD:INSERT
//命名参数:":name"
//对于太长的语法,用heredoc
$sql = <<< SQL
INSERT `staff`
SET `name`=?,`sex`=?,`email`=?;
SQL;
//sql语句->sql语句模板对象->预处理对象
$stmt = $db->prepare($sql);
$data = ['张无忌', 1, 'wuji@qq.com'];
//执行sql
if ($stmt->execute($data)) {
//true
//读:select
//写:insert,update,delete,成功后会返回表中受影响的记录数量
//!rowCount() 返回受影响的记录数量
if ($stmt->rowCount() > 0) {
echo '新增成功,id = ' . $db->lastInsertId() . '<hr>';
} else {
//false
echo '新增失败';
//!errorInfo返回一个数组,可以查看在哪里出错
print_r($stmt->errorInfo());
}
} else {
//false
echo 'sql执行失败';
print_r($stmt->errorInfo());
}
/**
* tips:
* 1.else:应该用于开发调试阶段,生产环境中应该将错误信息集中写道日志文件中
* 2.sql执行失败很常见,通常是语法错误,例如字段name写成了name1
* 3.新增失败通常是权限不足,如果没有插入权限或者当前表被锁定只读等,也可能是磁盘空间满了
*/
上述运行结果:
7、更新操作
<?php
//6.更新操作
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu', 'root', 'root');
//CURD:UPDATE
$sql = <<< SQL
UPDATE `staff`
SET `name`=?,`sex`=?,`email`=?
WHERE `id` = ?;
SQL;
//!绝对禁止无条件更新
//!否则所有信息都更新
//!所以要检测sql语句中,是否存在where子句
//!并且where前面千万别加;因为这样实际上执行不到where
//!stripos忽略大小写
//!strpos不忽略大小写
//检测sql语句中,是否存在where子句
//如果没有的话会返回false
//!如果只是将where注释掉的话,stripos会认为where还是存在
if(false === stripos($sql,'WHERE')){
exit('禁止无条件更新');
}
//sql语句->sql语句模板对象->预处理对象
$stmt = $db->prepare($sql);
//!把id为4的数据名改为任我行
$data = [ '任我行', 1, 'woxing@qq.com',4];
//执行sql
if ($stmt->execute($data)) {
//true
//读:select
//写:insert,update,delete,成功后会返回表中受影响的记录数量
//rowCount() 返回受影响的记录数量
if ($stmt->rowCount() > 0) {
echo '成功地更新了' . $stmt->rowCount() . '条记录';
} else {
//主要是用于检测是否重复执行
echo '没有记录被更新';
print_r($stmt->errorInfo());
}
} else {
//false
echo 'sql执行失败';
print_r($stmt->errorInfo());
//!debugDumpParams() 直接打印出当前执行的SQL语句的信息
//!注意,它和 var_dump() 、 php_info() 这类函数一样,是直接打印的,不是将结果返回到一个变量中。
$stmt->debugDumpParams();
}
上述运行结果:
8、删除操作
<?php
//删除操作
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu', 'root', 'root');
//CURD:DELETE
//DELETE FROM
$sql = <<< SQL
DELETE FROM`staff`
WHERE `id` = ?;
SQL;
//!绝对禁止无条件更新
//!否则所有信息都更新
//!所以要检测sql语句中,是否存在where子句
//!并且where前面千万别加;因为这样实际上执行不到where
//!stripos忽略大小写
//!strpos不忽略大小写
//检测sql语句中,是否存在where子句
//如果没有的话会返回false
//!如果只是将where注释掉的话,stripos会认为where还是存在
if(false === stripos($sql,'WHERE')){
exit('禁止无条件删除');
}
//sql语句->sql语句模板对象->预处理对象
$stmt = $db->prepare($sql);
//!把id为4的数据名改为任我行
$data = [4];
//执行sql
if ($stmt->execute($data)) {
//true
//读:select
//写:insert,update,delete,成功后会返回表中受影响的记录数量
//rowCount() 返回受影响的记录数量
if ($stmt->rowCount() > 0) {
echo '成功地删除了' . $stmt->rowCount() . '条记录';
} else {
//主要是用于检测是否重复执行
echo '没有记录被更新';
print_r($stmt->errorInfo());
}
} else {
//false
echo 'sql执行失败';
print_r($stmt->errorInfo());
}
上述运行结果:
9、查询操作
<?php
//查询操作
//查询-1:fetch() + while()
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu', 'root', 'root');
//CURD:DELETE
//DELETE FROM
//!SELECT + *表示把所有的字段取出
$sql = <<< SQL
SELECT`id`,`name`,`email`
FROM `staff`
LIMIT ?;
SQL;
//sql语句->sql语句模板对象->预处理对象
$stmt = $db->prepare($sql);
//因为limit要求的参数必须是整数.所以要进行传参
$num = 5;
//PDO::指定参数类型
$stmt->bindParam(1,$num,PDO::PARAM_INT);
//执行sql
if ($stmt->execute()) {
//fetch():逐条获取,指针自动后移指向下一条
//fetch如果执行失败,就返回false,执行成功就返回记录
$staff = $stmt->fetch();
if($staff){
printf('<pre>%s</pre>',print_r($staff,true));
}else{
echo '没有了';
}
//
} else {
//false
echo 'sql执行失败';
print_r($stmt->errorInfo());
//!debugDumpParams() 直接打印出当前执行的SQL语句的信息
//!注意,它和 var_dump() 、 php_info() 这类函数一样,是直接打印的,不是将结果返回到一个变量中。
$stmt->debugDumpParams();
}
//!常用的写操作:insert,updata,delete
上述运行结果:
每个字段查询会返回两个结果,一个是索引数组,一个是关联数组.
一般来说只关心返回的关联部分,需要用一个过滤器参数对结果进行过滤
$staff = $stmt->fetch(PDO::FETCH_ASSOC);
上述运行结果:
<?php
//查询操作
//查询-1:fetch() + while()
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu', 'root', 'root');
//CURD:DELETE
//DELETE FROM
//!SELECT + *表示把所有的字段取出
$sql = <<< SQL
SELECT`id`,`name`,`email`
FROM `staff`
LIMIT ?;
SQL;
//sql语句->sql语句模板对象->预处理对象
$stmt = $db->prepare($sql);
//因为limit要求的参数必须是整数.所以要进行传参
$num = 5;
//PDO::指定参数类型
$stmt->bindParam(1,$num,PDO::PARAM_INT);
//执行sql
if ($stmt->execute()) {
//fetch():逐条获取,指针自动后移指向下一条
//fetch如果执行失败,就返回false,执行成功就返回记录
//PDO::FETCH_ASSOC
while($staff = $stmt->fetch(PDO::FETCH_ASSOC)){
printf('<pre>%s</pre>',print_r($staff,true));
}
//
} else {
//false
echo 'sql执行失败';
print_r($stmt->errorInfo());
//!debugDumpParams() 直接打印出当前执行的SQL语句的信息
//!注意,它和 var_dump() 、 php_info() 这类函数一样,是直接打印的,不是将结果返回到一个变量中。
$stmt->debugDumpParams();
}
//!常用的写操作:insert,updata,delete
上述运行结果:
<?php
//查询操作
//查询-2:fetchAll() + foreach()
namespace pdo_edu;
use PDO;
//连接
$db = new PDO('mysql:dbname=phpedu', 'root', 'root');
//CURD:DELETE
//DELETE FROM
//!SELECT + *表示把所有的字段取出
$sql = <<< SQL
SELECT`id`,`name`,`email`
FROM `staff`
LIMIT ?;
SQL;
//sql语句->sql语句模板对象->预处理对象
$stmt = $db->prepare($sql);
//因为limit要求的参数必须是整数.所以要进行传参
$num = 5;
//PDO::指定参数类型
$stmt->bindParam(1,$num,PDO::PARAM_INT);
//执行sql
if ($stmt->execute()) {
//fetchAll():获取全部满足条件的记录
$staffs = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($staffs as $staff){
printf('<pre>%s</pre>',print_r($staff,true));
}
//
} else {
//false
echo 'sql执行失败';
print_r($stmt->errorInfo());
//!debugDumpParams() 直接打印出当前执行的SQL语句的信息
//!注意,它和 var_dump() 、 php_info() 这类函数一样,是直接打印的,不是将结果返回到一个变量中。
$stmt->debugDumpParams();
}
//!常用的写操作:insert,updata,delete
上述运行结果: