前几日有同事询问我Yii2中是否有封装递归创建目录的方法,我告知了他CFileHelper的用法,对这个事情我从未有过怀疑,任何成熟的框架必然会封装各种文件操作的方法,但过后我寻思良久,mkdir明明有$recursive参数,为何所有的框架都要封装创建文件的方法呢?
用过PHP4的人可能还记得,PHP4中的mkdir定义是这样的:
1 | bool mkdir ( string $pathname [,int $mode = 0777 ] ) |
而PHP5中的定义如下:
1 | bool mkdir ( string $pathname [,int $mode = 0777 [, bool$recursive = false [, resource$context ]]] ) |
这两个参数最早出现在2003年的php源码中,并在php5.0.0中发布,但是一直到PHP4的最后一个版本4.4.9这两个参数也没有被添加。
那么我们有了第一个答案,使用FileHelper是有兼容性方面考虑的,如果你的程序有可能在低版本的PHP中运行,需要使用外部的文件创建方法。
那么下一个问题,众所周知,Yii对PHP的版本要求是5.1.0,Yii2的版本要求是5.4.0,大多新版框架和系统都已经放弃了对PHP4的支持,那么在高版本PHP上运行的为什么要用FileHelper?
第二个答案是这样的,如果你仅仅是用来创建文件夹,那么mkdir的确更方便,但是mkdir有着几个猪一样的队友,比如rmdir和copy,他们都不支持递归,所以FileHelper更方便,他提供了内置函数外的各种强大功能,还能兼顾兼容性。
Yii2\helpers\CFileHelper 定义如下:
1 | public static function normalizePath($path, $ds = DIRECTORY_SEPARATOR) |
什么?没看出来强大?好,请看copyDirectory方法关于$option参数的说明:
1 | * @param array $options options for directory copy. Valid options are: |
@bobhero 通过另一角度分析了这个事情,他认为mkdir的这些队友如此设计是有原因的,但最终我没有找到答案。因为Python3关于文件操作的方法是这样的:
1 | os.mkdir(path, mode=0o777, *, dir_fd=None) |
而Ruby2.2.2的文件操作是这样的:
1 | Dir.mkdir(string [, integer]) |
出于什么样的考虑每个语言对此设计有这样的差异我们不得而知,但这的确引发了我不少的思考,你呢?
注:文中提到的FileHelper不仅仅指Yii的CFileHelper,泛指所有第三方文件操作库。