From 2757873ef2f4c39071e21e3fe626b36e8f937374 Mon Sep 17 00:00:00 2001 From: JaguarJack Date: Sun, 19 Jul 2020 09:15:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=96=87=E4=BB=B6=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exceptions/FiledNotFoundException.php | 8 + extend/catcher/library/FileSystem.php | 595 ++++++++++++++++-- 2 files changed, 563 insertions(+), 40 deletions(-) create mode 100644 extend/catcher/exceptions/FiledNotFoundException.php diff --git a/extend/catcher/exceptions/FiledNotFoundException.php b/extend/catcher/exceptions/FiledNotFoundException.php new file mode 100644 index 0000000..3a5d8e7 --- /dev/null +++ b/extend/catcher/exceptions/FiledNotFoundException.php @@ -0,0 +1,8 @@ +files($path); - - $dirs = $this->dirs($path); - - foreach ($dirs as $dir) { - $files = array_merge($files, $this->allFiles($dir)); - } - - return $files; + return file_exists($path); } /** - * 获取文件夹下的文件 + * 获取文件内容 * - * @time 2020年07月02日 - * @param $path - * @return array - */ - public function files($path) + * @param string $path + * @param bool $lock + * @return string + **/ + public function get($path, $lock = false) { - $files = []; - - $fileSystemIterator = new \FilesystemIterator($path); - - foreach ($fileSystemIterator as $fileSystem) { - if (!$fileSystem->isDir()) { - $files[] = $fileSystem->getPathName(); - } + if ($this->isFile($path)) { + return $lock ? $this->sharedGet($path) : file_get_contents($path); } - return $files; + throw new FiledNotFoundException("File does not exist at path {$path}"); } /** - * 获取文件夹 + * 安全获取文件内容 * - * @time 2020年07月02日 - * @param $path - * @return array + * @param string $path + * @return string */ - public function dirs($path) + public function sharedGet($path) { - $dirs = []; + $contents = ''; - $fileSystemIterator = new \FilesystemIterator($path); + $handle = fopen($path, 'rb'); - foreach ($fileSystemIterator as $fileSystem) { - if ($fileSystem->isDir()) { - $dirs[] = $fileSystem->getPathname(); + if ($handle) { + try { + if (flock($handle, LOCK_SH)) { + clearstatcache(true, $path); + + $contents = fread($handle, $this->size($path) ?: 1); + + flock($handle, LOCK_UN); + } + } finally { + fclose($handle); } } - return $dirs; + return $contents; + } + + /** + * 加载文件返回 + * + * @param string $path + * @return mixed + * + * @throws FiledNotFoundException + */ + public function getRequire($path) + { + if ($this->isFile($path)) { + return require $path; + } + + throw new FiledNotFoundException("File does not exist at path {$path}"); + } + + /** + * 加载文件 + * + * @param string $file + * @return mixed + */ + public function requireOnce($file) + { + require_once $file; + } + + /** + * hash + * + * @param string $path + * @return string + */ + public function hash($path) + { + return md5_file($path); + } + + /** + * 写入文件 + * + * @param string $path + * @param string $contents + * @param bool $lock + * @return int|bool + */ + public function put($path, $contents, $lock = false) + { + return file_put_contents($path, $contents, $lock ? LOCK_EX : 0); + } + + /** + * 替换 + * + * @param string $path + * @param string $content + * @return void + */ + public function replace($path, $content) + { + + clearstatcache(true, $path); + + $path = realpath($path) ?: $path; + + $tempPath = tempnam(dirname($path), basename($path)); + + chmod($tempPath, 0777 - umask()); + + file_put_contents($tempPath, $content); + + rename($tempPath, $path); + } + + /** + * 重制文件 + * + * @param string $path + * @param string $data + * @return int + */ + public function prepend($path, $data) + { + if ($this->exists($path)) { + return $this->put($path, $data.$this->get($path)); + } + + return $this->put($path, $data); + } + + /** + * 追加文件 + * + * @param string $path + * @param string $data + * @return int + */ + public function append($path, $data) + { + return file_put_contents($path, $data, FILE_APPEND); + } + + /** + * 设置权限 + * + * @param string $path + * @param int|null $mode + * @return mixed + */ + public function chmod($path, $mode = null) + { + if ($mode) { + return chmod($path, $mode); + } + + return substr(sprintf('%o', fileperms($path)), -4); + } + + /** + * 删除文件 + * + * @param string|array $paths + * @return bool + */ + public function delete($paths) + { + $paths = is_array($paths) ? $paths : func_get_args(); + + $success = true; + + foreach ($paths as $path) { + try { + if (! @unlink($path)) { + $success = false; + } + } catch (\ErrorException $e) { + $success = false; + } + } + + return $success; + } + + /** + * 移动文件 + * + * @param string $path + * @param string $target + * @return bool + */ + public function move($path, $target) + { + return rename($path, $target); + } + + /** + * 复制文件 + * + * @param string $path + * @param string $target + * @return bool + */ + public function copy($path, $target) + { + return copy($path, $target); + } + + /** + *硬连接 + * + * @param string $target + * @param string $link + * @return void|mixed + */ + public function link($target, $link) + { + $isWin = strtolower(substr(PHP_OS, 0, 3)) === 'win'; + if (! $isWin) { + return symlink($target, $link); + } + + $mode = $this->isDirectory($target) ? 'J' : 'H'; + + exec("mklink /{$mode} ".escapeshellarg($link).' '.escapeshellarg($target)); + } + + /** + * file name + * + * @param string $path + * @return string + */ + public function name($path) + { + return pathinfo($path, PATHINFO_FILENAME); + } + + /** + * basename + * + * @param string $path + * @return string + */ + public function basename($path) + { + return pathinfo($path, PATHINFO_BASENAME); + } + + /** + * dirname + * + * @param string $path + * @return string + */ + public function dirname($path) + { + return pathinfo($path, PATHINFO_DIRNAME); + } + + /** + * 文件后缀 + * + * @param string $path + * @return string + */ + public function extension($path) + { + return pathinfo($path, PATHINFO_EXTENSION); + } + + /** + * 文件类型 + * + * @param string $path + * @return string + */ + public function type($path) + { + return filetype($path); + } + + /** + * mimeType + * + * @param string $path + * @return string|false + */ + public function mimeType($path) + { + return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path); + } + + /** + * 文件大小 + * + * @param string $path + * @return int + */ + public function size($path) + { + return filesize($path); + } + + /** + * 获取上次文件的修改时间 + * + * @param string $path + * @return int + */ + public function lastModified($path) + { + return filemtime($path); + } + + /** + * 是否是文件夹. + * + * @param string $directory + * @return bool + */ + public function isDirectory($directory) + { + return is_dir($directory); + } + + /** + *是否可读 + * + * @param string $path + * @return bool + */ + public function isReadable($path) + { + return is_readable($path); + } + + /** + * 是否可写 + * + * @param string $path + * @return bool + */ + public function isWritable($path) + { + return is_writable($path); + } + + /** + * 是否是文件 + * + * @param string $file + * @return bool + */ + public function isFile($file) + { + return is_file($file); + } + + /** + * 查找文件 + * + * @param string $pattern + * @param int $flags + * @return array + */ + public function glob($pattern, $flags = 0) + { + return glob($pattern, $flags); + } + + /** + * 查找目录所有文件 + * + * @param string $directory + * @param bool $hidden + * @return \Symfony\Component\Finder\SplFileInfo[] + */ + public function files($directory, $hidden = false) + { + return iterator_to_array( + Finder::create()->files()->ignoreDotFiles(! $hidden)->in($directory)->depth(0)->sortByName(), + false + ); + } + + /** + * 递归文件目录下所有文件 + * + * @param string $directory + * @param bool $hidden + * @return \Symfony\Component\Finder\SplFileInfo[] + */ + public function allFiles($directory, $hidden = false) + { + return iterator_to_array(Finder::create()->files()->ignoreDotFiles(! $hidden)->in($directory)->sortByName(), + false + ); + } + + /** + * 文件目录下所有子目录 + * + * @param string $directory + * @return array + */ + public function directories($directory) + { + $directories = []; + + foreach (Finder::create()->in($directory)->directories()->depth(0)->sortByName() as $dir) { + $directories[] = $dir->getPathname(); + } + + return $directories; + } + + /** + * 创建目录 + * + * @param string $path + * @param int $mode + * @param bool $recursive + * @param bool $force + * @return bool + */ + public function makeDirectory($path, $mode = 0755, $recursive = false, $force = false) + { + if ($force) { + return @mkdir($path, $mode, $recursive); + } + + return mkdir($path, $mode, $recursive); + } + + /** + * 移动目录 + * + * @param string $from + * @param string $to + * @param bool $overwrite + * @return bool + */ + public function moveDirectory($from, $to, $overwrite = false) + { + if ($overwrite && $this->isDirectory($to) && ! $this->deleteDirectory($to)) { + return false; + } + + return @rename($from, $to) === true; + } + + /** + *复制目录 + * + * @param string $directory + * @param string $destination + * @param int|null $options + * @return bool + */ + public function copyDirectory($directory, $destination, $options = null) + { + if (! $this->isDirectory($directory)) { + return false; + } + + $options = $options ?: \FilesystemIterator::SKIP_DOTS; + + + if (! $this->isDirectory($destination)) { + $this->makeDirectory($destination, 0777, true); + } + + $items = new \FilesystemIterator($directory, $options); + + foreach ($items as $item) { + + $target = $destination.'/'.$item->getBasename(); + + if ($item->isDir()) { + $path = $item->getPathname(); + + if (! $this->copyDirectory($path, $target, $options)) { + return false; + } + } + + else { + if (! $this->copy($item->getPathname(), $target)) { + return false; + } + } + } + + return true; + } + + /** + * 删除目录 + * + * @param string $directory + * @param bool $preserve + * @return bool + */ + public function deleteDirectory($directory, $preserve = false) + { + if (! $this->isDirectory($directory)) { + return false; + } + + $items = new \FilesystemIterator($directory); + + foreach ($items as $item) { + + if ($item->isDir() && ! $item->isLink()) { + $this->deleteDirectory($item->getPathname()); + } else { + $this->delete($item->getPathname()); + } + } + + if (! $preserve) { + @rmdir($directory); + } + + return true; + } + + /** + * 删除目录下所有目录 + * + * @param string $directory + * @return bool + */ + public function deleteDirectories($directory) + { + $allDirectories = $this->directories($directory); + + if (! empty($allDirectories)) { + foreach ($allDirectories as $directoryName) { + $this->deleteDirectory($directoryName); + } + + return true; + } + + return false; + } + + /** + * 清空目录 + * + * @param string $directory + * @return bool + */ + public function cleanDirectory($directory) + { + return $this->deleteDirectory($directory, true); } } \ No newline at end of file