webstream-framework /
ClassLoader
| 1 | <?php |
||
| 2 | |||
| 3 | namespace WebStream\ClassLoader; |
||
| 4 | |||
| 5 | use RecursiveIteratorIterator; |
||
| 6 | use WebStream\DI\Injector; |
||
|
0 ignored issues
–
show
|
|||
| 7 | use WebStream\IO\File; |
||
|
0 ignored issues
–
show
The type
WebStream\IO\File was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 8 | use WebStream\IO\FileInputStream; |
||
|
0 ignored issues
–
show
The type
WebStream\IO\FileInputStream was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 9 | |||
| 10 | /** |
||
| 11 | * クラスローダ |
||
| 12 | * @author Ryuichi TANAKA. |
||
| 13 | * @since 2013/09/02 |
||
| 14 | * @version 0.7 |
||
| 15 | */ |
||
| 16 | class ClassLoader |
||
| 17 | { |
||
| 18 | use Injector; |
||
| 19 | |||
| 20 | /** |
||
| 21 | * @var Psr\Log\LoggerInterface |
||
|
0 ignored issues
–
show
The type
WebStream\ClassLoader\Psr\Log\LoggerInterface was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 22 | */ |
||
| 23 | private $logger; |
||
| 24 | |||
| 25 | /** |
||
| 26 | * @var string アプリケーションルートパス |
||
| 27 | */ |
||
| 28 | private string $applicationRoot; |
||
| 29 | |||
| 30 | /** |
||
| 31 | * constructor |
||
| 32 | * @param string アプリケーションルートパス |
||
| 33 | */ |
||
| 34 | 16 | public function __construct(string $applicationRoot) |
|
| 35 | { |
||
| 36 | 16 | $this->logger = new class () { public function __call($name, $args) {} }; |
|
| 37 | 16 | $this->applicationRoot = $applicationRoot; |
|
| 38 | } |
||
| 39 | |||
| 40 | /** |
||
| 41 | * クラスをロードする |
||
| 42 | * @param mixed クラスまたはクラスリスト |
||
| 43 | * @return array<string> ロード済みクラスリスト |
||
| 44 | */ |
||
| 45 | 7 | public function load($target): array |
|
| 46 | { |
||
| 47 | 7 | return is_array($target) ? $this->loadClassList($target) : $this->loadClass($target); |
|
| 48 | } |
||
| 49 | |||
| 50 | /** |
||
| 51 | * ファイルをインポートする |
||
| 52 | * @param string ファイルパス |
||
| 53 | * @param callable|null $filter フィルタリング無名関数 trueを返すとインポート |
||
| 54 | * @return bool インポート結果 |
||
| 55 | * @throws \WebStream\Exception\Extend\IOException |
||
| 56 | */ |
||
| 57 | 3 | public function import($filepath, callable $filter = null): bool |
|
| 58 | { |
||
| 59 | 3 | $file = new File($this->applicationRoot . "/" . $filepath); |
|
| 60 | 3 | if ($file->isFile()) { |
|
| 61 | 2 | if ($file->getFileExtension() === 'php') { |
|
| 62 | 2 | if ($filter === null || (is_callable($filter) && $filter($file->getFilePath()) === true)) { |
|
| 63 | 2 | include_once $file->getFilePath(); |
|
| 64 | 2 | $this->logger->debug($file->getAbsoluteFilePath() . " import success."); |
|
| 65 | } |
||
| 66 | } |
||
| 67 | |||
| 68 | 2 | return true; |
|
| 69 | } |
||
| 70 | |||
| 71 | 1 | return false; |
|
| 72 | } |
||
| 73 | |||
| 74 | /** |
||
| 75 | * 指定ディレクトリのファイルをインポートする |
||
| 76 | * @param string ディレクトリパス |
||
| 77 | * @param callable|null $filter フィルタリング無名関数 trueを返すとインポート |
||
| 78 | * @return bool インポート結果 |
||
| 79 | * @throws \WebStream\Exception\Extend\IOException |
||
| 80 | */ |
||
| 81 | 3 | public function importAll($dirPath, callable $filter = null): bool |
|
| 82 | { |
||
| 83 | 3 | $dir = new File($this->applicationRoot . "/" . $dirPath); |
|
| 84 | 3 | $isSuccess = true; |
|
| 85 | 3 | if ($dir->isDirectory()) { |
|
| 86 | 3 | $iterator = $this->getFileSearchIterator($dir->getAbsoluteFilePath()); |
|
| 87 | 3 | foreach ($iterator as $filepath => $fileObject) { |
|
| 88 | 3 | if (preg_match("/(?:\/\.|\/\.\.|\.DS_Store)$/", $filepath)) { |
|
| 89 | 3 | continue; |
|
| 90 | } |
||
| 91 | 3 | $file = new File($filepath); |
|
| 92 | 3 | if ($file->isFile()) { |
|
| 93 | 3 | if ($file->getFileExtension() === 'php') { |
|
| 94 | 3 | if ($filter === null || (is_callable($filter) && $filter($file->getFilePath()) === true)) { |
|
| 95 | 1 | include_once $file->getFilePath(); |
|
| 96 | 1 | $this->logger->debug($file->getAbsoluteFilePath() . " import success."); |
|
| 97 | } |
||
| 98 | } |
||
| 99 | } else { |
||
| 100 | $this->logger->warn($filepath . " import failure."); |
||
| 101 | $isSuccess = false; |
||
| 102 | } |
||
| 103 | } |
||
| 104 | } |
||
| 105 | |||
| 106 | 3 | return $isSuccess; |
|
| 107 | } |
||
| 108 | |||
| 109 | /** |
||
| 110 | * 名前空間リストを返却する |
||
| 111 | * @param string ファイル名 |
||
| 112 | * @return array<string> 名前空間リスト |
||
| 113 | * @throws \WebStream\Exception\Extend\IOException |
||
| 114 | * @throws \WebStream\Exception\Extend\InvalidArgumentException |
||
| 115 | */ |
||
| 116 | 3 | public function getNamespaces($fileName): array |
|
| 117 | { |
||
| 118 | 3 | $dir = new File($this->applicationRoot); |
|
| 119 | 3 | $namespaces = []; |
|
| 120 | 3 | if ($dir->isDirectory()) { |
|
| 121 | 3 | $iterator = $this->getFileSearchIterator($dir->getAbsoluteFilePath()); |
|
| 122 | 3 | foreach ($iterator as $filepath => $fileObject) { |
|
| 123 | 3 | if (preg_match("/(?:\/\.|\/\.\.|\.DS_Store)$/", $filepath)) { |
|
| 124 | 3 | continue; |
|
| 125 | } |
||
| 126 | 3 | $file = new File($filepath); |
|
| 127 | 3 | if ($file->isFile() && $file->getFileName() === $fileName) { |
|
| 128 | 2 | $fis = new FileInputStream($file); |
|
| 129 | 2 | while (($line = $fis->readLine()) !== null) { |
|
| 130 | 2 | if (preg_match("/^namespace\s(.*);$/", $line, $matches)) { |
|
| 131 | 2 | $namespaces[] = $matches[1]; |
|
| 132 | } |
||
| 133 | } |
||
| 134 | 2 | $fis->close(); |
|
| 135 | } |
||
| 136 | } |
||
| 137 | } |
||
| 138 | |||
| 139 | 3 | return $namespaces; |
|
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * ロード可能なクラスを返却する |
||
| 144 | * @param string クラス名(フルパス指定の場合はクラスパス) |
||
| 145 | * @return array<string> ロード可能クラス |
||
| 146 | * @throws \WebStream\Exception\Extend\IOException |
||
| 147 | */ |
||
| 148 | 7 | private function loadClass(string $className): array |
|
| 149 | { |
||
| 150 | 7 | $rootDir = $this->applicationRoot; |
|
| 151 | 7 | $logger = $this->logger; |
|
| 152 | |||
| 153 | // 名前空間セパレータをパスセパレータに置換 |
||
| 154 | 7 | if (DIRECTORY_SEPARATOR === '/') { |
|
| 155 | 7 | $className = str_replace("\\", DIRECTORY_SEPARATOR, $className); |
|
| 156 | } |
||
| 157 | |||
| 158 | 7 | $search = function ($dirPath, $searchFilePath) use ($logger) { |
|
| 159 | 7 | $includeList = []; |
|
| 160 | 7 | $dir = new File($dirPath); |
|
| 161 | 7 | if (!$dir->isDirectory()) { |
|
| 162 | 1 | $logger->error("Invalid search directory path: " . $dir->getFilePath()); |
|
| 163 | 1 | return $includeList; |
|
| 164 | } |
||
| 165 | 6 | $iterator = $this->getFileSearchIterator($dir->getAbsoluteFilePath()); |
|
| 166 | 6 | foreach ($iterator as $filepath => $fileObject) { |
|
| 167 | 6 | if (!$fileObject->isFile()) { |
|
| 168 | 6 | continue; |
|
| 169 | } |
||
| 170 | 6 | if (strpos($filepath, $searchFilePath) !== false) { |
|
| 171 | 5 | $file = new File($filepath); |
|
| 172 | 5 | $absoluteFilePath = $file->getAbsoluteFilePath(); |
|
| 173 | 5 | include_once $absoluteFilePath; |
|
| 174 | 5 | $includeList[] = $absoluteFilePath; |
|
| 175 | 5 | $logger->debug($absoluteFilePath . " load success. (search from " . $dir->getAbsoluteFilePath() . ")"); |
|
| 176 | } |
||
| 177 | } |
||
| 178 | |||
| 179 | 6 | return $includeList; |
|
| 180 | 7 | }; |
|
| 181 | |||
| 182 | 7 | return $search("${rootDir}", DIRECTORY_SEPARATOR . "${className}.php"); |
|
| 183 | } |
||
| 184 | |||
| 185 | /** |
||
| 186 | * ロード可能なクラスを複数返却する |
||
| 187 | * @param array クラス名 |
||
| 188 | * @return array<string> ロード済みクラスリスト |
||
| 189 | * @throws \WebStream\Exception\Extend\IOException |
||
| 190 | */ |
||
| 191 | private function loadClassList(array $classList): array |
||
| 192 | { |
||
| 193 | $includedList = []; |
||
| 194 | foreach ($classList as $className) { |
||
| 195 | $result = $this->loadClass($className); |
||
| 196 | if (is_array($result)) { |
||
| 197 | $includedList = array_merge($includedList, $result); |
||
| 198 | } |
||
| 199 | } |
||
| 200 | |||
| 201 | return $includedList; |
||
| 202 | } |
||
| 203 | |||
| 204 | /** |
||
| 205 | * ファイル検索イテレータを返却する |
||
| 206 | * @param string ディレクトリパス |
||
| 207 | * @return RecursiveIteratorIterator イテレータ |
||
| 208 | */ |
||
| 209 | 12 | private function getFileSearchIterator(string $path): \RecursiveIteratorIterator |
|
| 210 | { |
||
| 211 | 12 | $iterator = []; |
|
| 212 | 12 | $file = new File($path); |
|
| 213 | 12 | if ($file->isDirectory()) { |
|
| 214 | 12 | $iterator = new \RecursiveIteratorIterator( |
|
| 215 | 12 | new \RecursiveDirectoryIterator($path), |
|
| 216 | 12 | \RecursiveIteratorIterator::LEAVES_ONLY, |
|
| 217 | 12 | \RecursiveIteratorIterator::CATCH_GET_CHILD // for Permission deny |
|
| 218 | ); |
||
| 219 | } |
||
| 220 | 12 | return $iterator; |
|
|
0 ignored issues
–
show
|
|||
| 221 | } |
||
| 222 | } |
||
| 223 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths