如何根据文件路径找到文件的目录

1. 有下面这样的一个需求

把下面的两个路径转换为正确的文件目录

1
2
/mfw_project/test/demo/demo/../../demo.js
/mfw_project/test/./demo.js

转换成:

1
/mfw_project/test/demo.js

OK,开始搞!

  • 第一个方案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$str = '/mfw_project/test/demo/demo/../../demo.js';
//$str = '/mfw_project/test/./demo.js';
$arr = explode('/',$str);
//第一种情况
$arr = array_filter($arr,function($value){
if('.' === $value)
{
return false;
}
return true;
});
//第二种情况
while(($index = array_search('..',$arr))!==false)
{
unset($arr[$index]);
unset($arr[$index-1]);
$arr = array_values($arr);
}
$str = implode('/',$arr);
var_dump($str);
  • 第二个方案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$str = '/mfw_project/test/demo/demo/../../demo.js';
//$str = '/mfw_project/test/./demo.js';
function newStr($str)
{
//第一种情况
$str = preg_replace('/([\w\d])+\/..\//','',$str);
if(strpos($str,'..'))
{
return newStr($str);
}
//第二种情况
if(strpos($str,'.'))
{
$str = str_replace("./",'',$str);
}
return $str;
}
$str = newStr($str);
var_dump($str);

以上两种方案都可以解决我们的需求。但是那种效率更高些呢?我们测试一下

测试执行效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
$start_time = microtime(true);
$str = '/mfw_project/test/demo/demo/demo2/demo3/../../../../demo.js';
for($i=0;$i<100000;$i++)
{
/*
$arr = explode('/',$str);
$arr = array_filter($arr,function($value){
if('.' === $value)
{
return false;
}
return true;
});
while(($index = array_search('..',$arr))!==false){
unset($arr[$index]);
unset($arr[$index-1]);
$arr = array_values($arr);
}
$str = implode('/',$arr);
*/
$str = newStr($str);
}
function newStr($str)
{
//第一种情况
$str = preg_replace('/([\w\d])+\/..\//','',$str);
if(strpos($str,'..'))
{
return newStr($str);
}
//第二种情况
if(strpos($str,'.'))
{
$str = str_replace("./",'',$str);
}
return $str;
}
echo $str."\n";
$end_time = microtime(true);
$run_time = $end_time - $start_time;
echo "程序运行".$run_time."秒";
exit;
  • 执行结果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //递归方式
    ➜ ~ php 1.php
    /mfw_project/test/demo.js
    程序运行0.57571291923523
    ➜ ~ php 1.php
    /mfw_project/test/demo.js
    程序运行0.58426809310913
    ➜ ~ php 1.php
    /mfw_project/test/demo.js
    程序运行0.58362793922424
    //截取方式
    ➜ ~ php 1.php
    /mfw_project/test/demo.js
    程序运行0.22979879379272
    ➜ ~ php 1.php
    /mfw_project/test/demo.js
    程序运行0.23150992393494
    ➜ ~ php 1.php
    /mfw_project/test/demo.js
    程序运行0.22574400901794

可以看到代码,我们把程序循环执行了10万次,代码执行效率.
截取方式比递归方式,效率快了一倍多。

结论

  • 尽量使用PHP自带函数
  • PHP中,用正则匹配比直接用PHP截取慢,不过第二种方式代码更美观一些