이런 식으로 갈 여러 가지 방법이 있습니다. 두 가지 빠른 방법을 선택할 수 있습니다 : 빠르고 더러운 대 더 길고 덜 더러운 것 (하지만 금요일 밤입니다. 조금 더 미친 듯이 허락 받는다).
1. 빠른 (더러운)
이 포함 단지 (복수로 분할 할 수있는) 하나의 빠른 급습에있는 파일의 컬렉션을 필터링하는 데 사용하는 정규 표현식을 작성.
는 (만 두 주석 처리 된 줄은 개념 정말 중요하다.)
$directory = new RecursiveDirectoryIterator(__DIR__);
$flattened = new RecursiveIteratorIterator($directory);
// Make sure the path does not contain "/.Trash*" folders and ends eith a .php or .html file
$files = new RegexIterator($flattened, '#^(?:[A-Z]:)?(?:/(?!\.Trash)[^/]+)+/[^/]+\.(?:php|html)$#Di');
foreach($files as $file) {
echo $file . PHP_EOL;
}
이러한 접근 방식은 문제의 번호를 가지고, 그냥 한 줄 것을 구현하는 빠른 비록합니다 (하지만 정규식은 해독 할 고통 일 수 있습니다.)
2 이하가 빠른 (덜 더러운)
더 재사용 가능한 접근 방식은 맞춤형 필터의 몇 가지를 만드는 것입니다 (정규식을 사용하여, 또는 당신이 원하는대로!) 깍을 사용할 수의 목록을 아래로 처음에는 RecursiveDirectoryIterator
의 항목 만 원하는 항목으로 줄일 수 있습니다. 다음은 RecursiveRegexIterator
을 확장 한 단 한 가지 예입니다.
기본 작업은 필터링 할 정규식을 유지하는 것이 주 업무이며 그 밖의 모든 작업은 RecursiveRegexIterator
으로 지연됩니다. 이 클래스는 실제로 을 수행하지 않으므로 abstract
이라는 점에 유의하십시오.은 유용합니다. 실제 필터링은이 클래스를 확장 할 두 클래스에 의해 수행됩니다. 또한 FilesystemRegexFilter
이라고 불릴 수도 있지만 파일 시스템과 관련된 클래스를 필터링하도록 (이 수준에서) 강제로 적용되는 것도 없습니다. (나는 아주 졸린 것이 아니라면 더 나은 이름을 선택했을 것입니다.)
이 두 클래스는 파일 이름과 디렉토리 이름 각각에 대해 매우 기본적인 필터입니다.
class FilenameFilter extends FilesystemRegexFilter {
// Filter files against the regex
public function accept() {
return (! $this->isFile() || preg_match($this->regex, $this->getFilename()));
}
}
class DirnameFilter extends FilesystemRegexFilter {
// Filter directories against the regex
public function accept() {
return (! $this->isDir() || preg_match($this->regex, $this->getFilename()));
}
}
연습에 사람들을 넣으려면, 재귀 스크립트가 (!이 편집 주시기) 상주 및 폴더 이름 을 확인하여합니다 (.Trash
폴더를 필터링하는 디렉토리의 내용에 비해 다음과 같은 반복 특별히 고안된 정규 표현식과 일치시키고 PHP 및 HTML 파일 만 수락합니다.
$directory = new RecursiveDirectoryIterator(__DIR__);
// Filter out ".Trash*" folders
$filter = new DirnameFilter($directory, '/^(?!\.Trash)/');
// Filter PHP/HTML files
$filter = new FilenameFilter($filter, '/\.(?:php|html)$/');
foreach(new RecursiveIteratorIterator($filter) as $file) {
echo $file . PHP_EOL;
}
특히주의해야 할 점은 필터가 반복적이기 때문에 반복 처리하는 방법을 선택할 수 있다는 것입니다. 예를 들어, 우리는 쉽게에만 수행하여 (시작 폴더 포함) 깊이 2 단계까지 스캔에 자신을 제한 할 수 있습니다 :
$files = new RecursiveIteratorIterator($filter);
$files->setMaxDepth(1); // Two levels, the parameter is zero-based.
foreach($files as $file) {
echo $file . PHP_EOL;
}
우리의 필터링을 더 인스턴스화하여 (아직 이상의 필터를 추가하는 것이 슈퍼 쉽다 (예 : 파일 크기, 전체 경로 길이 등)에 대한 새로운 필터링 클래스를 생성하여 새로운 정규식을 가진 클래스를 만들 수 있습니다.
P. 흠,이 대답은 조금 엉망이됩니다. 나는 가능한 한 간결하게 유지하려고 노력했다. (심지어 광대 한 광대 한 부분을 제거하는 것조차). 그물 결과가 응답을 일관성 없게 남겨두면 사과하십시오.
내가 찾고있는 것을 정확히 보여주는 덜 빠르기 (그리고 덜 부정한) 접근법을 정말 고맙게 생각합니다. 감사. 신속하고 더러운하지만 이 치명적인 오류와 에러 출력했다 : RecursiveDirectoryIterator :: __ 구조 (/var/www/html/.Trash-0) '메시지가 catch되지 않은 예외'UnexpectedValueException을 ' – Chris
오류는 정말 아무 문제 없습니다 코드 (바 열심히 시도하지 말 것), 가장 큰 원인은 폴더의 사용 권한 (또는 부족)입니다. 어쨌든 당신이 더 나은 대안에 만족한다면 다행입니다. :) – salathe
아주 좋지만, 간단한 경로가 아닌 각 파일에 대해 SplFileInfo 개체를 얻는 방법은 무엇입니까? –