小熊奶糖(BearCandy)
小熊奶糖(BearCandy)
发布于 2024-03-28 / 34 阅读
0
0

PHP PDO 事物,连接数据库,try catch异常捕获,批量插入数据,插入数据,删除数据,fetch(),fetchAll()

在PHP中,使用PDO连接数据库并实现异常处理、批量插入数据以及插入和删除数据的操作可以通过以下步骤完成:

连接数据库并设置异常处理

<?php
// 定义数据库连接参数
$dbHost = 'localhost';
$dbName = 'your_database_name';
$dbUser = 'username';
$dbPass = 'password';

// 创建DSN字符串
$dsn = "mysql:host=$dbHost;dbname=$dbName;charset=utf8";

try {
    // 创建PDO实例
    $pdo = new PDO($dsn, $dbUser, $dbPass);

    // 设置PDO错误模式为异常
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  
    // 如果需要,设置其他属性如初始化命令(例如设置字符集)
    // $pdo->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8");

} catch (PDOException $e) {
    // 捕获并输出数据库连接错误信息
    die("Connection failed: " . $e->getMessage());
}

// 接下来进行数据操作
?>

批量插入数据

假设有一个 users表,结构如下:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50),
    email VARCHAR(100)
);

批量插入数据的例子:

$dataToInsert = [
    ['username' => 'user1', 'email' => 'user1@example.com'],
    ['username' => 'user2', 'email' => 'user2@example.com'],
    // 更多用户数据...
];

$sqlTemplate = "INSERT INTO users (username, email) VALUES (:username, :email)";

$stmt = $pdo->prepare($sqlTemplate);

foreach ($dataToInsert as $userData) {
    $stmt->bindParam(':username', $userData['username']);
    $stmt->bindParam(':email', $userData['email']);

    try {
        $stmt->execute();
    } catch (PDOException $e) {
        // 输出或处理插入失败的异常
        echo "Error inserting data: " . $e->getMessage();
    }
}

插入单条数据

$insertData = ['username' => 'new_user', 'email' => 'new_user@example.com'];

$sql = "INSERT INTO users (username, email) VALUES (:username, :email)";

$stmt = $pdo->prepare($sql);
$stmt->bindParam(':username', $insertData['username']);
$stmt->bindParam(':email', $insertData['email']);

try {
    $stmt->execute();
    echo "New record created successfully";
} catch (PDOException $e) {
    echo "Error inserting data: " . $e->getMessage();
}

删除数据

删除指定ID的数据:

$idToDelete = 123;

$sql = "DELETE FROM users WHERE id = :id";

$stmt = $pdo->prepare($sql);
$stmt->bindParam(':id', $idToDelete);

try {
    $stmt->execute();
    echo "Record deleted successfully";
} catch (PDOException $e) {
    echo "Error deleting data: " . $e->getMessage();
}

请注意,在实际应用中,确保对用户输入进行适当的过滤和转义,以防止SQL注入攻击,并且在必要时使用事务处理以确保数据完整性。

PDO(PHP Data Objects)在处理数据库操作错误时提供了三种不同的模式:

  1. PDO::ERRMODE_SILENT(静默模式,默认模式)

    • 在这种模式下,当发生错误时,PDO不会抛出异常,也不会产生任何 PHP 错误警告。它仅将错误代码和信息保存到PDO对象内部,开发者需要通过 $pdo->errorCode()$pdo->errorInfo() 方法手动检查错误。
  2. PDO::ERRMODE_WARNING

    • 当选择此模式时,PDO在遇到错误时会产生 E_WARNING 级别的错误消息,并将其记录至PHP错误日志或显示在标准输出中(取决于错误报告级别)。同时,仍可通过上述方法获取错误详情。
  3. PDO::ERRMODE_EXCEPTION

    • 此模式下,PDO在遇到错误时会抛出一个 PDOException 异常。这意味着你可以通过 try-catch 结构来捕获和处理这些异常,这通常被认为是一种更面向对象和更健壮的错误处理方式。

示例代码更改错误模式为异常模式:

try {
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    // 处理数据库连接错误
    echo 'Connection failed: ' . $e->getMessage();
}

在异常模式下,如果你尝试执行一个无效的SQL语句或者发生其他数据库错误,将会抛出异常,可以像下面这样处理:

try {
    $stmt = $pdo->prepare('SELECT * FROM non_existent_table');
    $stmt->execute();

    // ... 操作数据 ...
} catch (PDOException $e) {
    // 处理查询或其他数据库操作产生的异常
    echo 'Database error: ' . $e->getMessage();
    // 可能还需要记录错误日志或进行其他恢复操作
}

PDO(PHP Data Objects)中的事务(Transaction)允许你作为一个单独的工作单元执行一系列数据库操作,这些操作要么全部成功,要么全部失败。在事务处理中,如果其中一个操作失败,则所有已经执行的操作都会被回滚到事务开始前的状态,从而保持数据库的一致性。

在PDO中开启、执行和管理事务的基本步骤如下:

  1. 开启事务:

    $pdo->beginTransaction(); // 开始一个新的事务
    
  2. 在事务内执行多个SQL操作:

    try {
        $pdo->exec("INSERT INTO table1 (...) VALUES (...)");
        $pdo->exec("UPDATE table2 SET column = value WHERE condition");
        // 更多的数据库操作...
    
        // 如果所有的SQL语句都执行成功,提交事务
        $pdo->commit();
    } catch (PDOException $e) {
        // 如果在执行过程中有任何错误,回滚事务
        $pdo->rollBack();
        echo "Transaction failed: " . $e->getMessage();
    }
    
  3. 提交事务:

    • commit() 方法用于提交事务,一旦提交,所有在事务块内的修改都将永久地写入数据库。
  4. 回滚事务:

    • rollBack() 方法用于取消事务中的所有更改,当事务中有错误发生或你想放弃这次操作时,调用该方法。
  5. 自动提交:

    • 默认情况下,PDO连接会启用自动提交模式,即每执行一次SQL语句就会自动提交一次。但在进行事务处理时,通常会先禁用自动提交,然后手动控制事务的开始、提交和回滚。
  6. 示例代码片段:

    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 启用异常模式
    
    $pdo->beginTransaction();
    
    try {
        $stmt1 = $pdo->prepare("INSERT INTO some_table (...) VALUES (...)");
        $stmt1->execute();
    
        $stmt2 = $pdo->prepare("UPDATE another_table SET ... WHERE ...");
        $stmt2->execute();
    
        // ... 其他数据库操作 ...
    
        $pdo->commit(); // 如果这里没有抛出异常,事务将被提交
    } catch (PDOException $e) {
        $pdo->rollBack(); // 如果有异常,事务将被回滚
        echo "An error occurred during transaction: " . $e->getMessage();
    }
    

事务功能的成功执行依赖于所使用的MySQL存储引擎是否支持事务处理,例如InnoDB引擎就支持事务,而MyISAM引擎则不支持事务。

在PHP中使用PDO(PHP Data Objects)查询数据库的基本步骤包括:

  1. 建立数据库连接

    <?php
    $servername = "127.0.0.1";
    $username = "root";
    $password = "a13834841085";
    $dbname = "db_test";
    
    try {
        $dsn = "mysql:host=$servername;port=3306;dbname=$dbname;charset=utf8";
        $pdo = new PDO($dsn, $username, $password);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        echo "数据库连接成功!\n";
    } catch (PDOException $e) {
        echo "数据库连接失败: " . $e->getMessage();
    }
    ?>
    
  2. 执行SQL查询

    • 使用 query()方法执行非预处理的SQL查询:

      $sql = "SELECT * FROM your_table";
      $stmt = $pdo->query($sql);
      
      // 获取查询结果集
      $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
      foreach ($results as $row) {
          print_r($row);
      }
      
    • 使用 prepare()execute()进行预处理查询(有助于防止SQL注入):

      $sql = "SELECT * FROM your_table WHERE id = :id";
      $stmt = $pdo->prepare($sql);
      $stmt->bindParam(':id', $id, PDO::PARAM_INT);
      
      // 设置参数值
      $id = 1;
      $stmt->execute();
      
      // 获取单条结果
      $result = $stmt->fetch(PDO::FETCH_ASSOC);
      echo "查询结果: ";
      print_r($result);
      
  3. 处理查询结果

    • fetch()fetch(PDO::FETCH_ASSOC)用于获取下一行作为关联数组。
    • fetchAll()则获取所有行作为一个二维数组,每一项对应表的一行数据。
    • 若需获取记录数量,可使用 rowCount()方法(对于 SELECT COUNT(*)类型的查询尤其有用)。
  4. 关闭数据库连接(尽管在脚本结束时PDO连接通常会被自动关闭,但也可以手动关闭):

    unset($pdo);
    

或者在使用完PDO对象之后显式关闭连接:

$pdo = null;

总结起来,一个完整的PDO查询示例可能如下所示:

<?php
require_once 'database.php';

$data = include 'database_configuration.php';
$dsn = "mysql:host={$data['db_address']};port={$data['db_port']};dbname={$data['db_name']};charset=utf8";
$username = $data['username'];
$password = $data['password'];

try {
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $id = 1;
    $sql = "SELECT * FROM your_table WHERE id = ?";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$id]);
  
    $result = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($result) {
        echo "查询结果:\n";
        print_r($result);
    } else {
        echo "没有找到匹配的数据!";
    }
  
} catch (PDOException $e) {
    echo "查询执行失败: " . $e->getMessage();
}

// 可选,手动关闭连接
$pdo = null;
?>

在PHP的PDO扩展中,PDOStatement::fetch() 方法用于从结果集中获取下一行数据。此方法有许多可选参数,允许开发者控制如何获取和格式化数据。以下是 fetch()方法的基本签名及其参数说明:

mixed PDOStatement::fetch ([ int $fetch_style [, mixed $cursor_orientation = PDO::FETCH_ORI_NEXT [, int $cursor_offset = 0 ]]] )
  1. $fetch_style:

    • 定义获取数据的方式。它可以是以下常量之一:
      • PDO::FETCH_ASSOC: 返回一个关联数组,其中的键是列名(字段名)。
      • PDO::FETCH_NUM: 返回一个索引数组,其中的索引是列的数字索引(从0开始)。
      • PDO::FETCH_BOTH: 默认选项,返回一个组合数组,包含索引和关联两种形式的键值对。
      • PDO::FETCH_OBJ: 返回一个stdClass对象,其中的属性名对应列名。
      • PDO::FETCH_CLASS: 返回指定类的一个实例,将列名映射到类的属性。
      • PDO::FETCH_LAZY: 延迟绑定模式,只有在访问时才获取列的值。
      • 还有其他如 PDO::FETCH_GROUP, PDO::FETCH_UNIQUE 等模式,用于特殊需求。
  2. $cursor_orientation:

    • 当使用可滚动游标时,决定从哪个方向或位置获取下一行数据。
      • PDO::FETCH_ORI_NEXT: 默认值,获取下一行(同 fetch()通常行为)。
      • PDO::FETCH_ORI_PRIOR: 获取上一行。
      • PDO::FETCH_ORI_FIRST: 移动到第一行并获取。
      • PDO::FETCH_ORI_LAST: 移动到最后一行并获取。
      • PDO::FETCH_ORI_ABS: 根据给定的绝对行号获取。
      • PDO::FETCH_ORI_REL: 根据相对于当前位置的相对行号获取。
  3. $cursor_offset:

    • $cursor_orientationPDO::FETCH_ORI_ABSPDO::FETCH_ORI_REL 时,此参数提供行号。如果是绝对位置,则表示从结果集的第一行开始计算的行号;如果是相对位置,则表示相对于当前游标位置的行数。

举例:

$stmt = $pdo->prepare("SELECT * FROM my_table");
$stmt->execute();

// 获取下一关联数组形式的行
$row = $stmt->fetch(PDO::FETCH_ASSOC);

// 获取下一行并将其视为对象
$objRow = $stmt->fetch(PDO::FETCH_OBJ);

// 使用可滚动游标并在绝对位置3处获取行
$stmt = $pdo->prepare("SELECT * FROM my_table", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->execute();
$rowAtPos3 = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_ABS, 3);

注意:并非所有数据库驱动都支持可滚动游标和所有 $cursor_orientation$cursor_offset 参数组合。在实际应用中,请根据所使用的数据库适配器查阅文档以了解具体支持情况。


评论