Completed
Push — master ( 2e5bdd...9e2471 )
by Ryuichi
05:26
created

File::getAbsoluteFilePath()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 15.7547

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 6
cts 17
cp 0.3529
rs 8.439
c 0
b 0
f 0
cc 6
crap 15.7547
eloc 17
nc 7
nop 0
1
<?php
2
namespace WebStream\IO;
3
4
use WebStream\Exception\Extend\IOException;
5
6
/**
7
 * File
8
 * 状態を表さないもの(ファイルパス等)はキャッシュし
9
 * 状態を表すもの(存在チェク、ファイル種別、権限等)はキャッシュクリアし都度取得する
10
 * @author Ryuichi TANAKA.
11
 * @since 2016/02/05
12
 * @version 0.7
13
 */
14
class File
15
{
16
    /**
17
     * @var string ファイルパス
18
     */
19
    private $filePath;
20
21
    /**
22
     * @var string ファイル名
23
     */
24
    private $fileName;
25
26
    /**
27
     * @var string ファイル拡張子
28
     */
29
    private $fileExt;
30
31
    /**
32
     * constructor
33
     * @param string $filepath ファイルパス
34
     */
35
    public function __construct(string $filePath)
36
    {
37
        // realpathを含めてキャッシュクリア
38
        clearstatcache(true);
39
40
        $this->filePath = $filePath;
41
        $this->fileName = basename($this->filePath);
42
        $this->fileExt = pathinfo($this->filePath, PATHINFO_EXTENSION);
43
    }
44
45
    /**
46
     * ファイル名を返却する
47
     * @return string ファイル名
48
     */
49
    public function getFileName()
50
    {
51
        return $this->fileName;
52
    }
53
54
    /**
55
     * ファイル拡張子を返却する
56
     * @return string ファイル拡張子
57
     */
58
    public function getFileExtension()
59
    {
60
        return $this->fileExt;
61
    }
62
63
    /**
64
     * ファイルパスを返却する
65
     * シンボリックリンクの場合、シンボリックリンクファイルパスを返却する
66
     * @return string ファイルパス
67
     */
68
    public function getFilePath()
69
    {
70
        return $this->filePath;
71
    }
72
73
    /**
74
     * ファイルパスを返却する
75
     * シンボリックリンクの場合、実ファイルパスを返却する
76
     * @throws IOException
77
     * @return string ファイルパス
78
     */
79
    public function getAbsoluteFilePath()
80
    {
81
        if ($this->isLink()) {
82
            $filePath = $this->filePath;
83
            while (@is_link($filePath)) {
84
                $linkPath = readlink($filePath);
85
                if ($linkPath === false) {
86
                    throw new IOException("Symbolic link read error: " . $filePath);
87
                }
88
                $filePath = $linkPath;
89
            }
90
91
            $absoluteFilePath = realpath($filePath);
92
            if ($absoluteFilePath === false) {
93
                throw new IOException("File not found: " . $filePath);
94
            }
95
96
            return $absoluteFilePath;
97
        }
98
99
        $filePath = $this->getFilePath();
100
        $absoluteFilePath = realpath($filePath);
101
        if ($absoluteFilePath === false) {
102
            throw new IOException("File not found: " . $filePath);
103
        }
104
105
        return $absoluteFilePath;
106
    }
107
108
    /**
109
     * 読み込み権限があるか返却する
110
     * @return bool ファイルが存在し、読み込み権限があればtrue
111
     */
112
    public function isReadable()
113
    {
114
        // Fileオブジェクト作成後に属性が変わることを考慮しキャッシュクリアする
115
        clearstatcache();
116
117
        return @is_readable($this->filePath);
118
    }
119
120
    /**
121
     * 書き込み権限があるか返却する
122
     * @return bool ファイルが存在し、書き込み権限があればtrue
123
     */
124
    public function isWritable()
125
    {
126
        // Fileオブジェクト作成後に属性が変わることを考慮しキャッシュクリアする
127
        clearstatcache();
128
129
        return @is_writable($this->filePath);
130
    }
131
132
    /**
133
     * 実行権限があるか返却する
134
     * @return bool ファイルが存在し、実行権限があればtrue
135
     */
136
    public function isExecutable()
137
    {
138
        // Fileオブジェクト作成後に属性が変わることを考慮しキャッシュクリアする
139
        clearstatcache();
140
141
        return @is_executable($this->filePath);
142
    }
143
144
    /**
145
     * ファイルかどうか
146
     * @return bool ファイルならtrue
147
     */
148
    public function isFile()
149
    {
150
        clearstatcache();
151
152
        return is_file($this->filePath);
153
    }
154
155
    /**
156
     * ディレクトリかどうか
157
     * @return bool ディレクトリならtrue
158
     */
159
    public function isDirectory()
160
    {
161
        clearstatcache();
162
163
        return is_dir($this->filePath);
164
    }
165
166
    /**
167
     * リンクかどうか
168
     * @return bool リンクならtrue
169
     */
170
    public function isLink()
171
    {
172
        // Fileオブジェクト作成後に属性が変わることを考慮しキャッシュクリアする
173
        clearstatcache();
174
175
        return @is_link($this->filePath);
176
    }
177
178
    /**
179
     * ファイルサイズを返却する
180
     * ファイルが存在しなければ0
181
     * @return int ファイルサイズ
182
     */
183
    public function length()
184
    {
185
        $length = 0;
186
187
        if ($this->exists()) {
188
            $filePath = $this->getAbsoluteFilePath();
189
            $length = filesize($filePath);
190
191
            if ($length === false) {
192
                throw new IOException("Cannot get filesize of " . $filePath);
193
            }
194
        }
195
196
        return $length;
197
    }
198
199
    /**
200
     * ファイル(ディレクトリ、リンク含む)が存在するか
201
     * @return bool 存在すればtrue
202
     */
203
    public function exists()
204
    {
205
        // Fileオブジェクト作成後に属性が変わることを考慮しキャッシュクリアする
206
        clearstatcache();
207
208
        return $this->isLink() || $this->isDirectory() || $this->isFile();
209
    }
210
211
    /**
212
     * ファイルを削除する
213
     * @return bool 削除結果
214
     */
215
    public function delete()
216
    {
217
        // Fileオブジェクト作成後に属性が変わることを考慮しキャッシュクリアする
218
        clearstatcache();
219
220
        $isDeleted = false;
221
        if ($this->isWritable()) {
222
            if ($this->isDirectory()) {
223
                $isDeleted = rmdir($this->filePath);
224
            } else {
225
                $isDeleted = unlink($this->filePath);
226
            }
227
        }
228
229
        return $isDeleted;
230
    }
231
232
    /**
233
     * ファイルをリネームする
234
     * @param string $destPath 変更後ファイル名
235
     * @return bool リネーム結果
236
     */
237
    public function renameTo($destPath)
238
    {
239
        $dirname = dirname($destPath);
240
        $dir = new File($dirname);
241
        if (!$dir->isWritable()) {
242
            throw new IOException("Cannot writable: " . $destPath);
243
        }
244
        $dirPath = $dir->getFilePath();
245
        $absDestPath = $dirPath . "/" . basename($destPath);
246
247
        return rename($this->filePath, $absDestPath);
248
    }
249
250
    /**
251
     * ファイル更新日時を返却する
252
     * @return int ファイル更新日時
253
     */
254
    public function lastModified()
255
    {
256
        return $this->exists() ? filemtime($this->filePath) : 0;
257
    }
258
}
259