일반적인 사용 사례에 대한 복사 및 붙여 넣기 기능 준비, 위의 답변 중 하나의 개선 / 확장 버전 :
function getDirContents(string $dir, int $onlyFiles = 0, string $excludeRegex = '~/\.git/~', int $maxDepth = -1): array {
$results = [];
$scanAll = scandir($dir);
sort($scanAll);
$scanDirs = []; $scanFiles = [];
foreach($scanAll as $fName){
if ($fName === '.' || $fName === '..') { continue; }
$fPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath($dir . '/' . $fName));
if (strlen($excludeRegex) > 0 && preg_match($excludeRegex, $fPath . (is_dir($fPath) ? '/' : ''))) { continue; }
if (is_dir($fPath)) {
$scanDirs[] = $fPath;
} elseif ($onlyFiles >= 0) {
$scanFiles[] = $fPath;
}
}
foreach ($scanDirs as $pDir) {
if ($onlyFiles <= 0) {
$results[] = $pDir;
}
if ($maxDepth !== 0) {
foreach (getDirContents($pDir, $onlyFiles, $excludeRegex, $maxDepth - 1) as $p) {
$results[] = $p;
}
}
}
foreach ($scanFiles as $p) {
$results[] = $p;
}
return $results;
}
상대 경로가 필요한 경우 :
function updateKeysWithRelPath(array $paths, string $baseDir, bool $allowBaseDirPath = false): array {
$results = [];
$regex = '~^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', realpath($baseDir)), '~') . '(?:/|$)~s';
$regex = preg_replace('~/~', '/(?:(?!\.\.?/)(?:(?!/).)+/\.\.(?:/|$))?(?:\.(?:/|$))*', $regex);
if (DIRECTORY_SEPARATOR === '\\') {
$regex = preg_replace('~/~', '[/\\\\\\\\]', $regex) . 'i';
}
foreach ($paths as $p) {
$rel = preg_replace($regex, '', $p, 1);
if ($rel === $p) {
throw new \Exception('Path relativize failed, path "' . $p . '" is not within basedir "' . $baseDir . '".');
} elseif ($rel === '') {
if (!$allowBaseDirPath) {
throw new \Exception('Path relativize failed, basedir path "' . $p . '" not allowed.');
} else {
$results[$rel] = './';
}
} else {
$results[$rel] = $p;
}
}
return $results;
}
function getDirContentsWithRelKeys(string $dir, int $onlyFiles = 0, string $excludeRegex = '~/\.git/~', int $maxDepth = -1): array {
return updateKeysWithRelPath(getDirContents($dir, $onlyFiles, $excludeRegex, $maxDepth), $dir);
}
이 버전은 다음을 해결 / 개선합니다.
realpath
PHP open_basedir
가 ..
디렉토리를 다루지 않을 때의 경고 .
- 결과 배열에 대한 참조를 사용하지 않습니다.
- 디렉토리와 파일을 제외 할 수 있습니다.
- 파일 / 디렉토리 만 나열 할 수 있습니다.
- 검색 깊이를 제한 할 수 있습니다.
- 항상 디렉토리와 함께 출력을 먼저 정렬합니다 (따라서 디렉토리를 역순으로 제거 / 비울 수 있음).
- 상대 키로 경로를 얻을 수 있습니다.
- 수십만 또는 수백만 개의 파일에 최적화 됨
- 의견에 더 많은 것을 쓰십시오 :)
예 :
$onlyPhpFilesExcludeRegex = '~/\.git/|(?<!/|\.php)$|^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', realpath(__FILE__)), '~') . '$~is';
$phpFiles = getDirContents(__DIR__, 1, $onlyPhpFilesExcludeRegex);
print_r($phpFiles);
$phpFiles = getDirContentsWithRelKeys(__DIR__, 1, $onlyPhpFilesExcludeRegex);
print_r($phpFiles);
'~/\.git/|^(?!.*/(|' . '[^/]+_mails/en/[^/]+\.(?:html|txt)' . ')$)~is'
RecursiveDirectoryIterator