php的glob方法在windows下的转义无效的诡异问题。最后有彩蛋

目录结构如下

myfolder
    a.txt
[myfolder]
    a.txt

代码:

$files = glob('myfolder/a.txt');
var_dump($files);
$files = glob('[myfolder]/a.txt');
var_dump($files);
//[]在使用中需要转义
$files = glob('\[myfolder\]/a.txt');
var_dump($files);

windows下输出

test.php:7:
array(1) {
  [0] =>
  string(14) "myfolder/a.txt"
}
test.php:14:
array(0) {
}
test.php:21:
array(0) {
}

linux下输出

test.php:7:
array(1) {
  [0]=>
  string(14) "myfolder/a.txt"
}
test.php:14:
array(0) {
}
test.php:21:
array(1) {
  [0]=>
  string(16) "[myfolder]/a.txt"
}

不管是windows还是linux,[]在目录中都是正常字符

为什么windows下就匹配不出来呢?

我们去看php源码

查找PHP_FUNCTION(glob),

找到关键代码

PHP_FUNCTION(glob)
{
    ...
    if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
    ...
}

继续查找glob方法的定义

#ifndef PHP_WIN32
#include <glob.h>
#else
#include "win32/glob.h"
#endif

从这我们看出,glob方法在windows和linux中是用的2套方法,在linux中用的是linux底层的方法。

我们再去win32/glob.c下看代码

找到了下面这几行关键代码

...
#ifdef PHP_WIN32
    /* Force skipping escape sequences on windows
     * due to the ambiguity with path backslashes
     */
    flags |= GLOB_NOESCAPE;
#endif
...

翻译下大致意思是,由于windows下目录的路径正反斜杠混用,所以强制不转义

也就是说windows下,使用glob方法就算你用了反斜杠也不会转义

啊,问题终于找到了!!!

彩蛋来了

那么为什么windows用反斜杠做路径呢?

因为windows前身是ms-dos系统。

dos1时还没有目录结构的概念,并且当时微软的开发人员有 DEC 的背景,DEC 的操作系统上是用 / 做命令行参数分割符。

到了dos2.0时代,系统新增了目录结构概念,但是 / 已经被用了,所以只能换一个喽,于是微软用反斜杠做了目录路径的分隔符。

彩蛋原文

php

相关推荐