Entries tagged as php
WAMP crashes easily those days: Some notes on PHP configuration Mon, Sep 14. 2009
I've upgrade my WAMP(Windows+Apache+MySQL+PHP) to lastest versions, but Apache crashes more often then it used to be due to incorrect configuring PHP.
Now I've finially got a stably working development environment. And here is some notes:
go-pear.batdose not work.When initializing as usual using
go-pear.batcommand, I got an error message:- phar "E:\HTTPD\php-5.3.0-Win32-VC9-x86\PEAR\go-pear.phar" does not have a signature
- PHP Warning: require_once(phar://go-pear.phar/index.php): failed to open stream: phar error: invalid url or non-existent phar "phar://go-pear.phar/index.php" in E:\HTTPD\php-5.3.0-Win32-VC9-x86\PEAR\go-pear.phar on line 1236
So,
go-pear.bardid not work for me, but:is all right.- php -dphar.require_hash=0 PEAR\go-pear.phar
Xdebugmakes Apache crashes everytime.As I said, I've upgraded all components to it's lastest version: Apache, version 2.2.13 form offical site, PHP, version VC9 x86 Thread Safe, MySQL, version 5.1.38-community.
Following Xdebug manual, I have to download the one matches the PHP version I'm using. So, I downloaded Xdebug 2.0.5 5.3 VC9 (32 bit), made modification to php.ini to enable Xdebug, and restart Apache.
From now on, Apache crashed everytime I call
phpinof()function. I've tried some solution from Google ,but none of them works. Though, one page remains me of the version of PHP. And I found this on PHP for Windows download page:
Change my PHP from VC6 to VC9, re-configure all settings and download Xdebug 2.0.5 5.3 VC96(32 bit), it works!Which version do I choose?
If you are using PHP with Apache 1 or Apache2 from apache.org you need to use the VC6 versions of PHP
If you are using PHP with IIS you should use the VC9 versions of PHP
Can't make new folder when installing PEAR.
After solve problems above, I came to a new one, When installing PEAR, ater set the dirs, PHP began to download and install PEAR components, installation programe breaks and shows:
- Unable to create Temporary directory for processing E:\HTTPD\php\PEAR\tmp.
- Run this script as administrator or pick another location.
I'm sure nothing is wrong about dir premission. Solved this problem, I'm also sure that few people may face this, because it is due to the immature hardlink mechanism on Windows Server 2008.
I made hardlink named php to folder php-5.3.0-Win32-VC6-x86 and I was running the programe in php folder. After I change my current folder to php-5.3.0-Win32-VC6-x86, it goes well.
Conclusion: harklink on Windows is still a load of crap.
Installing PHP w/ IMAP support on Slackware Thu, Jul 2. 2009
When installing PostfixAdmin, I found that I need to re-compile PHP to support IMAP, but later more problems came to me.
Environment: Linux mail 2.6.27.7-smp #2 SMP Thu Nov 20 22:32:43 CST 2008 i686 Intel(R) Xeon(R) CPU E5405 @ 2.00GHz GenuineIntel GNU/Linux
Q: PHP configure utility reports that there is no IMAP support on my system.
A: According to PHP Manual: IMAP Installation, I need to get something named c-client, and compile PHP with --with-imap[=DIR].
Q: Where to get c-client?
A: Googled answer IMAP Information Center: The software and documentation is available at ftp://ftp.cac.washington.edu/imap. UW IMAP toolkit source distribution is available at ftp://ftp.cac.washington.edu/mail/imap.tar.Z.
Q: So strange a package, how to make and install?
A: Normally, you should run configure, make and make install to install a package from source, but no configure found and make is different.
First, make sure you have OpenSSL installed, and then follow the setps:
Extract the archive downloaded to /usr/local folder named imap-2007e
- cd /usr/local/imap-2007e
- # slx means Linux using -lcrypt to get the crypt() function
- make slx
- # BTW: you are supposed to fail this step, see notes below
- mkdir include
- mkdir lib
- cd c-client
- cp *.h ../include/
- cp *.c ../lib/
- ln -s ../c-client/c-client.a ../lib/libc-client.a
NOTE:
If you like me discover that "make slx" fails, but you're damn sure you've openssl installed then, it might be that the lib and include paths on your distribution are different then the defaults provided in the imap-2007e (or imap-XXXXx). To modify go to dir src/osdep/unix and edit Makefile, around L55:
# Extended flags needed for SSL. You may need to modify. SSLDIR=/usr/local/ssl SSLCERTS=$(SSLDIR)/certs SSLKEYS=$(SSLCERTS) SSLINCLUDE=$(SSLDIR)/include SSLLIB=$(SSLDIR)/lib SSLCRYPTO=-lcryptoChange SSLDIR, SSLINCLUDE and SSLIB to valid paths for Slackware. In my case, it should like this:
# Extended flags needed for SSL. You may need to modify. SSLDIR=/etc/ssl SSLCERTS=$(SSLDIR)/certs SSLKEYS=$(SSLCERTS) SSLINCLUDE=/usr/include/openssl SSLLIB=/usr/lib SSLCRYPTO=-lcryptoYou should also check your ld.so.conf for valid paths.
Q: How to compile PHP w/ IMAP support?
A: Finally, we've reached the last step. Re-compile PHP and everything is done. When configuring, just add those two imap options
- ./configure ... --with-imap=/usr/local/imap-2007e --with-imap-ssl
- make
- make install
Bing! Your system is ready for your imap application.
解决 propel-convert-xml-schema 把 null 默认值处理为字符串的问题 Thu, Aug 21. 2008
通过 propel-convert-xml-schema 把 xml schema 转化成 PHP 代码的时候,如果一个字符型字段不能为空且没有明确输入默认值,例如:
- <column name="username" type="VARCHAR" size="128" required="true" default=""/>
生成的 PHP 代码中该字段的默认值是 'null' 而不是 null,导致页面输入框的默认值不是空值,而是一个字符串的 null,很恼火。因为要么在页面中每个字段都对 'null' 做特殊处理,要么修改生成的 PHP 类文件,但是一旦重新执行 propel-convert-xml-schema 就会重新覆盖。
解决办法:修改 propel-generator/classes/propel/phing/PropelCreoleTransformTask.php 文件(对于 Symfony 来说,就是 symfony/vendor/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php)。应用如下 patch:
- 507,510c507
- < //$node->setAttribute("default", iconv($this->dbEncoding, 'utf-8', $defValue));
- < if(!empty($defValue)) {
- < $node->setAttribute("default", iconv($this->dbEncoding, 'utf-8', $defValue));
- < }
- ---
- > $node->setAttribute("default", iconv($this->dbEncoding, 'utf-8', $defValue));
参见:#2045 (propel-convert-xml-schema generate null text as default values) - symfony - Trac。
MySQL 中用 GKB 来让 UTF-8 字段中的中文按照拼音排序 Sat, Aug 16. 2008
UTF-8 中的中文不是按照拼音排序的,因此对于 使用 UTF-8 编码集的字段就无法按照拼音进行排序,最简单的解决方法就是转成 GBK 编码。
实例代码:
- SELECT *
- FROM `test`
- ORDER BY CONVERT( `test`.`name`
- USING GBK )
- LIMIT 0 , 30
数据库表结构:
- CREATE TABLE IF NOT EXISTS `test` (
- `id` int(3) NOT NULL AUTO_INCREMENT,
- `name` varchar(10) COLLATE utf8_bin NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
测试环境:Windows 2003 Standard Edition,MySQL 5.1.22-rc-community。
对于偶正在使用的 Symfony 框架,因为使用了 propel 做 ORM,比较难直接操作SQL,除非使用 RAW SQL,而且使用 RAW SQL会导致很多高级特性无法使用,解决方式:
- $criteria->addAscendingOrderByColumn('CONVERT(' . TestPeer::NAME . ' USING GBK)');
PHP 基准测试 Thu, Jun 5. 2008
原文:The PHP Benchmark | Web Resources | WebAppers。
创建 PHPBench 的目的是让你看到每一个 PHP 代码段的运行速度不都是一样的。看到 PHPBench 生成的结果,你很可能会大吃一惊。这个网站还有一个目的就是让你自己去发现一些规律,然后在你自己的服务器环境里,使用示例代码重新运行这些测试来验证你的发现。而且你还可以看到一些 PHPBench 测到的有趣的结论:
- 很奇怪的结果表明,如果你执行sizeof(),那么是否预先计算循环的次数基本上没有什么区别。
- 事实上,each 和 print 执行的功能完全一样,因此都适用于同样的代码段。有一小点需要注意的就是,当你使用逗号分隔输出列表并且使用 echo 输出,则会运行的稍微快一丁点。
- while 循环在 90% 的情况下确实能够快一点点。
需求: -
演示: http://www.phpbench.com/
协议: 自由协议
10 件(也许)你不了解 PHP 的事情 Mon, Feb 25. 2008
来源:10 things you (probably) didn’t know about PHP
PHP 是我用过的语言中,最令人恼火的但同时也是最有趣的语言。我之所以说“令人恼火”主要是因为函数命名极其不一致。尽管我每天都要用到这些函数,我还是要想一下“究竟是 str_pos 还是 strpos?是 str_split 还是 strsplit?”。另一方面,有时候可以用一行简单的代码就能解决一个难题。
下面是一些很酷的特性,很可能你也没有注意到:
- 使用 ip2long() 和 long2ip() 函数来把 IP 地址转化成整型存储到数据库里。这种方法把存储空间降到了接近四分之一(char(15) 的 15 个字节对整形的 4 个字节),计算一个特定的地址是不是在一个区段内页更简单了,而且加快了搜索和排序的速度(虽然有时仅仅是快了一点)。
- 在验证 email 地址的时候使用 checkdnsrr() 函数验证域名是否存在。这个内置函数能够确认指定的域名能够解析成 IP 地址。该函数的PHP 文档的用户评论部分有一个简单的用户自定义函数,这个函数基于 checkdnsrr(),用来验证 email 地址的合法性。对于那些认为自己的 email 地址是 “joeuser@wwwphp.net” 而不是 “joeuser@php.net” 的家伙们,这个方法可以很方便的抓住他们。
- 如果你使用的是 PHP 5 和 MySQL 4.1 或者更高的版本,考虑抛弃 mysql_* 系列函数改用改进版的 mysqli_* 系列函数。一个很好的功能就是你可以使用预处理语句,如果你在维护一个数据库密集型站点,这个功能能够加快查询速度。一些评估分数。
- 学会爱上三元运算符。
- 如果你在项目中感觉到有可复用的部分,在你写下一行代码前先看看 PEAR 中是否已经有了。很多 PHP 程序员都知道 PEAR 是一个很好的资源库,虽然还有很多程序员不知道。这个在线资源库包含了超过 400 个可以复用的程序片段,这些程序片段你可以立即用刀你的程序里。除非说你的项目真的是非常特别的,你总能找到帮你节省时间的 PEAR 包。(参见 PECL)
- 用 highlight_file() 来自动的打印出格式化的很漂亮的源代码。如果你在留言板、IRC 这些地方寻求一个脚本的帮助的话,这个函数用起来非常的顺手。当然了,要小心不要意外的泄露出你的数据库连接信息和密码等。
- 使用 error_reporting(0) 函数来防止用户看到潜在的敏感错误信息。在理想情况下,发布服务器应该在 php.ini 里完全禁止。但是如果你用的是一个共享的 web 服务器的话,你没有自己的 php.ini 文件,那么这种情况下你最好的选择就是在所有脚本的第一行前加上 error_reporting(0);(或者使用 require_once() 方法)。这就能够在出错的时候完全屏蔽敏感的 SQL 查询语句和路径名。
- 在网数据库中存储很大的字符串之前使用 gzcompress() 和 gzuncompress() 来显式的压缩/解压字符串。这个 PHP 内置函数使用 gzip 算法,可以压缩普通文本达 90%。在我每次要读写 BLOB 类型的字段的时候都使用这些函数。唯一额例外就是当我需要全文检索的时候。
- 通过“引用”传递参数的方法从一个函数中得到多个返回值。就像三元运算符一样,大部分受过正式编程训练的程序员都知道这个技巧。但是那些 HTML 背景大于 Pascal 背景的程序员都或多或少的有过这样的疑问“在仅能使用一次 return 的情况下,从一个函数里返回多个值?”答案就是在变量前加上一个 “&” 符号,通过“引用”传递而非“值”传递。
- 完全理解“魔术引号”和 SQL 注入的危险性。我希望阅读到这里的开发者都已经很对 SQL 注入和了解了。不过我还是把这条列在这里,是因为这个确实有点难以理解。如果你还没有听说过这种说法,那么把今天剩下的时间都用来 Google、阅读吧。
在 Linux 下用 PEAR 安装 Symfony 出现错误的解决方案 Wed, Jan 23. 2008
开发环境:
- Slackware Linux 12.0
- Apache httpd-2.2.6
- PHP 5.2.5
- PEAR 1.6.2
根据官方文档,用 PEAR 安装 Symfony的命令如下:
- pear channel-discover pear.symfony-project.com
- pear install symfony/symfony
但是运行 channel-discover 的时候报错:Discovery of channel "pear.symfony-project.com" failed。
原因:PEAR 本身的 bug,不支持 channel 的 url 中包含 - 字符。
解决方法:用命令 pear upgrade -f PEAR-1.4.6 把 PEAR 降级到 1.4.6 版,然后正常安装,再用命令 pear upgrade-all 升级 PEAR。
或者应用 PEAR 的 Bug #6960 补丁修补这个 Bug。此方法见参考链接 2。
参考链接:
神奇的土地上发生的神奇的错误 Thu, Dec 27. 2007
梨花体小诗一首做题记:
毫无疑问
我犯的错误
是全天下
最神奇的
在 long long ago 的某一天,偶的 Windows 2003 + Apache 2.2 + PHP 5 + MySQL 5.1 突然访问所有的页面都非常慢,打开一个页面,甚至是什么都不做的页面,都要等上好几秒钟,一个简单的 phpinfo(); 居然花了 8s。
偶的 WAMP 环境是多少年一直免安装升级上来的,这些古董配置都是偶千调万改才定下来的最优化的配置。但是就是找不到错误原因。
今天 reinstall Windows 2003,趁机全新的安装了一下 AMP 环境,发现默认配置下,PHP 页面速度非常正常,但是把 php.ini 文件修改成我要的,就立马恢复超级慢的状态。预示 diff 出所作的修改,逐条测试,直到最后发现,只要 extentions 加载 php_mysql.dll 或者 php_mysqli.dll,就会变慢,多次测试的结果都证明了这个结论。
在 Google 上使劲找和 php、mysql、slow 相关的页面,都没有任何相关的问题,难道今天偶 RP 大爆发碰到了千年不遇的超级难题?
搜索这个关键字无果,不过发现最新的 Apache 2.2 的 conf 文件结构发生了变化,于是顺便看看相关的文档,决定把自己用了 n 年的 PHP4/PHP5 共存的虚拟主机配置文件重新修正一下。偶以前都是图省事,用的是 CGI 方式驱动 PHP,关键配置如下:
- ScriptAlias /php5/ "e:/httpd/php5/"
- AddType application/x-httpd-php .php
- Action application/x-httpd-php "/php5/php-cgi.exe"
这个方法以前用的好好的,从 PHP4 就这样写,一直用到现在,虽然说效率低一点,不过开发的时候不在乎,能用就行了。最新的 Apache 2.2 里面推荐用的是 Module 方法,照猫画虎修改如下:
- LoadModule php5_module e:/HTTPD/php5/php5apache2_2.dll
- AddType application/x-httpd-php .php
- PHPIniDir "e:/HTTPD/php5"
好像很早就有这种加载的方法,汗,偶一直到现在才开始使用。当把 PHP 由 CGI 变成 Module 方式加载后,居然页面速度神奇的正常了。即使加载了 php_mysql.dll 也没有任何问题。真抓狂,实在想不出来这两个有什么关系,但是事实却是就是正确了。
同时发现最新的 Apache 的 conf 文件由以前的一个 httpd.conf 变成了以现在一个 httpd.conf 和 extra/httpd-*.conf 结合,结构更加清晰了,不错。赞 Apache 一个。
PHP Security / Sessions / Session Fixation Sun, Jul 1. 2007
Session Fixation
会话固定攻击
Session security is a sophisticated topic, and it's no surprise that sessions are a frequent target of attack. Most session attacks involve impersonation, where the attacker attempts to gain access to another user's session.
会话安全是一个老生常谈的话题了,会话作为一个常见的攻击目标一点也不稀奇。 绝大多数的会话攻击都用的是会话伪装,攻击者要试图用这种方法访问另外一个用户的会话。
The most crucial piece of information for an attacker is the session identifier, because this is required for any impersonation attack. There are three common methods used to obtain a valid session identifier:
对于攻击者来说,最重要的信息就是会话 ID,因为这对任何伪装攻击都是非常重要的。 要想得到一个合法的会话 ID,有三种常见的办法:
- Prediction
- Capture
- Fixation
- 预测
- 捕获
- 固定
Prediction refers to guessing a valid session identifier. With PHP's native session mechanism, the session identifier is extremely random, and this is unlikely to be the weakest point in your implementation.
预测就是猜想一个合法会话 ID。根据 PHP 原生的会话机制,会话 ID 非常的随机, 所以不太可能是你程序的最薄弱的环节。
Capturing a valid session identifier is the most common type of session attack, and there are numerous approaches. Because session identifiers are typically propagated in cookies or as GET variables, the different approaches focus on attacking these methods of transfer. While there have been a few browser vulnerabilities regarding cookies, these have mostly been Internet Explorer, and cookies are slightly less exposed than GET variables. Thus, for those users who enable cookies, you can provide them with a more secure mechanism.
捕获一个合法的会话 ID 是会话攻击中最常用的方法,而且有很多不同的方式。 因为会话 ID 通常都是通过 cookie 或者 GET 变量传递, 所以各种攻击方法的区别之处就在于攻击哪种传输 ID 的方法。 虽然有几个关于处理 cookie 的浏览器漏洞,IE 的漏洞最多, 而且比起 GET 变量来,cookie 不太可能被暴露。 所以,对于那些启用了 cookie 的用户,你可以给他们提供更安全的会话机制。
Fixation is the simplest method of obtaining a valid session identifier. While it's
not very difficult to defend against, if your session mechanism consists of nothing
more than session_start(), you are vulnerable.
会话固定是得到一个合法的会话 ID 的最简单的方法。
虽然防御这种攻击不是很难,但是如果你的会话机制只使用了 session_start() 的话,
你的系统非常容易受到攻击。
In order to demonstrate session fixation, I will use the following script,
session.php:
我用下面这个 session.php 脚本来示范一下会话固定:
- <?php
- {
- $_SESSION['visits'] = 1;
- }
- else
- {
- $_SESSION['visits']++;
- }
- echo $_SESSION['visits'];
- ?>
Upon first visiting the page, you should see 1 output to the screen. On each
subsequent visit, this should increment to reflect how many times you have
visited the page.
在你第一次访问这个页面的时候,你应该能够看到屏幕上输出的 1。
接下来的每一次访问,这个输出结果应该每次加一,以反映你访问了这个页面多少次。
To demonstrate session fixation, first make sure that you do not have an existing
session identifier (perhaps delete your cookies), then visit this page with
?PHPSESSID=1234 appended to the URL. Next, with a completely different
browser (or even a completely different computer), visit the same URL again with
?PHPSESSID=1234 appended. You will notice that you do not see 1 output on
your first visit, but rather it continues the session you previously initiated.
为了演示会话固定攻击,首先要确保你现在没有任何已存在的会话 ID(可以试着删除 cookie),
然后访问这个页面,访问的时候在 URL 后面附加上 ?PHPSESSID=1234。
然后,用一个完全不同的浏览器(最好换一台计算机),同样在 URL 后面附加上 ?PHPSESSID=1234
再次访问这个页面。你会发现你在首次访问的时候看见的输出不是 1,
而是继续刚才初始化的那个会话。
Why can this be problematic? Most session fixation attacks simply use a link or a protocol-level redirect to send a user to a remote site with a session identifier appended to the URL. The user likely won't notice, since the site will behave exactly the same. Because the attacker chose the session identifier, it is already known, and this can be used to launch impersonation attacks such as session hijacking.
为什么会话固定会成问题?大多数会话固定攻击者都是简单的使用一个链接, 或者一个协议层的重定向来给远程站点发送用户信息,也是通过在 URL 后面附加会话 ID 的方法。 因为这个站点的行为完全的一样,所以用户不太可能注意到。 又因为会话 ID 是攻击者选定的,这是已知的,所以这可以用来发动更加类似会话劫持这样的攻击。
A simplistic attack such as this is quite easy to prevent. If there isn't an active session associated with a session identifier that the user is presenting, then regenerate it just to be sure:
我们可以很容易的防范这种非常简单的攻击。如果用户提供了一个会话 ID, 但是没有任何活动的会话与之相关联,那么就重新声称一个 ID 以确保保险。
- <?php
- {
- $_SESSION['initiated'] = true;
- }
- ?>
The problem with such a simplistic defense is that an attacker can simply initialize a session for a particular session identifier, and then use that identifier to launch the attack.
这种简单的防御有一个问题,就是攻击者很容易就能初始化一个有着特定 ID 的会话, 然后用这个 ID 来发动攻击。
To protect against this type of attack, first consider that session hijacking is only really useful after the user has logged in or otherwise obtained a heightened level of privilege. So, if we modify the approach to regenerate the session identifier whenever there is any change in privilege level (for example, after verifying a username and password), we will have practically eliminated the risk of a successful session fixation attack.
要防御这种类型的攻击首先要考虑的是会话劫持只有在用户登录了,或者得到了更高权限后才能发挥作用。 所以,如果我们在权限状态发生任何变化(例如,确认和用户名和密码)后都重新生成会话 ID, 这样就能够消除因为成功的会话固定攻击所带来的风险。
PHP Security / Databases and SQL / SQL Injection Tue, Jun 19. 2007
SQL Injection
SQL 注入
SQL injection attacks are extremely simple to defend against, but many applications are still vulnerable. Consider the following SQL statement:
SQL 注入攻击很容易就能防范,但是很多程序在这方面还是很脆弱的。 看下面的 SQL 语句:
- <?php
- $sql = "INSERT
- INTO users (reg_username,
- reg_password,
- reg_email)
- VALUES ('{$_POST['reg_username']}',
- '$reg_password',
- '{$_POST['reg_email']}')";
- ?>
This query is constructed with $_POST, which should immediately look
suspicious.
这个查询使用 $_POST 进行构造,这样一眼就能够看出问题。
Assume that this query is creating a new account. The user provides a desired username and an email address. The registration application generates a temporary password and emails it to the user to verify the email address. Imagine that the user enters the following as a username:
假设这个查询时用来创建新帐号用的。用户指定他们想要用户名和 email 地址。 然后注册程序生成一个临时密码并且发送给用户以验证 email 地址。 假设用户输入了一个这样的用户名;
bad_guy', 'mypass', ''), ('good_guy
This certainly doesn't look like a valid username, but with no data filtering in
place, the application can't tell. If a valid email address is given
(shiflett@php.net, for example), and 1234 is what the application generates
for the password, the SQL statement becomes the following:
这个用户名看起来肯定不是一个合法的用户名,但是如果没有适当的数据过滤,
程序是区分不出来的。如果给定了一个合法的 email 地址(例如 shiflett@php.net),
程序生成的密码是 1234,那么这个 SQL 语句就变成下面这个样子:
- <?php
- $sql = "INSERT
- INTO users (reg_username,
- reg_password,
- reg_email)
- VALUES (' bad_guy', 'mypass', ''),
- ('good_guy',
- '1234',
- 'shiflett@php.net')";
- ?>
Rather than the intended action of creating a single account (good_guy) with a
valid email address, the application has been tricked into creating two accounts,
and the user supplied every detail of the bad_guy account.
本来预期的动作是创建一个有合法 email 地址的单一帐号(good_guy),
但是程序实际上被欺骗而创建了两个帐号,而且用户还指定了 bad_guy 帐号的所有信息。
While this particular example might not seem so harmful, it should be clear that worse things could happen once an attacker can make modifications to your SQL statements.
虽然这个特定的例子看起来没有那么大的危害,但是这说明了一旦攻击者能够修改你的 SQL 语句, 不定发生什么糟糕的事情呢。
For example, on the database you are using, it might be possible to send multiple queries to the database server in a single call. Thus, a user can potentially terminate the existing query with a semicolon and follow this with a query of the user's choosing.
例如,根据你用的数据库,很可能允许在一次调用中发送多个查询请求。 这样,用户就可能能够用一个分号终止当前的查询,然后紧跟着加入用户所选择的查询。
MySQL, until recently, does not allow multiple queries, so this particular risk is
mitigated. Newer versions of MySQL allow multiple queries, but the
corresponding PHP extension (ext/mysqli) requires that you use a separate
function if you want to send multiple queries (mysqli_multi_query() instead
of mysqli_query()). Only allowing a single query is safer, because it limits
what an attacker can potentially do.
到目前为止,MySQL 还不允许多重查询,所以这个特定的风险倒是不大。
MySQL 的新版支持多重查询,不过对应的 PHP 扩展(ext/mysqli)
要求你在希望进行多重查询的时候使用单独的函数(用 mysqli_multi_query() 替代 mysqli_query())。
因为单一查询能够限制攻击者可能做的事情,所以使用单一查询更加安全。
Protecting against SQL injection is easy:
防范 SQL 注入还是很简单的:
-
Filter your data.
This cannot be overstressed. With good data filtering in place, most security concerns are mitigated, and some are practically eliminated.
-
过滤数据。
这是绝对不能被越过的。如果在适当的地方有很好的数据过滤, 大多数安全隐患都能够减轻,甚至差不多都能够消除。
-
Quote your data.
If your database allows it (MySQL does), put single quotes around all values in your SQL statements, regardless of the data type.
-
给数据加引号。
如果你的数据库支持,在 SQL 语句里给所有的值都加上单引号,不管是什么类型的数据。
-
Escape your data.
Sometimes valid data can unintentionally interfere with the format of the SQL statement itself. Use
mysql_escape_string()or an escaping function native to your particular database. If there isn't a specific one,addslashes()is a good last resort. -
数据转义。
有一些数据,虽然是合法的,但是可能会在无意中和 SQL 语句的格式产生冲突。 那么就使用
mysql_escape_string()函数,或者你的数据库原生的转义函数进行数据转义。 如果没有特定的转义函数,addslashes()是最后手段。

