浅析PHP编程中10个最常见的错误(4)

  没有统一的编码标准会使你的项目出现很多问题。最明显的就是你的项目代码不具有一致性。更坏的地方在于,你的代码将更加难以调试、扩展和维护。这也就意味着你的团队效率会降低,包括做一些很多无意义的劳动。

  对于PHP开发者来说,是比较幸运的。因为有PHP编码标准推荐(PSR),由下面5个部分组成:

PSR-0:自动加载标准
PSR-1:基本编码标准
PSR-2:编码风格指南
PSR-3:日志接口标准
PSR-4:自动加载
  PSR最初由PHP社区的几个大的团体所创建并遵循。Zend, Drupal, Symfony, Joomla及其它的平台都为此标准做过贡献并遵循这个标准。即使是PEAR,早些年也想让自己成为一个标准,但现在也加入了PSR阵营。

  在某些情况下,使用什么编码标准是无关紧要的,只要你使用一种编码风格并一直坚持使用即可。但是遵循PSR标准不失为一个好办法,除非你有什么特殊的原因要 自己弄一套。现在越来越多的项目都开始使用PSR,大部分的PHP开发者也在使用PSR,因此使用PSR会让新加入你团队的成员更快的熟悉项目,写代码时 也会更加舒适。

 错误10:错误使用empty()函数

  一些PHP开发人员喜欢用empty()函数去对变量或表达式做布尔判断,但在某些情况下会让人很困惑。

  首先我们来看看PHP中的数组Array和数组对象ArrayObject。看上去好像没什么区别,都是一样的。真的这样吗?

// PHP 5.0 or later: $array = []; var_dump(empty($array)); // outputs bool(true) $array = new ArrayObject(); var_dump(empty($array)); // outputs bool(false) // why don't these both produce the same output?

  让事情变得更复杂些,看看下面的代码:

// Prior to PHP 5.0: $array = []; var_dump(empty($array)); // outputs bool(false) $array = new ArrayObject(); var_dump(empty($array)); // outputs bool(false)

  很不幸的是,上面这种方法很受欢迎。例如,在Zend Framework 2中,Zend\Db\TableGateway 在 TableGateway::select() 结果集上调用 current() 方法返回数据集时就是这么干的。开发人员很容易就会踩到这个坑。

  为了避免这些问题,检查一个数组是否为空最后的办法是用 count() 函数:

// Note that this work in ALL versions of PHP (both pre and post 5.0): $array = []; var_dump(count($array)); // outputs int(0) $array = new ArrayObject(); var_dump(count($array)); // outputs int(0)

  在这顺便提一下,因为PHP中会将数值0认为是布尔值false,因此 count() 函数可以直接用在 if 条件语句的条件判断中来判断数组是否为空。另外,count() 函数对于数组来说复杂度为O(1),因此用 count() 函数是一个明智的选择。

  再来看一个用 empty() 函数很危险的例子。当在魔术方法 __get() 中结合使用 empty() 函数时,也是很危险的。我们来定义两个类,每个类都有一个 test 属性。

  首先我们定义 Regular 类,有一个 test 属性:

class Regular { public $test = 'value'; }

  然后我们定义 Magic 类,并用 __get() 魔术方法来访问它的 test 属性:

class Magic { private $values = ['test' => 'value']; public function __get($key) { if (isset($this->values[$key])) { return $this->values[$key]; } } }

  好了。我们现在来看看访问各个类的 test 属性会发生什么:

$regular = new Regular(); var_dump($regular->test); // outputs string(4) "value" $magic = new Magic(); var_dump($magic->test); // outputs string(4) "value"

  到目前为止,都还是正常的,没有让我们感到迷糊。

  但在 test 属性上使用 empty() 函数会怎么样呢?

var_dump(empty($regular->test)); // outputs bool(false) var_dump(empty($magic->test)); // outputs bool(true)

  结果是不是很意外?

  很不幸的是,如果一个类使用魔法 __get() 函数来访问类属性的值,没有简单的方法来检查属性值是否为空或是不存在。在类作用域外,你只能检查是否返回 null 值,但这并不一定意味着没有设置相应的键,因为键值可以被设置为 null 。

  相比之下,如果我们访问 Regular 类的一个不存在的属性,则会得到一个类似下面的Notice消息:

Notice: Undefined property: Regular::$nonExistantTest in /path/to/test.php on line 10 Call Stack: 0.0012 234704 1. {main}() /path/to/test.php:0

  因此,对于 empty() 函数,我们要小心的使用,要不然的话就会结果出乎意料,甚至潜在的误导你。

您可能感兴趣的文章:

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

转载注明出处:http://www.heiqu.com/e02079db6d8b753830fbf98ba95b33db.html