PHP 계정에서 다음과 같은 구조로 파일이 존재하고 있습니다.
목표는 files 디렉토리(폴더) 내에 있는 파일들을 탐색하고, 파일들의 정보(이름, 확장자, 크기 등)를 표시 및 데이터베이스 테이블에 입력하는 것입니다. 핵심 코드는 아래와 같습니다.
$dir = './files'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
$dir
은 탐색 대상 디렉토리의 루트 경로를 입력합니다. 현재 작성중인 php 파일과 files 디렉토리가 같은 경로 내에 있으므로 위와 같이 입력하였습니다. 일단 RecursiveDirectoryIterator
는 이름을 보면 파일 시스템 내부를 재귀적으로 탐색하는 역할을 하는 것처럼 보이고, 실제로 그 역할이 맞습니다. 다만 new RecursivesiveDirectoryIterator(경로)
를 단독으로 사용하면 원하는 결과가 나오지 않습니다.
// 잘못된 코드: 루트 디렉토리의 내용만 출력됨 $iterator = new RecursiveDirectoryIterator($dir);
단독으로 사용할 경우 files 디렉토리 정보만 출력하고 하위 디렉토리는 출력되지 않습니다. 이것을 RecursiveIteratorIterator
라는 클래스의 인스턴스로 한 번 감싸고 실행해야 실제로 재귀 탐색을 수행합니다. 클래스 이름이 이상한데 풀어쓰면 RecursiveIterator의 Iterator
입니다. 굳이 이렇게 작성해야 하는 이유는 이 글(영문)을 참고해주세요.
이제 $iterator
는 파일 및 디렉토리의 정보들을 담고 있습니다. 이것을 foreach
문으로 처리하면 됩니다.
<?php // DB 초기화 작업 (...) if(!$mysqli){ echo "MySQL 접속 실패: "; } function iterateDirectory($i, $mysqli) { foreach ($i as $path) { if ($path->isDir()) { iterateDirectory($path, $mysqli); } else { $r_path = str_replace("\\", "/", $path); $v_path = str_replace("./files/", "", $r_path); $basename = $path->getBasename(); $real_path = str_replace("./files", "", $path->getPath()); $extension = $path->getExtension(); $disp_name = str_replace(".".$extension, "", $basename); $a_time = $path->getATime(); $c_time = $path->getCTime(); $m_time = $path->getMTime(); $a_date = date("Y-m-d H:i:s", $a_time); $c_date = date("Y-m-d H:i:s", $c_time); $m_date = date("Y-m-d H:i:s", $m_time); $size = $path->getSize(); $type = $path->getType(); echo "<tr>"; echo "<td>".$basename; echo "<td>".$real_path; echo "<td>".$extension; echo "<td>".$disp_name; echo "<td>".$a_date; echo "<td>".$c_date; echo "<td>".$m_date; echo "<td>".$size; echo "<td>".$type; $sql = "INSERT INTO `music_midi_files`" ."(`id`, `disp_name`, `basename`, `path`, `extension`, " ."`a_time`, `c_time`, `m_time`, `size`, `type`, `reg_dt`, `is_work`) VALUES " ."(0,'$disp_name','$base_name','$real_path','$extension'," ."'$a_date','$c_date','$m_date','$size','$type',sysdate(),1)"; if($mysqli->query($sql)) { echo "<td><span style='color:green;'>success</span>"; } else { echo "<td><span style='color:red;'>failure</span>"; } echo "</tr>"; } } } $dir = './files'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); iterateDirectory($iterator, $mysqli); ?>
데이터베이스 초기화 작업에 대한 코드는 생략합니다. 이 글을 참고해주세요. 재귀 탐색을 위해 iterateDirectory
라는 함수를 만들었습니다. 이 안에 $iterator
에 대한 foreach
문을 실행합니다. $path
가 디렉토리라면 해당 함수를 재귀호출하고, 아니라면(=파일이라면) 파일 정보를 표시하고 sql의 insert
문을 실행합니다. 참고로 $path
의 타입은 FilesystemIterator
입니다. (바로 가기(영문))
위에서 언급했던 문제되는 부분이 이 if
문인데 ReursiveDirectoryIterator
의 결과는 여기서 디렉토리라는 것을 인지하고 그 이후 탐색해야 할 정보도 가지고 있습니다. 다만 $path
를 파라미터로 하는 함수를 호출해도 작업을 수행하지 못합니다.
0개의 댓글