Maison  >  Article  >  développement back-end  >  Installation, configuration et utilisation d'objets PDO à collecter en php

Installation, configuration et utilisation d'objets PDO à collecter en php

WBOY
WBOYavant
2021-12-20 18:34:391832parcourir

Cet article vous apporte des connaissances sur l'objet pdo en PHP. L'extension PHP Data Object (PDO) définit une interface légère et cohérente pour que PHP puisse accéder à la base de données. Comment le comprendre et l'utiliser ensemble ? ça aide tout le monde.

Installation, configuration et utilisation d'objets PDO à collecter en php

Compréhension des objets PDO

1.1 Introduction

                      L'extension PHP Data Objects (PDO) définit une interface légère et cohérente permettant à PHP d'accéder à la base de données. Chaque pilote de base de données qui implémente l'interface PDO peut exposer des fonctionnalités spécifiques à la base de données sous forme d'extensions standard. Notez que l'utilisation des extensions PDO en elle-même n'implémente aucune fonctionnalité de base de données ; un pilote PDO spécifique à la base de données doit être utilisé pour accéder aux services de base de données.
PDO fournit une couche d'abstraction d'accès aux données, ce qui signifie que quelle que soit la base de données utilisée, les mêmes fonctions (méthodes) peuvent être utilisées pour interroger et obtenir des données. PDO ne fournit pas de couche d'abstraction de base de données ; il ne réécrit pas SQL et n'émule pas les fonctionnalités manquantes. Si nécessaire, une couche d'abstraction mature doit être utilisée.

1.2 Méthode d'installation et de configuration

  • PDO et tous les principaux pilotes sont publiés avec PHP en tant qu'extensions partagées. Pour les activer, modifiez simplement le fichier php.ini :
extension=php_pdo.dll

Remarque : Cette étape est requise dans PHP 5.3 et supérieur. Ce n'est pas nécessaire dans les versions supérieures, car PDO n'a plus besoin d'être un fichier DLL.

  • Si vous souhaitez vous connecter à la base de données, vous devez également supprimer le signe ";" devant l'extension de base de données liée à PDO, puis redémarrer le serveur Apache.
extension=php_pdo.dll
extension=php_pdo_firebird.dll
extension=php_pdo_informix.dll
extension=php_pdo_mssql.dll
extension=php_pdo_mysql.dll
extension=php_pdo_oci.dll
extension=php_pdo_oci8.dll
extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll

1.3 PDO Class

1.3.1 PDO :: __ Construct

pdo :: __ Construct - Créez une instance PDO qui représente une connexion de base de données

  • Description
PDO::__construct ( string $dsn , string $username = ? , string $password = ? , array $driver_options = ? )
  • Parameters
    • dsn
      Le nom de la source de données, ou DSN, contient les informations demandées pour se connecter à la base de données. En règle générale, un DSN se compose du nom du pilote PDO, suivi de deux points et de la syntaxe de connexion pour le pilote PDO spécifique. Exemple :

      mysql:host=localhost;dbname=pxscj

    • username
      Nom d'utilisateur dans la chaîne DSN. Pour certains pilotes PDO, ce paramètre est facultatif.
    • password
      Le mot de passe dans la chaîne DSN. Pour certains pilotes PDO, ce paramètre est facultatif.
    • driver_options
      Un tableau clé => valeur d'options de connexion pour un pilote spécifique.
  • Valeur de retour
    En cas de succès, un objet PDO est renvoyé.
  • Exemple
<?php /* Connect to an ODBC database using driver invocation */$dsn = &#39;mysql:host=localhost;dbname=pxscj&#39;;$user = &#39;user&#39;;$password = &#39;123456&#39;;try {
    $dbh = new PDO($dsn, $user, $password);} catch (PDOException $e) {
    echo &#39;Connection failed: &#39; . $e->getMessage();}?>

1.3.2 PDO::exec

PDO::exec — Exécute une instruction SQL et renvoie le nombre de lignes affectées

  • Description
PDO::exec ( string $statement ) : int
  • Par amètres
    • statement
      L'instruction SQL à préparer et à exécuter.

      Insight : L'instruction ici doit gérer correctement les entrées de l'utilisateur pour empêcher l'injection SQL

  • Valeur de retour
    PDO::exec() renvoie le nombre de lignes affectées par la modification ou la suppression de l'instruction SQL. S'il n'y a aucune ligne affectée, PDO::exec() renvoie 0.
  • Exemple
<?php $db=new PDO("mysql:host=localhost;dbname=PXSCJ","user","123456");$delete_sql="delete from userinfo where username=&#39;user1&#39;";    //注销自己的SQL语句$affected=$db->exec($delete_sql);              //执行没有返回的sql语句$delete_sqlif($affected)                                  //如果受影响记录数不为0
    echo "注销用户成功!";else
    echo "注销用户失败!";?>

1.3.3 PDO::query

PDO::query — Exécute une instruction SQL et renvoie le jeu de résultats sous la forme d'un objet PDOStatement

  • Description
public PDO::query ( string $statement ) : PDOStatement
  • Paramètres
    • statement
      Instructions SQL qui doivent être préparées et exécutées.
  • Valeur de retour
    PDO::query() renvoie un objet PDOStatement ou renvoie false en cas d'échec.
  • Exemple
<?php $db=new PDO("mysql:host=localhost;dbname=pxscj","user","123456");$query="select * from kcb";                 //SQL语句foreach($db->query($query) as $row) {       //执行SQL语句$query--执行有结果集的SQL语句
    echo "课程号:".$row[0]."<br>";          //返回的是一个PDOStatement类(型)的对象
    echo "课程名:".$row[1]."<br>";          //还可以用PDOStatement类的方法fetch()行读
    echo "开课日期:".$row[2]."<br>"; 
    echo "学时:".$row[3]."<br><br>";}?>

1.3.4 PDO::prepare

PDO::prepare — Prépare l'instruction à exécuter et renvoie l'objet d'instruction

  • Description
public PDO::prepare ( string $statement , array $driver_options = array() ) : PDOStatement

La méthode ute() prépare le Instruction SQL à exécuter. Une instruction SQL peut contenir zéro ou plusieurs marqueurs d'espace réservé de paramètre, sous la forme de noms (:name) ou de points d'interrogation (?), qui seront remplacés par des données réelles lors de son exécution. Dans la même instruction SQL, la forme nommée et la forme point d'interrogation ne peuvent pas être utilisées en même temps ; une seule des formes paramètres peut être sélectionnée. Remarque : 用参数形式绑定用户输入的数据,不要直接字符串拼接到查询里,防SQL注入

  • paramètres
    • statement
      doit être un modèle d'instruction SQL valide pour le serveur de base de données cible. Le tableau

    • driver_options
      contient une ou plusieurs paires clé-valeur clé=>valeur pour définir les propriétés de l'objet PDOStatement renvoyé.

  • 返回值
    如果数据库服务器完成准备了语句, PDO::prepare() 返回 PDOStatement 对象。 如果数据库服务器无法准备语句, PDO::prepare() 返回 false 或抛出 PDOException (取决于 错误处理器)。
    注:模拟模式下的 prepare 语句不会和数据库服务器交互,所以 PDO::prepare() 不会检查语句。
  • 示例
$db=new PDO("mysql:host=localhost;dbname=pxscj","user","123456");$in_sql="insert into userinfo(username,password,sex,age,email) values(?,?,?,?,?)";  $in_result=$db->prepare($in_sql);                                                   //预处理SQL语句$in_sql$userid="php3"; $pwd1="111111"; $sex=0; $age=36; $email="php3@qq.com";$in_result->bindParam(1, $userid);   //PDOStatement的bindParam()的作用是绑定参数给execute()$in_result->bindParam(2, $pwd1);    //SQL语句使用问号参数时--bindParam()第一个参数是问号索引偏移(第几个)$in_result->bindParam(3, $sex);     //bindParam()第二个参数是赋值给SQL语句参数(问号)的变量$in_result->bindParam(4, $age);          $in_result->bindParam(5, $email);$in_result->execute();             //执行经过预处理的SQL语句$in_resultif($in_result->rowCount()==0)     //用PDOStatement的rowCount()返回结果集行的总数
    echo "插入记录失败!";else
    echo "插入记录成功!";

1.3.5 PDO::beginTransaction

PDO::beginTransaction — 启动一个事务

  • 说明
PDO::beginTransaction():bool
  • 返回值
    成功时返回 true, 或者在失败时返回 false。

1.3.6 PDO::rollBack

PDO::rollBack — 回滚一个事务

  • 说明
PDO::rollBack():bool

回滚由 PDO::beginTransaction() 发起的当前事务。如果没有事务激活,将抛出一个 PDOException 异常。
如果数据库被设置成自动提交模式,此函数(方法)在回滚事务之后将恢复自动提交模式。

  • 返回值
    成功时返回 true, 或者在失败时返回 false。
  • 示例
<?php /* 开始一个事务,关闭自动提交 */$dbh->beginTransaction();/* 更改数据库架构和数据  */$sth = $dbh->exec("DROP TABLE fruit");$sth = $dbh->exec("UPDATE dessert
    SET name = 'hamburger'");/*  识别错误且回滚更改  */$dbh->rollBack();/*  此时数据库连接恢复到自动提交模式  */?>

1.3.7 内部函数说明

PDO::beginTransaction — 启动一个事务
PDO::commit — 提交一个事务
PDO::__construct — 创建一个表示数据库连接的 PDO 实例
PDO::errorCode — 获取跟数据库句柄上一次操作相关的 SQLSTATE
PDO::errorInfo — Fetch extended error information associated with the last operation on the database handle
PDO::exec — 执行一条 SQL 语句,并返回受影响的行数
PDO::getAttribute — 取回一个数据库连接的属性
PDO::getAvailableDrivers — 返回一个可用驱动的数组
PDO::inTransaction — 检查是否在一个事务内
PDO::lastInsertId — 返回最后插入行的ID或序列值
PDO::prepare — 准备要执行的语句,并返回语句对象
PDO::query — 执行 SQL 语句,以 PDOStatement 对象形式返回结果集
PDO::quote — 为 SQL 查询里的字符串添加引号
PDO::rollBack — 回滚一个事务
PDO::setAttribute — 设置属性

1.4 PDOStatement类

1.4.1 PDOStatement::bindParam

PDOStatement::bindParam — 绑定一个参数到指定的变量名

  • 说明
PDOStatement::bindParam ( mixed $parameter , mixed &$variable , int $data_type = PDO::PARAM_STR , int $length = ? , mixed $driver_options = ? ):bool

绑定一个PHP变量到用作预处理的SQL语句中的对应命名占位符或问号占位符。 不同于 PDOStatement::bindValue() ,此变量作为引用被绑定,并只在 PDOStatement::execute() 被调用的时候才取其值。

  • 返回值
    成功时返回 true, 或者在失败时返回 false。
  • 参数  
    • parameter
      参数标识符。对于使用命名占位符的预处理语句,应是类似 :name 形式的参数名。对于使用问号占位符的预处理语句,应是以1开始索引的参数位置。
    • variable
      绑定到 SQL 语句参数的 PHP 变量名。
    • data_type
      使用 PDO::PARAM_* 常量明确地指定参数的类型。要从一个存储过程中返回一个 INOUT 参数,需要为 data_type 参数使用按位或操作符去设置 PDO::PARAM_INPUT_OUTPUT 位。
    • length
      数据类型的长度。为表明参数是一个存储过程的 OUT 参数,必须明确地设置此长度。
    • driver_options
  • 示例
<?php /* 通过绑定的 PHP 变量执行一条预处理语句  */$calories = 150;$colour = &#39;red&#39;;$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories bindParam(':calories', $calories, PDO::PARAM_INT);$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);$sth->execute();?>

1.4.2 PDOStatement::execute

PDOStatement::bindParam — 绑定一个参数到指定的变量名

  • 说明
PDOStatement::execute ( array $input_parameters = ? ) : bool

执行预处理过的语句。如果预处理过的语句含有参数标记,必须选择下面其中一种做法:

1)调用 PDOStatement::bindParam() 绑定 PHP 变量到参数标记:如果有的话,通过关联参数标记绑定的变量来传递输入值和取得输出值
2)或传递一个只作为输入参数值的数组

  • 返回值
    成功时返回 true, 或者在失败时返回 false。
  • 参数  
    • input_parameters
  • 示例
<?php /* 通过传递一个含有插入值的数组执行一条预处理语句 */$calories = 150;$colour = &#39;red&#39;;$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories execute(array(':calories' => $calories, ':colour' => $colour));?>

1.4.3 PDOStatement::fetch

PDOStatement::fetch — 从结果集中获取下一行

  • 说明
PDOStatement::fetch ( int $fetch_style = ? , int $cursor_orientation = PDO::FETCH_ORI_NEXT , int $cursor_offset = 0 ):mixed

从一个 PDOStatement 对象相关的结果集中获取下一行。fetch_style 参数决定 POD 如何返回行。

  • 返回值
    此函数(方法)成功时返回的值依赖于提取类型。在所有情况下,失败都返回 false 。
  • 参数
  • fetch_style
    控制下一行如何返回给调用者。此值必须是 PDO::FETCH_* 系列常量中的一个,缺省为 PDO::ATTR_DEFAULT_FETCH_MODE 的值 (默认为 PDO::FETCH_BOTH )。
PDO::FETCH_ASSOC:返回一个索引为结果集列名的数组
PDO::FETCH_BOTH(默认):返回一个索引为结果集列名和以0开始的列号的数组
PDO::FETCH_BOUND:返回 true ,并分配结果集中的列值给 PDOStatement::bindColumn() 方法绑定的 PHP 变量。
PDO::FETCH_CLASS:返回一个请求类的新实例,映射结果集中的列名到类中对应的属性名。如果 fetch_style 包含 PDO::FETCH_CLASSTYPE(例如:PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE),则类名由第一列的值决定
PDO::FETCH_INTO:更新一个被请求类已存在的实例,映射结果集中的列到类中命名的属性
PDO::FETCH_LAZY:结合使用 PDO::FETCH_BOTH 和 PDO::FETCH_OBJ,创建供用来访问的对象变量名
PDO::FETCH_NUM:返回一个索引为以0开始的结果集列号的数组
PDO::FETCH_OBJ:返回一个属性名对应结果集列名的匿名对象
  • cursor_orientation
    对于 一个 PDOStatement 对象表示的可滚动游标,该值决定了哪一行将被返回给调用者。此值必须是PDO::FETCH_ORI_* 系列常量中的一个,默认为 PDO::FETCH_ORI_NEXT。
  • offset
    对于一个 cursor_orientation 参数设置为 PDO::FETCH_ORI_ABS 的PDOStatement 对象代表的可滚动游标,此值指定结果集中想要获取行的绝对行号。
  • 示例
<?php $sth = $dbh->prepare("SELECT name, colour FROM fruit");$sth->execute();/* 运用 PDOStatement::fetch 风格 */print("PDO::FETCH_ASSOC: ");print("Return next row as an array indexed by column name\n");$result = $sth->fetch(PDO::FETCH_ASSOC);print_r($result);print("\n");?>

1.4.4 PDOStatement::execute

PDOStatement::fetchAll — 返回一个包含结果集中所有行的数组

  • 说明
PDOStatement::fetchAll ( int $fetch_style = ? , mixed $fetch_argument = ? , array $ctor_args = array() ):array
  • 返回值
    PDOStatement::fetchAll() 返回一个包含结果集中所有剩余行的数组。此数组的每一行要么是一个列值的数组,要么是属性对应每个列名的一个对象。
    注:使用此方法获取大结果集将导致系统负担加重且可能占用大量网络资源。与其取回所有数据后用PHP来操作,倒不如考虑使用数据库服务来处理结果集。例如,在取回数据并通过PHP处理前,在 SQL 中使用 WHERE 和 ORDER BY 子句来限定结果。
  • 参数  
    • fetch_style
      控制返回数组的内容如同 PDOStatement::fetch()一样。默认为 PDO::ATTR_DEFAULT_FETCH_MODE 的值( 其缺省值为 PDO::FETCH_BOTH )想要返回一个包含结果集中单独一列所有值的数组,需要指定 PDO::FETCH_COLUMN 。通过指定 column-index 参数获取想要的列。
    • fetch_argument
      根据 fetch_style 参数的值,此参数有不同的意义:
      PDO::FETCH_COLUMN:返回指定以0开始索引的列。
      PDO::FETCH_CLASS:返回指定类的实例,映射每行的列到类中对应的属性名。
      PDO::FETCH_FUNC:将每行的列作为参数传递给指定的函数,并返回调用函数后的结果。
    • ctor_args
      当 fetch_style 参数为 PDO::FETCH_CLASS 时,自定义类的构造函数的参数。
  • 示例
<?php $sth = $dbh->prepare("SELECT name, colour FROM fruit");$sth->execute();/* 获取结果集中所有剩余的行 */print("Fetch all of the remaining rows in the result set:\n");$result = $sth->fetchAll();print_r($result);?>

1.4.5 PDOStatement::rowCount

PDOStatement::rowCount — 返回受上一个 SQL 语句影响的行数

  • 说明
PDOStatement::rowCount():int

       PDOStatement::rowCount() 返回上一个由对应的 PDOStatement 对象执行DELETE、 INSERT、或 UPDATE 语句受影响的行数。
       如果上一条由相关 PDOStatement 执行的 SQL 语句是一条 SELECT 语句,有些数据可能返回由此语句返回的行数。但这种方式不能保证对所有数据有效,且对于可移植的应用不应依赖于此方式。

  • 返回值
    返回行数。
  • 示例
<?php /*  从 FRUIT 数据表中删除所有行 */$del = $dbh->prepare('DELETE FROM fruit');$del->execute();/*  返回被删除的行数 */print("Return number of rows that were deleted:\n");$count = $del->rowCount();print("Deleted $count rows.\n");?>

1.4.6 内部函数说明

PDOStatement::bindColumn — 绑定一列到一个 PHP 变量
PDOStatement::bindParam — 绑定一个参数到指定的变量名
PDOStatement::bindValue — 把一个值绑定到一个参数
PDOStatement::closeCursor — 关闭游标,使语句能再次被执行。
PDOStatement::columnCount — 返回结果集中的列数
PDOStatement::debugDumpParams — 打印一条 SQL 预处理命令
PDOStatement::errorCode — 获取跟上一次语句句柄操作相关的 SQLSTATE
PDOStatement::errorInfo — 获取跟上一次语句句柄操作相关的扩展错误信息
PDOStatement::execute — 执行一条预处理语句
PDOStatement::fetch — 从结果集中获取下一行
PDOStatement::fetchAll — 返回一个包含结果集中所有行的数组
PDOStatement::fetchColumn — 从结果集中的下一行返回单独的一列。
PDOStatement::fetchObject — 获取下一行并作为一个对象返回。
PDOStatement::getAttribute — 检索一个语句属性
PDOStatement::getColumnMeta — 返回结果集中一列的元数据
PDOStatement::nextRowset — 在一个多行集语句句柄中推进到下一个行集
PDOStatement::rowCount — 返回受上一个 SQL 语句影响的行数
PDOStatement::setAttribute — 设置一个语句属性
PDOStatement::setFetchMode — 为语句设置默认的获取模式。

1.5 用法及小结

      以上PDO类及PDOStatement类的说明摘录自php开发手册,详细描述只摘录了常用的几个内部函数。实话实说对于一个程序员最好的提升技术的方法之一就是看文档,通过查阅文档可以解决我们在开发中遇到的许多问题,而且通过文档我们可以知道很多api使用的细节和注意点,帮助我们规避很多错误。总而言之遇到问题看文档,多百度,多看博客,多总结,这才是长久的学习之道。
      多说不做也是不行的,练习才是技术提升的必由之路,练习实践才可以在其中发现问题,提升自己,下面代码是我对PDO的一些常见用法的整理:

try {	
    $db=new PDO("mysql:host=localhost;dbname=pxscj","user","123456"); }catch (PDOException $e) {       
    echo "数据库连接失败:".$e->getMessage(); }$db->exec("set names utf-8");  //插入                             $query="insert into kcb values('606','PHP程序设计',6,48,3)";   if($affCount=$db->exec($query)) {                           
    echo "插入成功,受影响条数为:".$affCount."<br><br>";                }//查询$query="select * from kcb";                                 foreach($db->query($query) as $row) {        
    echo "课程号:".$row[0]."<br>";   
    echo "课程名:".$row[1]."<br>";  
    echo "开课日期:".$row[2]."<br>"; 
    echo "学时:".$row[3]."<br><br>";}//事务处理try {   
    $db->exec("set names utf-8");                           
    $db->beginTransaction();                                 
    $affrows=$db->exec("insert into kcb values('506','UML系统分析',5,48,3)");    
    if(!$affrows)
        throw new PDOException("插入失败1");
    $affrows=$db->exec("insert into kcb values('606','PHP程序设计',6,32,2)");  
    if(!$affrows)
        throw new PDOException("插入失败2");
    echo "插入成功!"; 
    $db->commit();                                         }catch (PDOException $e) {                                   
    echo $e->getMessage(); 
    $db->rollBack();   //回滚(要么成功要么失败)}//prepare 可以防sql注入$in_sql="insert into userinfo(username,password,sex,age,email) values(?,?,?,?,?)"; $in_result=$db->prepare($in_sql); $userid="php3"; $pwd1="111111"; $sex=0; $age=36; $email="php3@qq.com";$in_result->bindParam(1, $userid); $in_result->bindParam(2, $pwd1);         $in_result->bindParam(3, $sex);       $in_result->bindParam(4, $age);       $in_result->bindParam(5, $email);$in_result->execute();    if($in_result->rowCount()==0)       
    echo "插入记录失败!";else
    echo "插入记录成功!";//更新 改密码$oldpwd=$_POST['oldpwd'];				                           //原密码$newpwd=$_POST['newpwd'];				                           //新密码$s_sql="select * from userinfo where username='$username'";                   //SQL语句$s_result=$db->query($s_sql);                                                list($username,$password,$sex,$age,$email)=$s_result->fetch(PDO::FETCH_NUM);if($password!=$oldpwd)					                   //判断原密码是否正确
    echo "原密码错误!";else {
    $checkpwd=preg_match('/^\w{6,20}$/',$newpwd);if(!$checkpwd)
    echo "新密码格式不满足要求!";else {
    $update_sql="update userinfo set password='$newpwd' where username='$username'";  
    $affected=$db->exec($update_sql); 
    if($affected)
        echo"密码修改成功!";
    else
        echo "密码修改失败!";
    }}//删除 注销session_start();$username=@$_SESSION['userid'];$delete_sql="delete from userinfo where username='$username'";    //注销自己的SQL语句$affected=$db->exec($delete_sql);                                if($affected)             
    echo "注销用户成功!";else
    echo "注销用户失败!";

1.6 PDO与JPA闲谈

      软件开发框架总是有很多互通的地方,因为无论任何开发语言,java或者php底层实现都离不开数据结构,算法,还有软件设计模式,而这些都是互通的,而好的软件框架离不开设计模式运用.
自从学习php接触了解到PDO对象扩展时我便联想到我曾使用的springboot JPA持久层框架,于是我查了些资料,以下便是我的个人理解:
       首先先解释一下PDO和JPA的概念

  • PDO

PHP 数据对象(PHP Data Objects) 扩展为PHP访问数据库定义了一个轻量级的一致接口。
PDO 提供了一个 数据访问 抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据。PDO 不提供 数据库 抽象层;它不会重写 SQL,也不会模拟缺失的特性。如果需要的话,应该使用一个成熟的抽象层。

  • PDO架构概念图
    Installation, configuration et utilisation dobjets PDO à collecter en php

  • JPA

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而接口是需要实现才能工作的。所以底层需要某种实现,而Hibernate就是实现了JPA接口的ORM框架。

  • JPA 概念关系图

Installation, configuration et utilisation dobjets PDO à collecter en php

      从上述概念和架构图可以看出PDO和JPA还是有一定区别的。首先PHP的PDO只是一个抽象的数据访问接口层,它对数据库的访问还要依赖相应的数据库驱动,而且需要自行编写操作数据的SQL语句。
      而java的JPA则是一个持久层规范,也就是说JPA仅仅定义了一些接口,这些接口是关于类和数据库表的映射的,也就是说,JPA这个规范在数据访问接口层之上,而真正实现这个规范和底层数据访问接口是在如Hibernate的这些数据持久层框架内.
      以Hibernate这个持久层框架为例,它实现了对象和数据库表的映射关系,仅需要操作相应的访问DAO层接口即可实现数据库的查询并转换为java对象内部属性数据。而Hibernate底层对数据库的访问还得依赖JDBC接口。
      由此可见PDO和JPA规范完全处于两个不同层次,JPA是数据访问方法底层的高层次抽象,而PDO仅相当于java的JDBC接口层。PDO的抽象层次相对较低,这也符合PHP的轻量级web开发语言
的特点,这也是它的一个优点,可以方便清晰地实现一些复杂的数据库访问操作,但不利于复杂的高抽象度的大型项目的开发.
      以上内容为个人对PHP PDO对象和java JPA规范的一些理解和比较,水平有限,可能会有不准确的地方。

1.7 实验问题与总结

1.7.1 mysql连接

php使用mysql原生密码连接如

$conn=mysqli_connect('localhost','user','123456')or die('连接失败');

会出现错误:The server requested authentication method unknown to the client.
原因:
由于本地使用mysql版本在8.0以上,而mysql 8升级了密码的验证方式 caching_sha2_password,所以原生连接会失败,解决办法使用sql修改用户登录验证方式:

use mysql;ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';

1.7.2 sql注入总结

php使用mysqli或pdo的query方法查询时,如未对用户表单输入数据进行处理可能会存在SQL注入隐患,如

$username=$_POST['username'];$password=$_POST['password']; //magic_quotes_gpc设为off的情况下//mysql$conn = mysqli_connect("localhost", "user" ,"123456") or die('连接失败'); //mysql_connect()链接MySQL服务器mysqli_select_db($conn,'PXSCJ') or die('选择数据库失败'); //mysql_select_db()选择数据库mysqli_query($conn,"SET NAMES utf-8");//设置字符集为utf-8$str="select * from userinfo where username='$username' and password='$password'";$result=mysqli_query($conn,$str); //PDO//连接数据库,新建PDO对象$pdo=new PDO("mysql:host=localhost;dbname=pxscj","user","123456");$str="select * from userinfo where username='$username' and password='$password'";$result=$pdo->query($str);

当用户输入username值为user,password值为123 ' or 1=1,即查询sql被转义为:

select * from userinfo where username='user' and password='123 ' or ' 1=1'

则用户将跳过密码的查询验证得到所有userinfo的数据,并且还存在其他SQL语句越权执行的风险
处理风险的方法有以下几种:

  • addslashes()函数转义
$password=addslashes($password);

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。预定义字符是:
单引号(')
双引号(")
反斜杠(\)
NULL

  • 使用PDO对象的prepare()方法
$sql="select * from userinfo where username='$username' and password='$password'";//注意不是中文状态下的问号? $result=$pdo->prepare($sql); //按照?的顺序绑定参数值 $result->bindParam(1,$username); $result->bindParam(2,$password); $result->execute();

大家如果感兴趣的话,可以点击《PHP视频教程》进行更多关于PHP知识的学习。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer