PHP Memcached使用详解
翻译烂到家了,看不顺眼轻喷。。。 1.为什么要使用PDO? mysql_函数已经过时,相当一段时间以来,mysql_函数在其他SQL数据库编程接口方面已经有所差别;它不支持预处理,存储过程,事务等一些现代数据库设计思想,SQL语句字符串转义函数 mysql_real_escape_s
翻译烂到家了,看不顺眼轻喷。。。
1.为什么要使用PDO?
mysql_*函数已经过时,相当一段时间以来,mysql_*函数在其他SQL数据库编程接口方面已经有所差别;它不支持预处理,存储过程,事务等一些现代数据库设计思想,SQL语句字符串转义函数 mysql_real_escape_string()
和 拼接SQL语句的编程方法 已经过时并且很容易出错。最近一段时间里,它缺乏开发者的关注,缺少维护将可能导致一些安全问题不能被即时修复,或者在适配新版本的MySQL的时候不能正常工作,这成为mysql_*函数面临的的另一个问题。PHP社区最近也对mysql_*函数给出不建议使用的建议,也有可能在未来的版本中最终被弃用(不过不用过于担心,这可能还需要很长一段时间)。
PDO拥有更好的编程接口,你可以使用它写出更加简洁,高效,安全的代码。PDO还为不同的SQL数据库提供了不同的驱动,方便你使用新的数据库而不用再学习不同的编程接口。与拼接SQL语句构造查询语句不同,绑定参数可以简洁方便的构造出更加安全的查询语句,使用绑定参数的方法在 多次相似语句查询(仅仅某个参数不同)中也可以提高不少性能。PDO在错误处理方面也提供了多种方法。mysql_*函数缺乏一致的处理,与PDO的异常模式相比,或者说没有处理异常,使用PDO,你可以得到一致的错误处理,这将节省您大量的时间来跟踪问题。
在当前的PHP版本中,PDO模块是默认安装启用的,但是在使用PDO前你还需要安装另外两个软件包,一个是pdo_mysql数据库驱动程序,另外一个是类似php-mysql的mysql驱动程序。
2.连接MySQL
以前的方式:
<code>$link = mysql_connect('localhost', 'user', 'pass'); mysql_select_db('testdb', $link); mysql_set_charset('UTF-8', $link); </code>
新的方式:
* 创建一个PDO对象,参数包括 DSN, username, password 和 一个驱动选项的数组(可忽略)。
* DSN其实就是一个告诉PDO该使用哪一种数据库驱动 和 一些连接信息的字符串,了解更多 PDO MYSQL DSN .
<code>$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password'); </code>
注意:确保DSN中设置了字符编码信息,否则将可能返回字符编码设置错误的信息,出于安全考虑,DSN最好包括字符编码信息设置。
你也可以在第四个参数数组里填写一些驱动选项,建议将 PDO异常模式
(下文讲解) 和 关闭预处理模拟
(默认打开的,仅对于旧版本MySQL有用)两个参数加入到第四个参数数组中。
<code>$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password', array(PDO::ATTR_EMULATE_PREPARES => false,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); </code>
你也可以在创建PDO对象后再通过setAttribute方法设置相应选项。
<code>$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password'); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); </code>
3.错误处理
mysql_*函数的错误处理
<code>//connected to mysql $result = mysql_query("SELECT * FROM table", $link) or die(mysql_error($link)); </code>
OR die()
是个不错的错误处理方法,但是会因此结束页面,将错误信息呈现到用户面前,这可能是我们不想看到的结果。
PDO有三种错误处理模式:
- PDO::ERRMODE_SILENT # 和 mysql_*函数类似,检查代码并查看
$db->errorInfo();
获取详细信息。 - PDO::ERRMODE_WARNING # 抛出PHP警告。
- PDO::ERRMODE_EXCEPTION #抛出
PDOException
异常,在我认为,这是我们应该使用的模式, 这和die(mysql_error());
类似,但是它可以捕获并抛出具体异常信息。
code:
<code>try { //connect as appropriate as above $db->query('hi'); //invalid query! } catch(PDOException $ex) { echo "An Error occured!"; //user friendly message some_logging_function($ex->getMessage()); } </code>
注意:你可以不用立即执行并捕获异常,你可以在任何合适的时候随时捕获。
<code>function getData($db) { $stmt = $db->query("SELECT * FROM table"); return $stmt->fetchAll(PDO::FETCH_ASSOC); } //then much later try { getData($db); } catch(PDOException $ex) { //handle me. } </code>
如果你不想使用try/catch
来处理异常,就像使用OR die()
那样处理,在production模式下关闭display_errors
选项即可。
4.简单的查询语句(SELECT
)
mysql_*代码:
<code>$result = mysql_query('SELECT * from table') or die(mysql_error()); $num_rows = mysql_num_rows($result); while($row = mysql_fetch_assoc($result)) { echo $row['field1'].' '.$row['field2']; //etc... } </code>
PDO代码:
<code>foreach($db->query('SELECT * FROM table') as $row) { echo $row['field1'].' '.$row['field2']; //etc... } </code>
query()
方法返回了一个 PDOStatement
对象,你可以通过如下方法获取结果:
<code>$stmt = $db->query('SELECT * FROM table'); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { echo $row['field1'].' '.$row['field2']; //etc... } </code>
或者
<code>$stmt = $db->query('SELECT * FROM table'); $results = $stmt->fetchAll(PDO::FETCH_ASSOC); //use $results </code>
# Fetch Modes
注意 fetch()
和 fetchAll()
代码中的PDO::FETCH_ASSOC
,它高速 PDO 以关联数组的形式返回 键,值;其他比如PDO::FETCH_NUM
模式,则返回数值键值的数组,默认模式是 PDO::FETCH_BOTH
则返回前面两者的集合,既有数值键值的数组,又有关联数组。PDO也可以获取数据返回对象PDO::FETCH_OBJ
,PDO::FETCH_CLASS
,PDO::FETCH_BOUND
,bindColumn
方法等更多内容,请阅读: PDOStatement Fetch documentation。
# 获取数据行数(Getting Row Count)
代替 mysql_num_rows
方法,你可以使用 PDOStatement
对象的rowCount();
方法。
<code>$stmt = $db->query('SELECT * FROM table'); $row_count = $stmt->rowCount(); echo $row_count.' rows selected'; </code>
注意:官方文档称此函数仅适用于返回 `UPDATE`, `INSERT`, `DELETE`操作的`affected rows`,而 `SELECT`操作,仅对于`PDO_MYSQL` 驱动,此函数同样适用(谨记),在操作其他数据库的时候尤其注意。
# 获取最后操作ID(Getting the Last Insert Id)
mysql_*代码:
<code>$result = mysql_query("INSERT INTO table(firstname, lastname) VALUES('John', 'Doe')") or die("Insert Failed ".mysql_error()); $insert_id = mysql_insert_id(); </code>
PDO代码:
<code>$result = $db->exec("INSERT INTO table(firstname, lastname) VAULES('John', 'Doe')"); $insertId = $db->lastInsertId(); </code>
5.执行 INSERT
, UPDATE
, DELETE
操作
mysql_*代码:
<code>$results = mysql_query("UPDATE table SET field='value'") or die(mysql_error()); $affected_rows = mysql_affected_rows($result); echo $affected_rows.' were affected'; </code>
PDO代码:
<code>$affected_rows = $db->exec("UPDATE table SET field='value'"); echo $affected_rows.' were affected' </code>
DELETE
, INSERT
操作同样适用。
6.运行带有查询参数的语句(Running Statements With Parameters)
对于 不携带任何参数的查询语句,我们可以使用 query
方法处理SELECT
操作,使用exec
方法处理 INSERT
,UPDATE
,INSERT
操作,而对于携带查询参数的语句,你应该使用绑定参数的方法来安全的处理这些操作。
mysql_*代码:
<code>$results = mysql_query(sprintf("SELECT * FROM table WHERE id='%s' AND name='%s'", mysql_real_escape_string($id), mysql_real_escape_string($name))) or die(mysql_error()); $rows = array(); while($row = mysql_fetch_assoc($results)){ $rows[] = $row; } </code>
PDO代码:
<code>$stmt = $db->prepare("SELECT * FROM table WHERE id=? AND name=?"); $stmt->execute(array($id, $name)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); </code>
prepare方法将查询语句发送到服务器,以“?”作为参数占位符进行编译,execute方法将查询参数发送到服务器,运行之前编译好的查询语句。因为 查询语句 和 查询参数 是分开发送的,所以在参数里的SQL语句是不可能被执行的,所以不会发生 SQL注入,这是一种比连接字符串构造SQL语句更加安全的解决方法。
注意: 当你使用**绑定参数**的时候,不要对"?"占位符使用引号(SQL语句原来是对参数使用引号的),因为参数类型是在execute方法的时候确定的,所以在prepare的时候不必对占位符使用引号。
还有一些绑定参数的方法,bindValue方法可以分别绑定每个参数来代替execute方法的数组方式,同时还分别设置每个参数的类型。
<code>$stmt = $db->prepare("SELECT * FROM table WHERE id=? AND name=?"); $stmt->bindValue(1, $id, PDO::PARAM_INT); $stmt->bindValue(2, $name, PDO::PARAM_STR); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); </code>
#命名占位符
如果你有许多参数需要绑定,不要使用问号占位符
,以防混淆出错,你可以使用命名占位符
代替问号占位符
。
<code>$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name"); $stmt->bindValue(':id', $id, PDO::PARAM_INT); $stmt->bindValue(':name', $name, PDO::PARAM_STR); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); </code>
你也可以使用execute方法,以数组的方式绑定参数:
<code>$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name"); $stmt->execute(array(':name' => $name, ':id' => $id)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); </code>
#INSERT
, DELETE
, UPDATE
预处理查询
INSERT
, DELETE
, UPDATE
预处理语句的使用和SELECT
类似,我们举几个例子:
<code>$stmt = $db->prepare("INSERT INTO table(field1,field2,field3,field4,field5) VALUES(:field1,:field2,:field3,:field4,:field5)"); $stmt->execute(array(':field1' => $field1, ':field2' => $field2, ':field3' => $field3, ':field4' => $field4, ':field5' => $field5)); $affected_rows = $stmt->rowCount(); </code>
<code>$stmt = $db->prepare("DELETE FROM table WHERE id=:id"); $stmt->bindValue(':id', $id, PDO::PARAM_STR); $stmt->execute(); $affected_rows = $stmt->rowCount(); </code>
<code>$stmt = $db->prepare("UPDATE table SET name=? WHERE id=?"); $stmt->execute(array($name, $id)); $affected_rows = $stmt->rowCount(); </code>
#在预处理中使用SQL函数
无效方法:
<code>//THIS WILL NOT WORK! $time = 'NOW()'; $name = 'BOB'; $stmt = $db->prepare("INSERT INTO table(`time`, `name`) VALUES(?, ?)"); $stmt->execute(array($time, $name)); </code>
正确方法
<code>$name = 'BOB'; $stmt = $db->prepare("INSERT INTO table(`time`, `name`) VALUES(NOW(), ?)"); $stmt->execute(array($name)); </code>
你也可以在SQL函数里绑定参数:
<code>$name = 'BOB'; $password = 'badpass'; $stmt = $db->prepare("INSERT INTO table(`hexvalue`, `password`) VALUES(HEX(?), PASSWORD(?))"); $stmt->execute(array($name, $password)); </code>
但是不能作为LIKE的参数:
<code>//THIS DOES NOT WORK $stmt = $db->prepare("SELECT field FROM table WHERE field LIKE %?%"); $stmt->bindParam(1, $search, PDO::PARAM_STR); $stmt->execute(); </code>
正确使用LIKE并绑定参数的方法:
<code>$stmt = $db->prepare("SELECT field FROM table WHERE field LIKE ?"); $stmt->bindValue(1, "%$search%", PDO::PARAM_STR); $stmt->execute(); </code>
注意:这里使用的是bindValue而不是bindParam,否则会发生PDOException或致命错误。
#使用循环运行预处理语句
预处理语句可以一次设置,多次调用,因为仅在第一次传入的时候编译,因此在后来的多次调用中提高了不少效率。
典型的应用就是bindParam
,bindParam
与bindValue
的不同之处在于,它不是绑定了参数的值,而是绑定参数变量本身,因此,如果参数变量变化了,那么在execute处理的时候,查询也将相应变化。
<code>$values = array('bob', 'alice', 'lisa', 'john'); $name = ''; $stmt = $db->prepare("INSERT INTO table(`name`) VALUES(:name)"); $stmt->bindParam(':name', $name, PDO::PARAM_STR); foreach($values as $name) { $stmt->execute(); } </code>
6.PDO中的事务(Transactions)
注意:调用beginTransaction()
方法即自动关闭了自动提交
。
<code>try { $db->beginTransaction(); $db->exec("SOME QUERY"); $stmt = $db->prepare("SOME OTHER QUERY?"); $stmt->execute(array($value)); $stmt = $db->prepare("YET ANOTHER QUERY??"); $stmt->execute(array($value2, $value3)); $db->commit(); } catch(PDOException $ex) { //Something went wrong rollback! $db->rollBack(); echo $ex->getMessage(); } </code>
原文链接:PDO Tutorial for MySQL Developers
参考链接:PDO Documentation
延伸阅读:Validation and SQL Injection
原文地址:PHP Memcached使用详解, 感谢原作者分享。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

이 튜토리얼은 PHP를 사용하여 XML 문서를 효율적으로 처리하는 방법을 보여줍니다. XML (Extensible Markup Language)은 인간의 가독성과 기계 구문 분석을 위해 설계된 다목적 텍스트 기반 마크 업 언어입니다. 일반적으로 데이터 저장 AN에 사용됩니다

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

정적 바인딩 (정적 : :)는 PHP에서 늦은 정적 바인딩 (LSB)을 구현하여 클래스를 정의하는 대신 정적 컨텍스트에서 호출 클래스를 참조 할 수 있습니다. 1) 구문 분석 프로세스는 런타임에 수행됩니다. 2) 상속 관계에서 통화 클래스를 찾아보십시오. 3) 성능 오버 헤드를 가져올 수 있습니다.

문자열은 문자, 숫자 및 기호를 포함하여 일련의 문자입니다. 이 튜토리얼은 다른 방법을 사용하여 PHP의 주어진 문자열의 모음 수를 계산하는 방법을 배웁니다. 영어의 모음은 A, E, I, O, U이며 대문자 또는 소문자 일 수 있습니다. 모음이란 무엇입니까? 모음은 특정 발음을 나타내는 알파벳 문자입니다. 대문자와 소문자를 포함하여 영어에는 5 개의 모음이 있습니다. a, e, i, o, u 예 1 입력 : String = "Tutorialspoint" 출력 : 6 설명하다 문자열의 "Tutorialspoint"의 모음은 u, o, i, a, o, i입니다. 총 6 개의 위안이 있습니다

PHP의 마법 방법은 무엇입니까? PHP의 마법 방법은 다음과 같습니다. 1. \ _ \ _ Construct, 객체를 초기화하는 데 사용됩니다. 2. \ _ \ _ 파괴, 자원을 정리하는 데 사용됩니다. 3. \ _ \ _ 호출, 존재하지 않는 메소드 호출을 처리하십시오. 4. \ _ \ _ get, 동적 속성 액세스를 구현하십시오. 5. \ _ \ _ Set, 동적 속성 설정을 구현하십시오. 이러한 방법은 특정 상황에서 자동으로 호출되어 코드 유연성과 효율성을 향상시킵니다.

PHP와 Python은 각각 고유 한 장점이 있으며 프로젝트 요구 사항에 따라 선택합니다. 1.PHP는 웹 개발, 특히 웹 사이트의 빠른 개발 및 유지 보수에 적합합니다. 2. Python은 간결한 구문을 가진 데이터 과학, 기계 학습 및 인공 지능에 적합하며 초보자에게 적합합니다.

PHP는 전자 상거래, 컨텐츠 관리 시스템 및 API 개발에 널리 사용됩니다. 1) 전자 상거래 : 쇼핑 카트 기능 및 지불 처리에 사용됩니다. 2) 컨텐츠 관리 시스템 : 동적 컨텐츠 생성 및 사용자 관리에 사용됩니다. 3) API 개발 : 편안한 API 개발 및 API 보안에 사용됩니다. 성능 최적화 및 모범 사례를 통해 PHP 애플리케이션의 효율성과 유지 보수 성이 향상됩니다.

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7
