phpStorm中的CodeIgniter代码自动提示

 首先到GitHub上下载文件

然后按照下面的步骤进行设置:
1.将下载的文件放置项目根目录.
2.在PHPStorm中打开项目,分别找到system/core/Controller.php,system/core/Model.php,system/database/DB_active_rec.php文件,右键,选择Mark as Plain Text.
3.打开my_models.php,按照上面注释中的示例的格式在这段注释代码中继续添加你的model,如你有一个admin_model就在注释中加上一行

PHP代码
  1. * @property admin_model       $admin_model  

然后你在写代码时打完admin_model后其中的方法就会提示并能自动完成。

那些最好的轮子 – PHP篇

 关于不要重复造轮子的二三事一文中,交代了一些背景和想法。本篇则完全是一些干货,列举一些我用过或者即将会用的PHP轮子,基本都符合我对好轮子的定义:开源、许可证宽松、容易集成的PHP项目,目有些已经集成在EvaEngine里面,希望能帮助别人少走弯路。

日志还会陆续补充更新,同时欢迎推荐补充。

 

Databse 数据库ORM

 

Doctrine 2

  • License : MIT
  • Source Code
  • Allo点评:Doctrine是功能最全最完善的PHP orM,社区一直很活跃,对NoSQL也非常迅速的作出了跟进与支持。但之所以没有说Doctrine是最好的,是因为我对PHP究竟有没有必要使用如此庞大的ORM还心存疑虑,平心而论Doctrine的入门门槛实在有些高,尤其是DBAL的提出,更是要把开发者牢牢绑定在Doctrine这艘大船上,用与不用,还是要仔细权衡。

 

RedBeanPHP

  • License : New BSD
  • Source Code
  • Allo点评:相比起Doctrine,RedBean轻巧的简直要飞起来,这两个轮子就是一组最好的比照,是大而全,还是小而精,根据项目选择吧。

 

Documents & Testing 文档与测试

 

phpDocumentor 2

  • License : MIT
  • Source Code
  • Allo点评:老牌php文档生成工具。

 

Faker

  • License : MIT
  • Source Code
  • Allo点评:Faker是一个很神奇的项目,会自动生成拟真的数据,包括用户资料、长文本、IP、日期等等,在网站上线前测试时非常好用。

 

Datetime 时间处理

 

Carbon

  • License : MIT
  • Source Code
  • Allo点评:虽然PHP5内置的Datetime类已经足够应付一般需求,不过Carbon所提供的一些更人性化的处理则更符合实际需求,如果是时间相关的项目应该考虑使用。

 

File System 文件系统

 

Gaufrette

  • License : MIT
  • Source Code
  • Allo点评:文件系统几乎是所有项目都会遇到的问题,Gaufrette为常见的文件系统提供了一套统一接口,包括本地文件/FTP/Dropbox/GridFS/Zip/AmazonS3等等,是大型系统必备的组件。

 

Front-end 前端性能

 

Assetic

  • License : MIT
  • Source Code
  • Allo点评:Assetic可以说生来就是为了多模块的项目而存在的,有了Assetic,可以将分散在各模块中的前端文件编译、合并、压缩。可以让开发人员专注于代码的编写而不是前端文件的生成。

 

lessphp

  • License : MIT
  • Source Code
  • Allo点评:LESS编译器的php版本。不过对于复杂的LESS项目,比如bootstrap,编译的结果与NodeJS原版还是有差异,只能做为Assetic的一个补充。

 

minify

  • License : MIT
  • Source Code
  • Allo点评:PHP版本的CSS/JS压缩器。

 

发布于 分类 网站技术于那些最好的轮子 – PHP篇留下评论

关于不要重复造轮子的二三事

 “不要重复造轮子 Stop Trying to Reinvent the Wheel,可能是每个程序员入行被告知的第一条准则。我自己也会对新人反复灌输这个概念,写程序其实是一个最能“偷懒”的工作:你现在费力实现的每一个功能,可能早已经有极好的解决方法贡献在开源社区,如果可以直接用现成的,那节省下来的时间是不是可以用来偷懒呢?极端的说法,哪怕是那位把所有开发外包给沈阳一家公司的哥们,如果撇开道德以及商业安全,只要能贡献优质的代码和健壮的功能,对于一个项目来说,这样做其实没任何问题。

找轮子存在的问题

虽然不要重复造轮子的准则被反复提到,但是以我个人的经验,这个准则实践起来其实很有难度,因为:

  1. “不要重复造轮子”意味着首先需要找到一个可以用的轮子,而且我们一般希望是能最好的轮子才可以一劳永逸。这就对个人的信息检索能力有非常高的要求。
  2. 找到了一个轮子,但这个轮子好不好用,需要时间来论证。能一眼判断一个项目的质量以及易用性,这其实需要大量项目经验的积累。
  3. 好轮子不是你想用,想用就能用的。要想将一个开源项目整合到自己的项目中,需要对这个项目有比较深的了解。开源项目的文档质量参差不齐,当使用轮子时,只看文档往往是不够的,还需要阅读源代码甚至深度修改定制。更不要说大部分开源项目根本没有中文文档。

所以现实情况往往是:新人不懂得检索方法,找不到轮子;好不容易找到一个轮子,学了半天不会用;好不容易能运行,很多地方与需求不一致,但是又不会改;一来二去,最后还是变成自己写轮子,同时还得出一个结论:别人的轮子都不好用,还是要坚持自己造轮子。

这种情况的最佳体现,就是曾经有一段时间遍地开花的PHP框架。每一个写框架的人都认为自己写的框架才是最好的轮子,甚至是很多PHP新人,对几个成熟框架浅尝辄止后,也纷纷投身写框架的行列。成品大部分看过去却是大同小异,只是语法层面更符合作者本人的习惯,而缺乏大量的测试以及文档社区,最终的结果就是一个半成品然后无疾而终。

这个例子可能有马后炮之嫌,毕竟PHP的造框架运动是由当时的背景和多方面的因素造成的,目前因为有了PHP-FIG制订的规范,PHP的框架的资源已经慢慢集中在Zend FrameworkSymfonyCakePHPYiiCodeIgniter这样少数几个成熟框架之下了。更多的符合PSR规范的模块类库在取代新框架不断涌现,这对整个PHP社区都是好事情。

话题稍微扯的有点远,不过核心的意思还是为了说明,找轮子本身其实是一件不容易的事情。而我对上面问题的解决方法是:找轮子的任务不要交给新人,而是要由经验丰富,信息检索能力强的编程人员负责,最好是项目的构架人员。团队成员找到的轮子最好也由构架人员拍板,用还是不用。对于团队新人,最重要的任务还是编程基本功、文档阅读能力以及如何用好已经拍板的轮子。

怎样才算是好轮子

个人认为好轮子应该具备以下的特征:

  1. 开源,并且License宽松。
  2. 有文档,代码规范,接口友好,最好有实际用例。
  3. 社区相对活跃。
  4. 松耦合,定制容易。

至于同时找到好几个轮子需要选择的情况,可能要根据项目的实际情况进行取舍:有些轮子侧重于大而全,希望解决大部分问题,但是细节上处理不够细致;有些轮子小而精,专注解决一个问题,但是不具备好的通用性。但只要合适好用,都是一个好轮子。

我自己认可的一些好轮子列举在这里:

如何找到好轮子

如何找到好轮子其实在上面问题中已经很清楚了,你应当具备:

  1. 信息检索能力
  2. 外文资料阅读能力
  3. 代码阅读能力以及平时的积累

对于第一条,个人的信息检索能力是无法一蹴而就的,不过如果是还在等待我对此再说出一二三而不是去自己检索寻找方法的朋友,基本上已经没救了。

这里唯一需要说的是,如果想用百度那货去找技术资料的还是省省吧。

外文资料阅读能力也非一日之功,不过个人倒是有个小窍门,如果想要获得一些项目的HelloWorld入门教程或者服务器的配置,可以将检索语言限定为日语,因为日文用户的教程往往秉承了日本细致入微的精神,包括项目背景、需要的环境安装等等一些对初学者才有用的知识,在日文的技术资料中往往也会写的很清楚。

至于平时的积累,可能程序员都知道GithubSourceForgeGoogle Code这些优秀的项目托管网站。但是积累的意思并不是说有时间上去看两眼或者随便收藏一下这么简单。

比如我自己侧重PHP方面的项目,我的一个做法是找到Github下所有Follower大于300的PHP项目(其实一共不到200个其中很多还是php框架),然后一个一个像扫货一样,对其进行了解以及记录。

我的另一个做法是查看知名PHP框架,看看他们用了哪些轮子,比如在Symfony Reference中,你就能淘到Asseticmonolog 这样的好货。

最后一个办法是在Github上Follow一些活跃的作者,比如我的Following中就会显示我的Stars和Forks,里面自然也是我认为值得收藏关注的项目。

PHP NOTICE级错误提示对程序性能影响的研究

我是个有代码洁癖的人,写出来的程序上线后不想见到任何错误 ,而且我也认为错误信息虽然被屏蔽了,但是应该会影响性能的,曾想去验证我这个想法,但还没去验证过,今天正好看到一文章是说这个情况,验证了我的观点,于是摘录如下:

很多人开发php的时候喜欢关掉一部分的错误提示,尤其是Notice级别的提示,这样做可以省去一些严格判断的代码。而平时开发喜欢开着E_ALL级别的我今天在接手同事的项目时,看着满屏幕Notice错误时突然想到了1个问题:

在关掉错误提示时,那么程序代码中大量的notice级别错误是否会造成PHP性能下降,从而使关闭错误输出成为一个掩耳盗铃的做法呢?
下面我来用性能测试来证明这个推论:
测试1:
在关闭错误显示的情况下,测试未初始化变量和已初始化变量在10000000次循环中的性能
变量已初始化的循环代码如下:
PHP代码
  1. $start = getmicrotime();  
  2. error_reporting(E_ALL | E_STRICT);  
  3. ini_set('display_errors', false);  
  4. ini_set('log_errors', false);  
  5. $var=1;  
  6. for ($i=0; $i < 10000000; $i++) {   
  7.     $foo=$var;  
  8. }  
  9. $end = getmicrotime();  
  10. echo $end – $start;  
  11.   
  12. function getmicrotime(){  
  13.     list($usec,$sec)=explode(" ",microtime());  
  14.     return ((float)$usec+(float)$sec);  
  15. }  
变量未初始化的循环代码如下:
PHP代码
  1. $start = getmicrotime();  
  2. error_reporting(E_ALL | E_STRICT);  
  3. ini_set('display_errors', false);  
  4. ini_set('log_errors', false);  
  5.   
  6. for ($i=0; $i < 10000000; $i++) {   
  7.     $foo=$var;  
  8. }  
  9. $end = getmicrotime();  
  10. echo $end – $start;  
  11.   
  12. function getmicrotime(){  
  13.     list($usec,$sec)=explode(" ",microtime());  
  14.     return ((float)$usec+(float)$sec);  
  15. }  
测试成绩:
初始化:平均 5.28 秒
未初始化:平均 17.2 秒
性能差距:3.25倍
 
测试2:
在关闭错误显示的情况下,测试数组索引使用引号和非引号引用在10000000次循环中的性能
数组有引号索引代码如下:
PHP代码
  1. $start = getmicrotime();  
  2. error_reporting(E_ALL | E_STRICT);  
  3. ini_set('display_errors', false);  
  4. ini_set('log_errors', false);  
  5.   
  6. $array=array('foo'=>'baa');  
  7. for ($i=0; $i < 10000000; $i++) {   
  8.     $foo=$array['foo'];  
  9. }  
  10. $end = getmicrotime();  
  11. echo $end – $start;  
  12.   
  13. function getmicrotime(){  
  14.     list($usec,$sec)=explode(" ",microtime());  
  15.     return ((float)$usec+(float)$sec);  
  16. }  
 数组无引号索引代码如下:
PHP代码
  1. $start = getmicrotime();  
  2. error_reporting(E_ALL | E_STRICT);  
  3. ini_set('display_errors', false);  
  4. ini_set('log_errors', false);  
  5.   
  6. $array=array('foo'=>'baa');  
  7. for ($i=0; $i < 10000000; $i++) {   
  8.     $foo=$array[foo];  
  9. }  
  10. $end = getmicrot

无限分类的树状迭代方法

 用RecursiveIteratorIterator类来实现,详见代码:

PHP代码
  1. <?php header('Content-Type: text/html; charset=utf-8');?>  
  2.    
  3. <style>  
  4.    
  5.     ul {list-style-type: circle}  
  6.    
  7. </style>  
  8.    
  9. <?php  
  10. $array = array(   
  11.     "苹果" => array (   
  12.         "一代" => array(   
  13.             "苹果1""苹果1S"   
  14.         ),   
  15.         "二代" => array(   
  16.             "苹果2"array(   
  17.             "苹果2 8G","苹果2 16G"   
  18.         ),   
  19.         ),   
  20.         "三代" => array()   
  21.     ),  
  22.     "三星" => array(   
  23.             "galaxy S4""galaxy S5"   
  24.         ),   
  25. );  
  26.    
  27. class RecursiveListIterator extends RecursiveIteratorIterator {   
  28.    
  29.     public $tab = " ";   
  30.    
  31.     public function beginChildren() {   
  32.         if (count($this->getInnerIterator()) == 0) { return; }   
  33.         echo str_repeat($this->tab, $this->getDepth()), "<ul>
    "
    ;   
  34.     }   
  35.    
  36.     public function endChildren() {   
  37.         if (count($this->getInnerIterator()) == 0) { return; }   
  38.         echo str_repeat($this->tab, $this->getDepth()), "</ul>
    "
    ;   
  39.         echo str_repeat($this->tab, $this->getDepth()), "</li>
    "
    ;   
  40.     }   
  41.    
  42.     public function nextElement() {   
  43.         // 显示叶子节点  
  44.         if ( ! $this->callHasChildren()) {   
  45.             echo str_repeat($this->tab, $this->getDepth()+1), '<li>'$this->current(), "</li>
    "
    ;   
  46.             return;   
  47.         }   
  48.    
  49.         // 显示分支标签   
  50.         echo str_repeat($this->tab, $this->getDepth()+1), '<li>'$this->key();   
  51.         echo (count($this->callGetChildren()) == 0) ? "</li>
    "
     : "
    "
    ;   
  52.     }   
  53. }   
  54.    
  55. $it = new RecursiveListIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST); &

PHP聊天室框架workerman-chat

   workerman-chat是一个以workerman作为服务器容器,使用PHP开发的基于Websocket协议的一个可分布式部署的聊天室框架。

workerman-chat采用gateway workers 进程模型。gateway只负责网络IO,全异步非阻塞,每个gateway进程都可以同时接受上万客户端连接。 workers采用的是PHP开发者所熟悉的同步模型,并提供了开发者基本的接口 onConnect、onMessage、onClose、sendToUid、sendToAll等方法。 开发者只要在onConnect、onMessage、onClose三个方法中添加上自己的业务逻辑即可,开发维护非常简单。

由于采用的是gateway workers 进程模型,gateway和workers之间是无状态的,gateway和workers可以分别部署在不同的物理机上,所以扩容和升级都非常方便。 workerman-chat也非常适合游戏后台开发。

查看php聊天室demo请点击这里

特性

  • 使用PHP开发
  • PHP多进程
  • gateway workers进程模型
  • 支持libevent事件轮询库,支持高并发
  • 默认使用Websocket协议,更小带宽,更好性能
  • 支持分布式部署,可横向扩容
  • 客户端跨浏览器支持(需要浏览器支持html5或者flash)
  • 同样非常适合游戏后台开发

安装启动

1、下载workerman-chat,并解压缩到任意目录

2、启动workerman./bin/workermand start如下图

php聊天室启动示意图

3、浏览器访问端口55151,例如workerman.net:55151如图:

php聊天室使用界面

说明

本聊天室业务逻辑非常简单,业务逻辑都在文件./applications/Chat/Event.php中,开发者可以随意修改,比如增加私聊、表情、分组等功能

解决phpmyadmin查看表结构一直在加载的问题

   今天这两天用电脑上原来安装好的xampp上带的phpMyadmin来管理Mysql数据库,查看表结构时一直显示“正在加载”,从Google上百度后得到了解决方法,见:http://www.fenanr.com/read/112032.html

我主要用到了下面这些:
 
打开 ./libraries/Util.class.php 文件.
查找:
PHP代码
  1. return strftime($date$timestamp);  

替换成如下代码:

PHP代码
  1. if(extension_loaded('gettext'))   
  2.   return strftime($date$timestamp);  

中国区可以替换成以下代码:

PHP代码
  1. if(extension_loaded('gettext')){           
  2. date_default_timezone_set('UTC');   
  3. return gmdate('Y-m-d H:i:s'$timestamp + 28800);}  

作者提到:原理: 本地化时间格式化需要gettext支持, 假如你的环境没有开启此功能, 将会返回乱码, 影响#phpmyadmin ajax的处理. 

我这发现开启了gettext依旧会乱码,所以前部分代码用strftime不起作用,后面这个用gmdate才行。但是没必要判断gettext了吧。

搜索了一圈,没有找到乱码的解决方案,说是strftime对中文的支持不好,放弃了,用其它方法来格式化时间吧,比如date等函数。

xampp套件Apache启动失败解决方案

   刚换了工作,今天第一天报到,熟悉环境,配置开发环境。给我分配的工作电脑上已经安装有XAMPP,发现Apache启动不了,XAMPP控制面板上提示:

XML/HTML代码
  1. 11:27:36  [Apache]  Error: Apache shutdown unexpectedly.  
  2. 11:27:36  [Apache]  This may be due to a blocked port, missing dependencies,   
  3. 11:27:36  [Apache]  improper privileges, a crash, or a shutdown by another method.  
  4. 11:27:36  [Apache]  Press the Logs button to view error logs and check  
  5. 11:27:36  [Apache]  the Windows Event Viewer for more clues  
  6. 11:27:36  [Apache]  If you need more help, copy and post this  
  7. 11:27:36  [Apache]  entire log window on the forums  

  看这提示信息,应该是端口被占用,用DOS命令netstat -ano查了端口,也没发现有被占用的。用命令行模式到D:xamppapachein目录下运行httpd,提示:

XML/HTML代码
  1. AH00526: Syntax error on line 238 of D:/xampp/apache/conf/httpd.conf:  
  2. DocumentRoot must be a directory  

打开配置文件,发现DocumentRoot设置的目录已经不存在了,估计是以前用这台电脑的同事清理了,改为一个存在的目录,再重启Apache,成功了。

常用的PHP类库—PHP开发者必备

PDF 生成器

FPDF – 这量一个可以让你生成PDF的纯PHP类库。

Excel 相关

你的站点需要生成Excel?没有问题,下面这两个类库可以让你轻松做到这一点。

php-excel – 这是一个非常简单的Excel文件生成类。(用PHPExcel读取excel并导入数据库

PHP Excel Reader – 可以解析并读取XLS文件中的数据。

扩展阅读:

php-excel-reader读取excel内容存入数据库

使用php-excel-reader读取excel文件

E-Mail 相关

不喜欢PHP的mail函数?觉得不够强大?下面的PHP邮件相关的库绝对不会让你失望。

Swift Mailer – 免费的超多功能的PHP邮件库。

PHPMailer – 超强大的邮件发送类。(PHPMailer使用教程,使用PHPMailer发送邮件(含附件下载)

单元测试

如果你在使用测试驱动的方法开发你的程序,下面的类库和框架绝你能帮助你的开发。

SimpleTest – 一个PHP的单元测试和网页测试的框架。

PHPUnit – 来自xUnit 家族,提供一个框架可以让你方便地进行单元测试的案例开发。并可非常容易地分析其测试结果。

图表库

下面的类库可以让你很简的创建复杂的图表和图片。当然,它们需要GD库的支持。

pChart – 一个可以创建统计图的库。

Libchart – 这也是一个简单的统计图库。

JpGraph – 一个面向对象的图片创建类。jpGraph的应用及基本安装配置

Open Flash Chart – 这是一个基于Flash的统计图。

RSS 解析

解释RSS并是一件很单调的事情,不过幸好你有下面的类库可以帮助你方便地读取RSS的Feed。

MagpieRSS – 开源的PHP版RSS解析器,据说功能强大,未验证。

SimplePie – 这是一个非常快速,而且易用的RSS和Atom 解析库。

缩略图生成

phpThumb – 功能很强大,如何强大还是自己去体会吧。

支付

你的网站需要处理支付方面的事情?需要一个和支付网关的程序?下面这个程序可以帮到你。

PHP Payment Library – 支持Paypal, Authorize.net 和2Checkout (2CO)

OpenID

PHP-OpenID – 支持OpenID的一个PHP库。OpenID是帮助你使用相同的用户名和口令登录不同的网站的一种解决方案。如果你对OpenID不熟悉的话,你可以到这里看看:http://openid.net.cn/

对象关系映射ORM

ADOdb – 数据库抽象(adodb专题教程

Doctrine – 对象关系映射Object relational mapper (ORM) ,需要 PHP 5.2.3+ 版本,一个非常强大的database abstraction layer (DBAL).

Propel – 对象关系映射框架- PHP5

Outlet – 也是关于对象关系映射的一个工具。

本文转载自:phpddt

PHP中该怎样防止SQL注入?

本文由 伯乐在线 – rokety 翻译自 StackOverflow。欢迎加入技术翻译小组

 如果用户输入的数据在未经处理的情况下插入到一条SQL查询语句,那么应用将很可能遭受到SQL注入攻击,正如下面的例子:

PHP代码
  1. $unsafe_variable = $_POST['user_input'];    
  2. mysql_query("Insert INTO `table` (`column`) VALUES ('" . $unsafe_variable . "')");  
因为用户的输入可能是这样的:
 
value'); Drop TABLE table;–
那么SQL查询将变成如下:
 
Insert INTO `table` (`column`) VALUES('value'); Drop TABLE table;–')
应该采取哪些有效的方法来防止SQL注入?
 
 
最佳回答(来自Theo):
 
使用预处理语句和参数化查询。预处理语句和参数分别发送到数据库服务器进行解析,参数将会被当作普通字符处理。这种方式使得攻击者无法注入恶意的SQL。 你有两种选择来实现该方法:
 
1、使用PDO:
PHP代码
  1. $stmt = $pdo->prepare('Select * FROM employees Where name = :name');   
  2. $stmt->execute(array('name' => $name));     
  3. foreach ($stmt as $row) {  
  4.     // do something with $row  
  5. }

2、使用mysqli:

PHP代码
  1. $stmt = $dbConnection->prepare('Select * FROM employees Where name = ?');  
  2. $stmt->bind_param('s'$name);  
  3. $stmt->execute();  
  4. $result = $stmt->get_result();  
  5. while ($row = $result->fetch_assoc()) {  
  6.     // do something with $row  
  7. }  

注意,在默认情况使用PDO并没有让MySQL数据库执行真正的预处理语句(原因见下文)。为了解决这个问题,你应该禁止PDO模拟预处理语句。一个正确使用PDO创建数据库连接的例子如下:

PHP代码
  1. $dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8''user''pass');  
  2. $dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);  
  3. $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
在上面的例子中,报错模式(ATTR_ERRMODE)并不是必须的,但建议加上它。这样,当发生致命错误(Fatal Error)时,脚本就不会停止运行,而是给了程序员一个捕获PDOExceptions的机会,以便对错误进行妥善处理。 然而,第一个setAttribute()调用是必须的,它禁止PDO模拟预处理语句,而使用真正的预处理语句,即有MySQL执行预处理语句。这能确保语句和参数在发送给MySQL之前没有被PHP处理过,这将使得攻击者无法注入恶意SQL。了解原因,可参考这篇博文:PDO防注入原理分析以及使用PDO的注意事项。 注意在老版本的PHP(<5.3.6),你无法通过在PDO的构造器的DSN上设置字符集,参考:silently ignored the charset parameter。
 
解析
 
当你将SQL语句发送给数据库服务器进行预处理和解析时发生了什么?通过指定占位符(一个?或者一个上面例子中命名的 :name),告诉数据库引擎你想在哪里进行过滤。当你调用execute的时候,预处理语句将会与你指定的参数值结合。 关键点就在这里:参数的值是和经过解析的SQL语句结合到一起,而不是SQL字符串。SQL注入是通过触发脚本在构造SQL语句时包含恶意的字符串。所以,通过将SQL语句和参数分开,你防止了SQL注入的风险。任何你发送的参数的值都将被当作普通字符串,而不会被数据库服务器解析。回到上面的例子,如果$name变量的值为 ’Sarah’; Delete FROM employees ,那么实际的查询将是在 employees 中查找 name 字段值为 ’Sarah’; Delete FROM employees 的记录。 另一个使用预处理语句的好处是:如果你在同一次数据库连接会话中执行同样的语句许多次,它将只被解析一次,这可以提升一点执行速度。 如果你想问插入该如何做,请看下面这个例子(使用PDO):
PHP代码
  1. $preparedStatement = $db->prepare('Insert INTO table (column) VALUES (:column)');  
  2. $preparedStatement->execute(array('column' => $unsafeValue));