创建config文件夹,在文件夹中放置database.php,数据库信息:
<?php
namespace pdo_deu;
return [
// dsn
'type' => 'mysql',
'host' => '127.0.0.1',
'dbname' => 'phpedu',
'port' => '3306',
'charset' => 'utf8',
// username
'username' => 'root',
'password' => 'root',
];
然后在connect_test.php中,引入database.php:
<?php
namespace pdo_edu;
use PDO;
$dbConfig = require 'database.php';
print_r($dbConfig); //打印数据库信息
// 将关联数组中的每一个成员,打散成独立变量
extract($dbConfig);
// heredoc
echo <<< SHOW
$type;
$host;
$dbname;
$port;
$charset;
$username;
$password;
<br>
SHOW;
// pdo: 连接三要素
// 1. dsn
// mysql:host=127.0.0.1;dbanme=phpedu;port=3306;charset=utf8;
$tpl = '%s:host=%s;dbanme=%s;port=%s;charset=%s';
$args = [$type, $host, $dbname, $port, $charset];
$dsn = sprintf($tpl, ...$args);
// 2. 创建数据对象
$db = new PDO($dsn, $username, $password);
// var_dump($db);
if ($db) echo '<h2>连接成功</h2>';
extract(): 将关联数组中的每一个成员,打散成独立变量。也就是database.php里面的数组。 heredoc()使用该方式打印出变量 定义tpl的数据库连接模板,通过sprintf方法把args的变量传入至tpl模板中,根据%s替换。 sprintf就是把变量传入带有的%s中的替换。 然后创建数据对象PDO,把$dsn和$username,$password 最后在connect_test基础上再完善:
<?php
namespace pdo_edu;
use PDO;
$dbConfig = require 'database.php';
extract($dbConfig);
// 1. dsn
$tpl = '%s:host=%s;dbname=%s;port=%s;charset=%s';
$args = [$type, $host, $dbname, $port, $charset];
$dsn = sprintf($tpl, ...$args);
// echo $dsn;
// 2. 创建数据对象
$db = new PDO($dsn, $username, $password);
// 设置结果集的默认获取模式:只要关联部分
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
// 设置结果集的默认获取模式:只要关联部分 $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 在 PHP 的 PDO(PHP Data Objects)扩展中,setAttribute 方法用于设置 PDO 对象或 PDOStatement 对象的属性,以此来控制 PDO 的行为。 PDO::ATTR_DEFAULT_FETCH_MODE:默认的获取模式。PDO::FETCH_ASSOC指定要关联数组。
bool PDO::setAttribute ( int $attribute , mixed $value )
$attribute:这是一个整数类型的参数,用于指定要设置的属性。PDO 定义了多个预定义的属性常量,你可以使用这些常量来设置不同的属性。 $value:用于指定属性的值,其类型取决于具体的属性。 数据的插入:
<?php
namespace php_edu;
/**
* 数据库常用操作
* 1. 读操作: select
* 2. 写操作: insert,update,delete
* 简称: CURD, 增删改查
*/
// 1. 连接数据库
require __DIR__ . '/config/connect.php';
// 2. CURD: INSERT
/**
* PDO预处理
* 为什么要用预处理?
* 1. 防止SQL注入攻击, 2. 数据延迟绑定
* (编程时只写SQL语句模板,执行SQL时再给占位符绑定真实数据)
* 预处理过程:
* 1. 创建SQL语句模板对象: 数据使用占位符表示
* 2. 执行SQL语句,根据操作类型(写/读),读返回结果集/数组, 写返回受影响的记录数量
*/
// INSERT 插入
// INSERT 表名 SET 字段1=值1, 字段2=值2, ....
// SQL语句的推荐规范:
// 1. 关键字全大写
// 2. 表名,字段名使用反引号做为定界符
$sql = 'INSERT `staff` SET `name` = ?, `sex` = ?, `email` = ?';
// 1. 创建SQL语句模板对象
$stmt = $db->prepare($sql);
// 2. 执行SQL语句
$stmt->execute(['小龙女', 1, 'xiaolongnv@php.cn']);
$stmt->execute(['洪七公', 0, 'hongqigong@php.cn']);
$stmt->execute(['黄蓉', 0, 'huangrong@php.cn']);
$stmt->execute(['杨过', 0, 'yangguo@php.cn']);
$stmt->execute(['猪老师', 0, 'zhulaoshi@php.cn']);
$stmt->execute(['灭绝', 0, 'miejue@php.cn']);
// 成功
// $stmt->rowCount(): 返回受影响的记录数量
if ($stmt->rowCount() > 0) {
echo '新增成功, 新增记录的主键ID = ' . $db->lastInsertId();
} else {
echo '新增失败';
print_r($stmt->errorInfo());
}
// INSET INTO table (字段列表) VALUES (值列表)
prepare作用是创建sql的模板,是PDO预处理机制。 prepare方法对 SQL 语句进行预处理。 execute方法执行预处理后的 SQL 语句。 调用 lastInsertId 方法获取最后一次插入操作生成的自增 ID,并将其存储在 $lastInsertedId 变量中 数据的更新:
<?php
namespace php_edu;
// 1. 连接数据库
require __DIR__ . '/config/connect.php';
// 2. CURD: UPDATE 更新
// UPDATE 表名 SET 字段1=值1 ... WHERE 更新条件
$sql = 'UPDATE `staff` SET `name` = ? WHERE `id` = ?';
$stmt = $db->prepare($sql);
$stmt->execute(['老顽童', 6]);
if ($stmt->rowCount() > 0) {
echo '更新成功';
} else {
echo '更新失败';
print_r($stmt->errorInfo());
}
rowCount :在 PDO 里,rowCount 方法用于返回受上一次执行的 SQL 语句影响的行数。对于 INSERT、UPDATE、DELETE 这类会修改数据库数据的语句,它返回实际受影响的行数;对于 SELECT 语句,在某些数据库驱动(如 MySQL)中,该方法不一定能返回结果集中的行数,若要获取结果集行数,通常需要使用 fetchAll 等方法结合 count 函数。 数据的删除:
<?php
namespace php_edu;
// 1. 连接数据库
require __DIR__ . '/config/connect.php';
// 2. CURD: DELETE 删除
// DELETE FROM 表名 SET 字段1=值1 ... WHERE 更新条件
// $sql = 'DELETE FROM `staff` WHERE `id` = ? ';
// '?' : 匿名占位符
// 'string': 命名占位符
$sql = 'DELETE FROM `staff` WHERE `id` = :id';
$stmt = $db->prepare($sql);
$stmt->execute([':id' => $_GET['id']]);
// 如果条件来自外部, 例如 url 中 get 参数
// echo $_GET['id'];
if ($stmt->rowCount() > 0) {
echo 'id = ' . $_GET['id'] . ' 删除成功';
} else {
echo '删除失败';
print_r($stmt->errorInfo());
}
数据的单条查询:
<?php
namespace php_edu;
use PDO;
// 1. 连接数据库
require __DIR__ . '/config/connect.php';
// 2. CURD: SELECT 单条查询
// SELECT 字段列表 FROM 表名 WHERE 查询条件
$sql = 'SELECT `id`,`name` FROM `staff` WHERE `id` > :id';
$stmt = $db->prepare($sql);
$stmt->execute(['id' => 10]);
// 单条查询
// $staff = $stmt->fetch(PDO::FETCH_ASSOC);
// printf('<pre>%s</pre>', print_r($staff, true));
// $staff = $stmt->fetch(PDO::FETCH_ASSOC);
// printf('<pre>%s</pre>', print_r($staff, true));
// $staff = $stmt->fetch(PDO::FETCH_ASSOC);
// printf('<pre>%s</pre>', print_r($staff, true));
// $staff = $stmt->fetch(PDO::FETCH_ASSOC);
// var_dump($staff);
// PDO::FETCH_ASSOC: 结果集获取模式,只返回关联部分
while ($staff = $stmt->fetch()) {
printf('<pre>%s</pre>', print_r($staff, true));
}
fetch() 方法 fetch() 是 PDOStatement 对象的一个方法,用于从结果集中获取下一行数据。每次调用 fetch() 方法时,它会返回结果集中的下一行数据,并且将内部指针移动到下一行。当没有更多行数据时,fetch() 方法会返回 false。 PDO::FETCH_ASSOC PDO::FETCH_ASSOC 是一个常量,作为 fetch() 方法的参数,用于指定返回数据的格式。当使用 PDO::FETCH_ASSOC 时,fetch() 方法会以关联数组的形式返回结果集中的一行数据,关联数组的键是结果集中的列名,值是对应列的值。(因为如果直接fetch(PDO)的话会返回关联数组和索引数组)。 printf 是 PHP 中的一个格式化输出函数,它可以按照指定的格式将变量的值输出到屏幕上。
printf(format, arg1, arg2, ...);
其中,format 是一个字符串,包含了格式说明符(如 %s 表示字符串),arg1, arg2, ... 是要输出的变量。 %s 格式说明符 在 printf 的 format 参数中,%s 是一个格式说明符,表示要输出一个字符串。printf 会将 %s 替换为后面传入的字符串参数。 print_r 函数 print_r 是 PHP 中用于打印变量详细信息的函数,常用于打印数组或对象。它有两个参数: 第一个参数是要打印的变量。 第二个参数是一个布尔值,如果设置为 true,print_r 不会直接输出结果,而是将结果作为字符串返回;如果设置为 false 或省略该参数,print_r 会直接将结果输出到屏幕上。 数据的多条查询:
<?php
namespace php_edu;
use PDO;
// 1. 连接数据库
require __DIR__ . '/config/connect.php';
// 2. CURD: SELECT 多条查询
// SELECT 字段列表 FROM 表名 WHERE 查询条件
$sql = 'SELECT `id`,`name` FROM `staff` WHERE `id` > :id';
$stmt = $db->prepare($sql);
$stmt->execute(['id' => 10]);
// fetchAll: 返回全部满足条件的记录集合,二维数组
$staffs = $stmt->fetchAll();
// print_r($staffs);
foreach ($staffs as $staff) {
printf('<pre>%s</pre>', print_r($staff, true));
}
fetchAll:该方法会返回一个包含结果集中所有行数据的数组。