十个 PHP 开发者最容易犯的错误 (4)

为了避免出现这种问题,考虑限制一下你查询的数量,使用一个较小的数字来循环,像这样:

$totalNumberToFetch = 10000; $portionSize = 100; for ($i = 0; $i <= ceil($totalNumberToFetch / $portionSize); $i++) { $limitFrom = $portionSize * $i; $res = $connection->query( "SELECT `x`,`y` FROM `test` LIMIT $limitFrom, $portionSize"); }

当我们把这个常见错误和上面的  结合起来考虑的时候, 就会意识到我们的代码理想需要在两者间实现一个平衡。是让查询粒度化和重复化,还是让单个查询巨大化。生活亦是如此,平衡不可或缺;哪一个极端都不好,都可能会导致 PHP 无法正常运行。

常见错误 #6: 忽略 Unicode/UTF-8 的问题

从某种意义上说,这实际上是PHP本身的一个问题,而不是你在调试 PHP 时遇到的问题,但是它从未得到妥善的解决。 PHP 6 的核心就是要做到支持 Unicode。但是随着 PHP 6 在 2010 年的暂停而搁置了。

这并不意味着开发者能够避免 正确处理 UTF-8 并避免做出所有字符串必须是『古老的 ASCII』的假设。 没有正确处理非 ASCII 字符串的代码会因为引入粗糙的 海森堡bug(heisenbugs)  而变得臭名昭著。当一个名字包含 『Schrödinger』的人注册到你的系统时,即使简单的 strlen($_POST['name']) 调用也会出现问题。

下面是一些可以避免出现这种问题的清单:

如果你对 UTF-8 还不了解,那么你至少应该了解下基础的东西。 这儿 有个很好的引子。

确保使用 mb_* 函数代替老旧的字符串处理函数(需要先保证你的 PHP 构建版本开启了『多字节』(multibyte)扩展)。

确保你的数据库和表设置了 Unicode 编码(许多 MySQL 的构建版本仍然默认使用 latin1  )。

记住 json_encode() 会转换非 ASCII 标识(比如: 『Schrödinger』会被转换成 『Schr\u00f6dinger』),但是 serialize() 不会 转换。

确保 PHP 文件也是 UTF-8 编码,以避免在连接硬编码字符串或者配置字符串常量的时候产生冲突。

Francisco Claria  在本博客上发表的 UTF-8 Primer for PHP and MySQL  是份宝贵的资源。

常见错误 #7: 认为 $_POST 总是包含你 POST 的数据

不管它的名称,$_POST 数组不是总是包含你 POST 的数据,他也有可能会是空的。 为了理解这一点,让我们来看一下下面这个例子。假设我们使用 jQuery.ajax() 模拟一个服务请求,如下:

// js $.ajax({ url: 'http://my.site/some/path', method: 'post', data: JSON.stringify({a: 'a', b: 'b'}), contentType: 'application/json' });

(顺带一提,注意这里的 contentType: 'application/json' 。我们用 JSON 类型发送数据,这在接口中非常流行。这在 AngularJS $http service 里是默认的发送数据的类型。)

在我们举例子的服务端,我们简单的打印一下 $_POST 数组:

// php var_dump($_POST);

奇怪的是,结果如下:

array(0) { }

为什么?我们的 JSON 串 {a: 'a', b: 'b'} 究竟发生了什么?

原因在于 当内容类型为 application/x-www-form-urlencoded 或者 multipart/form-data 的时候 PHP 只会自动解析一个 POST 的有效内容。这里面有历史的原因 --- 这两种内容类型是在 PHP 的 $_POST 实现前就已经在使用了的两个重要的类型。所以不管使用其他任何内容类型 (即使是那些现在很流行的,像 application/json), PHP 也不会自动加载到 POST 的有效内容。

既然 $_POST 是一个超级全局变量,如果我们重写 一次 (在我们的脚本里尽可能早的),被修改的值(包括 POST 的有效内容)将可以在我们的代码里被引用。这很重要因为 $_POST 已经被 PHP 框架和几乎所有的自定义的脚本普遍使用来获取和传递请求数据。

所以,举个例子,当处理一个内容类型为 application/json 的 POST 有效内容的时候 ,我们需要手动解析请求内容(decode 出 JSON 数据)并且覆盖 $_POST 变量,如下:

// php $_POST = json_decode(file_get_contents('php://input'), true);

然后当我们打印 $_POST 数组的时候,我们可以看到他正确的包含了 POST 的有效内容;如下:

array(2) { ["a"]=> string(1) "a" ["b"]=> string(1) "b" } 常见错误 #8: 认为 PHP 支持单字符数据类型

阅读下面的代码并思考会输出什么:

for ($c = 'a'; $c <= 'z'; $c++) { echo $c . "\n"; }

如果你的答案是 a 到 z,那么你可能会对这是一个错误答案感到吃惊。

没错,它确实会输出 a 到 z,但是,它还会继续输出 aa 到 yz。我们一起来看一下这是为什么。

PHP 中没有 char 数据类型; 只能用 string 类型。记住一点,在 PHP 中增加 string 类型的 z 得到的是 aa:

php> $c = 'z'; echo ++$c . "\n"; aa

没那么令人混淆的是,aa 的字典顺序是 小于  z 的:

php> var_export((boolean)('aa' < 'z')) . "\n"; true

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwpxfs.html