Passed
Push — master ( b40076...712f93 )
by 世昌
01:54
created

CharsetGuesser::toAbsolutePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
namespace nebula\application\filesystem;
3
4
use nebula\component\loader\PathTrait;
5
6
/**
7
 * 文件路径推测
8
 * 包括非UTF-8路径以及大小写敏感
9
 */
10
class CharsetGuesser
11
{
12
    protected $gusse = ['GBK','GB2312','BIG5'];
13
    protected $realPath;
14
    protected $path;
15
16
    public function __construct(string $path, array $charset = [])
17
    {
18
        $this->path = $this->toAbsolutePath($path);
19
        $this->gusse = count($charset) > 0? $charset : $this->gusse;
20
    }
21
22
    /**
23
     * 获取真实路径
24
     *
25
     * @return string
26
     */
27
    public function getRealPath():string
28
    {
29
        return  $this->exist() ? (realpath($this->path) ?? $this->realPath): '';
30
    }
31
32
    /**
33
     * 判断文件是否存在
34
     *
35
     * @return boolean
36
     */
37
    public function exist():bool
38
    {
39
        if ($this->existCase($this->path)) {
40
            return true;
41
        }
42
        foreach ($this->gusse as $code) {
43
            $file = iconv('UTF-8', $code, $this->path);
44
            $abspath =  $this->toAbsolutePath($file);
45
            if ($file !== false && $this->existCase($abspath)) {
46
                $this->realPath = $abspath;
47
                return true;
48
            }
49
        }
50
        return false;
51
    }
52
53
    /**
54
     * 正常文件系统中可以判断文件大小写
55
     *
56
     * @param string $path
57
     * @return boolean
58
     */
59
    protected function existCase(string $abspath):bool
60
    {
61
        // 真实文件系统
62
        if (realpath($abspath) === $abspath) {
63
            return true;
64
        }
65
        // 虚拟文件系统
66
        if (\file_exists($abspath)) {
67
            foreach (stream_get_wrappers() as $wrapper) {
68
                if (strpos($abspath, $wrapper.'://') === 0) {
69
                    return true;
70
                }
71
            }
72
        }
73
        return false;
74
    }
75
76
    protected function toAbsolutePath(string $path)
77
    {
78
        return PathTrait::toAbsolutePath($path);
79
    }
80
}
81