PDO常用操作与trait、interface、抽象类的详解
程序员文章站
2022-03-24 21:20:34
...
PDO常用方法
连接数据库
直接写PDO连接数据库,后续的操作都引入这个connect.php文件config.php
数据库基本连接参数
<?php
return [
// 数据库类型
'type' =>$type ?? 'mysql',
// 主机地址
'host' => $host ?? 'localhost',
// 默认数据库
'dbname' =>$dbname ?? 'phpedu',
// 账号
'username' =>$username ?? 'root',
// 密码
'password' =>$password ?? 'root',
// 默认字符集
'charset' =>$charset ?? 'utf8',
// 默认端口
'port' =>$port ?? '3306'
];
connect.php
数据库连接文件
<?php
$config = require 'config.php';
// var_dump($config);
extract($config);
$dsn = "{$type}:host={$host};dbname={$dbname}";
// echo $dsn;
$pdo = new PDO($dsn,$username,$password);
// var_dump($pdo);
// 设置默认返回数据是关联数组格式
$pdo->setAttribute
(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
插入记录
-
插入记录完整版
<?php
// 1.引入连接文件
require __DIR__.DIRECTORY_SEPARATOR.'connect.php';
// 2.操作
/*
// 2.1.1 匿名预处理SQL语句
$sql = 'INSERT INTO `users` SET `name`=?, `email`=?, `password`=?;';
$stmt = $pdo->prepare($sql);
// 方法一:匿名占位符
// 2.1.2变量绑定占位符
$stmt->bindParam(1, $name, PDO::PARAM_STR, 30);
$stmt->bindParam(2, $email, PDO::PARAM_STR, 100);
$stmt->bindParam(3, $password, PDO::PARAM_STR, 40);
// 2.1.3变量赋值 执行
$name = '小李';
$email = 'xl@php.cn';
$password = sha1('222');
// 执行
$stmt->execute();
*/
// 方法二:匿名占位符省略版 ,直接执行,传入索引数组,数据按照占位符顺序
// $stmt->execute(['小马', 'xm@php.cn', sha1('111')]);
// 2.2.1 命名占位符
$sql = 'INSERT INTO `users` SET `name` =:name, `email` = :email, `password` =:password;';
$stmt = $pdo->prepare($sql);
/*
// 方法三:命名占位符
// 2.2.2 命名与变量名绑定
$stmt -> bindParam(':name',$name,PDO::PARAM_STR,30);
$stmt -> bindParam(':email',$email,PDO::PARAM_STR,100);
// :name 前面的冒号可以省略
$stmt -> bindParam('password', $password, PDO::PARAM_STR,40);
// 2.2.3 变量名赋值
$name = '小虎';
$email = 'xh@php.cn';
$password = sha1('xiaohu');
$stmt->execute();
*/
// 方法四:命名占位符省略版
$stmt->execute(['name'=>'小方','email'=>'xf@php.cn','password'=>sha1('xiaofang')]);
// 2.4输出影响结果
echo '成功新增了 ' . $stmt->rowCount() . ' 条记录,新增的主键id = '. $pdo->lastInsertId();
// 3.关闭
$pdo = null;
运行结果图:
-
插入记录精简版
<?php
require 'connect.php';
// 标准版
/*
$sql = 'INSERT INTO `users` SET `name`=?, `email`=?, `password`=?;';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(1, $name, PDO::PARAM_STR, 30);
$stmt->bindParam(2, $email, PDO::PARAM_STR, 100);
$stmt->bindParam(3, $password, PDO::PARAM_STR, 40);
$name = '小骆';
$email = 'xl@php.cn';
$password = sha1('xiaoluo');
$stmt->execute();
echo '成功新增:'.$stmt->rowCount().'条记录,新增的主键ID是:'.$pdo->lastInsertId();
*/
// 最简化版
$sql = 'INSERT INTO `users` SET `name`=:name, `email`=:email, `password`=:password;';
$stmt = $pdo->prepare($sql);
$stmt->execute(['name'=>'小琪','email'=>'xq@php.cn','password'=>sha1('xiaoqi')]);
echo '成功新增:'.$stmt->rowCount().'条记录,新增的主键ID是:'.$pdo->lastInsertId();
// 关闭连接
$pdo = null;
-
更新记录
<?php
// 1.连接
require __DIR__.DIRECTORY_SEPARATOR.'connect.php';
// 2.操作
$sql = 'UPDATE `users` SET `name`=:name, `email`=:email, `password`=:password WHERE `id`=:id;';
$stmt = $pdo->prepare($sql);
$stmt->execute(['name'=>'tlilam','email'=>'tlilam@php.cn','password'=>sha1('tlilam'),'id'=>'12']);
echo $stmt->rowCount() == true ? '成功更新:'.$stmt->rowCount().'条记录' : '没有记录被更新';
// 3.关闭
$pdo = null;
运行结果图:
-
删除记录
<?php
// 1.连接
require __DIR__.DIRECTORY_SEPARATOR.'connect.php';
// 2.操作
$sql = 'DELETE FROM `users` WHERE `id`=?;';
$stmt = $pdo->prepare($sql);
$stmt->execute(['12']);
echo $stmt->rowCount() == true ? '成功删除:'.$stmt->rowCount().'条记录' : '没有记录被删除';
// 3.关闭
$pdo = null;
运行结果图:
-
查询记录:fetch()+while()
<?php
// PDO 查询操作 fetch() + while()
// 1.连接
require __DIR__.DIRECTORY_SEPARATOR.'connect.php';
// 2.操作
$sql = 'SELECT `id`, `name`, `email` FROM `users` WHERE `id` > ?;';
$stmt = $pdo->prepare($sql);
if($stmt->execute( ['6'] )) {
// 查询成功返回
/*
// 测试一条条查询出来
$user = $stmt->fetch();
printf('<pre>%s</pre>',print_r($user,true));
$user = $stmt->fetch();
printf('<pre>%s</pre>',print_r($user,true));
// 数据查询完之后返回的是false
$user = $stmt->fetch();
var_dump($user);
*/
// 这样我们就可以使用while循环,没有数据的时候就停止
while($user = $stmt->fetch()){
printf('<pre>%s</pre>',print_r($user,true));
}
}else{
// 失败检查方法1,打印出错误信息
printf('<pre>%s</pre>',print_r($stmt->errorInfo(), true));
// 失败检查方法2,打印出执行的SQL语句,进行检查
$stmt->debugDumpParams();
}
// 3.关闭
$pdo = null;
运行结果图:
-
查询记录:fetchALl() + foreach()
<?php
// PDO 查询操作 fetchAll() + foreach()
// 1. 连接
require __DIR__.DIRECTORY_SEPARATOR.'connect.php';
// 2.操作
$sql = 'SELECT `id`,`name`,`email` FROM `users` WHERE `id` > ?;';
$stmt = $pdo->prepare($sql);
if($stmt->execute(['6'])){
// 返回关联和索引数组合并后的结果
$users = $stmt->fetchAll();
// 填入参数只返回关联数组,可以在connect.php 进行声明默认取关联数组数据
// $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
// print_r($users);
foreach($users as $user){
echo 'id:'.$user['id'].',name:'.$user['name'].',email:'.$user['email'].'<br/>';
}
}else{
$stmt->debugDumpParams();
}
// 3.关闭
$pdo = null;
运行结果图:
-
查询记录:将每条记录的字段值绑定到变量
<?php
// PDO 查询操作,将一条记录的每个字段值绑定到变量
// 1.连接
require __DIR__.DIRECTORY_SEPARATOR.'connect.php';
// 2.操作
$sql = 'SELECT `id`,`name`,`email` FROM `users` WHERE `id` > ?;';
$stmt = $pdo->prepare($sql);
$stmt->execute(['6']);
// 2.1绑定
$stmt->bindColumn('id',$id);
$stmt->bindColumn('name',$name);
$stmt->bindColumn('email',$email);
// PDO::FETCH_BOUND 可选
while($user = $stmt->fetch(PDO::FETCH_BOUND) ){
echo "<li>ID :{$id},name:{$name},email:{$email}</li>";
}
// 3.关闭
$pdo = null;
运行结果图:
-
查询符合条件的记录数量
<?php
// 1.连接
require __DIR__.DIRECTORY_SEPARATOR.'connect.php';
// 获取满足条件的记录 不能使用$stmt->rowCount();这不一定准确
// 获取满足条件的记录数量
$sql = 'SELECT COUNT(*) AS `count` FROM `users` WHERE `id` > ?;';
// 预处理SQL语句
$stmt = $pdo->prepare($sql);
// 执行
$stmt->execute( ['6'] );
// 绑定到变量
$stmt->bindColumn('count',$count);
// 取出记录
$stmt->fetch(PDO::FETCH_BOUND);
echo '满足条件记录数量是: ', $count, ' 条记录';
// 3.关闭
$pdo = null;
运行结果图:
trait的常用场景:组合性、代码复用、抽象方法
<?php
// trait1:代码复用
trait tDemo1{
public function getName(){
return $this->name;
}
}
// trait2:抽象方法
trait tDemo2{
abstract function getEmail();
}
// trat3:引入多个trait
trait tDemo{
use tDemo1, tDemo2;
}
// 引入组合后的trait: tDemo
class test1{
use tDemo;
public $name = 'test1';
public $email = 'test1@qq.com';
public function getEmail(){
return $this->name;
}
}
class test2{
use tDemo;
public $name = 'test2';
public $email = 'test2@qq.com';
public function getEmail(){
return $this->name;
}
}
// 引入trait调用公用方法
echo (new test1)->name;
echo (new test2)->name;
// 引入有抽象方法,需实现trait的抽象方法
echo (new test1)->email;
echo (new test2)->email;
trait使用总结
- 代码最常用的是代码复用,公用的方法放在trait里面需要使用就use引入trait
- trait也支持抽象方法,引入的类需要实现抽象方法
- trait支持父类被继承的时也被继承下去,优先级是宿主子类>宿主类>trait
- trait支持多引用,trait可以引入多个trait,类也可以引入多个trait
- trait命名冲突可以用AS别名或者insteadof顶替解决
interface的常用场景:规范开发
接口: 完全的分离了: 设计(接口)与实现(实现类) 多继承性质
<?php
interface buy{
// 进货总价
function buyPrice($value,$num);
}
interface sell{
// 接口中没有属性,有常量
const SHUILV = 0.06;
// 卖货总价
function sellPrice($value,$num);
}
//工作类实现接口buy,sell
class work implements buy,sell{
public function buyPrice($value,$num){
return $value * $num;
}
public function sellPrice($value,$num){
// return ($value + $value * 0.06) * $num;
return ($value + $value * sell::SHUILV ) * $num;
}
}
$work = new work();
echo '进货总价:' .$work->buyPrice(3500,10).'-----';
echo '卖货总价:' .$work->sellPrice(4000,10);
interface使用总结
- 接口主要是在规范开发的使用,不同的接口组合规范出新类的实现
- 接口中方法没有方法体
- 一个类可以同时实现多个接口,用逗号隔开
- 实现类使用implements实现接口
- 接口中只有常量和“抽象”方法
抽象类的使用
抽象类: 部分的分离了: 设计(抽象类)与实现(工作类) 单继承性质
<?php
// 定义抽象类
abstract class aDemo{
// 定义常量
const TEST = '123';
// 定义属性
protected $password = 'pwd';
// 定义普通方法 得到加料后的密码加密
protected function getPassword($value){
return sha1($value.$this->$password);
}
// 定义抽象静态方法
abstract static function getName($name);
}
class work extends aDemo{
// 类实现抽象静态方法,进行不同的样式输出
static function getName($name){
return '姓名:<strong>'.$name.'</strong> ';
}
public function test(){
return aDemo::TEST;
}
}
echo work::getName('user');
echo (new work)->test();
抽象类与接口的相同点:
1、“抽象”方法都是用于声明某一种事物,规范名称、参数,形成模块,未有详细的实现细节。
2、都是通过类来实现相关的细节工作
3、语法上,抽象方法的抽象类与接口一样,不能有方法体,即{}符号
4、都可以用继承,接口可以继承接口形成新的接口,抽象类可以继承抽象类从而形成新的抽象类
抽象类与接口的不同点:
1、抽象类可以有常量、属性、普通方法、抽象方法,但接口不能有属性、普通方法、可以有常量
2、抽象类内未必有抽象方法,但接口内一定会有“抽象”方法
3、语法上有不同,下面是具体使用上的不同
4、抽象类用abstract关键字在类前声明,且有class声明为类,接口是用interface来声明,但不能用class来声明,因为接口不是类。
5、抽象类的抽象方法一定要用abstract来声明,而接口则不需要,接口里面的方法默认就是一种“抽象”的方法
6、抽象类是用extends关键字让子类继承抽象父类后,在子类实现详细的抽象方法。
7、接口则是用implements关键字让类实现接口的详细方法,且类可以一次性实现多个接口,用逗号分开各个接口