PHP 到底该怎么定义全局函数

看到很多的各种编程规范都要求,定义函数要先 function_exists 判断一下再定义,我觉得是很不合理的。这样写给我一种感觉,婊子立牌坊,还不知道嫖客到底光顾了没有

我拒绝的理由如下:

  • 增加了排错难度,假设之前有了同名函数,只会调用先定义的。自己后定义的函数没有被光顾,你要找到错误需要看调用栈,到底光顾了哪一个。假设没有这么判断一下,IDE在写的时候就会立刻提示错误,运行时也会出来会立马爆出函数重复定义的致命错误。
  • 如果所有的package定义的全局函数都这么先判断一下。如果发生了同名,这是很恐怖的事情,只有一个package能正常工作,其他都不能正常工作。

大家这么追捧这样定义函数,大部分原因应该是受到了laravel的影响。在我理解laravel这么写,是因为它站在一个框架的角度,一个调用链的末端,宁愿自身牺牲一些辅助函数,也要让别的包能好好运行,从而整个框架能正常的开箱。

但是我们使用框架再来开发就没必要这么写了,因为我们站在调用链的末端,定义的函数是一定要用到的,是一定不能向其他package妥协的,不然真是那句话 婊子立牌坊,还不知道嫖客到底光顾了没有

想要定义规范,我有一点建议。在编写给别人使用的package,应该给辅助函数加上命名空间。这样一来,所有冲突都没有了。像是laravel框架也不用来迁就你的包,而自损自己的函数,还写那么多if降低一点性能。

所以最后的结论就是不要在定义函数的时候多一层判断了!


2017-03-17 14:34:47 update
发现一种情况要需要使用 function_exists 比如password系列函数php5.5.0以上才支持。假如在低版本想使用password系列函数,就只能自己实现了,所以要用 function_exists 判断一下,用来兼容更多php版本。除了这个情况,还是不应该多一层判断,以至于现在都是滥用的感觉。

讨论数量: 12

部分自定义函数只是因为暂时没有内置的,所以自己写一个,比如很久之前的jsonencode,这样等它内置了几乎可以无缝过渡。laravel也定义了很多array*的函数,指不定哪天php就内置了,到时候冲突就大了。

愚以为还是加判断的好,此乃开源界基本的礼貌。
不过言虽如此,屌似卿者,不加也罢,谁敢BB!

7年前 评论

@genyii 原来是为了防止新增内置函数,受教了。但是他是怎么能料定自己实现的功能和以后php内置的无差别。。。 不然后续的坑 岂不是更大。。。

7年前 评论
leo

@Boomdawn 我觉得这个理由说不过去,未来新增函数的参数、返回值都有可能和Laravel定义的不一样,即使加了判断还是可能导致错误。

7年前 评论

@Boomdawn 不敢料定。但加了if至少相当于客气了一下。这已经不是代码层面的问题了,而是我等所不理解的精神追求

7年前 评论

@leo 同意,新增内置函数不一定自己定义的一样。
尽量不要定义全局函数,定义类静态方法。

7年前 评论

@MrJing 理想状态我觉得是这样的

file1.php:
<?php
namespace foo;

function bar()
{
    echo 'from bar';
}
?>

file2.php:
<?php
foo\bar(); // output: from bar
?>
7年前 评论

@genyii 互相客气的后果挺严重的,都互相谦让的话,最后能用上的只有一个,结果就是程序不能正确运行。

7年前 评论

@Boomdawn 嗯嗯,也是好办法,用命名空间

7年前 评论

当年我就是因为 Laravel 的全局函数而拒绝使用。后来想想,不倔了,学学它吧。虽然 Laravel 的是辅助函数,没有真正的逻辑,但冲突了还是用不了。框架自身也依赖了这些函数,也就是说这些函数一定要正常工作,不然你就不要用 Laravel 了。

7年前 评论

命名空间看起来屌

7年前 评论

function_exists 是防止二次加载

7年前 评论

@reatang 在这个自动载入的时代,二次加载貌似不太可能了。再不济也有 require_once

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!