PHP에서 Zip 파일로 작업하는 것은 특히 압축 패키지에서 콘텐츠를 추출하거나 파일 구조를 읽어야 할 때 일반적인 작업입니다. Zip_Read () 함수는 ZipAchive 클래스 외부의 Zip 파일을 처리하는 또 다른 방법입니다. 종종 Zip_open () 및 Zip_entry_read () 와 같은 함수와 함께 사용됩니다. 이러한 기능은 낮은 수준이지만, 특히 멀티 레이어 중첩 디렉토리를 포함하는 Zip 파일을 처리 할 때 Zip 파일 구조를 더 깊이 파악하려는 개발자에게는 여전히 큰 의미가 있습니다.
먼저 zip_open () 로 zip 파일을 열고 zip_read ()를 사용하여 각 항목을 반복해야합니다. 다음은 기본 구조입니다.
$zip = zip_open("nested_directories.zip");
if (is_resource($zip)) {
while ($entry = zip_read($zip)) {
$entryName = zip_entry_name($entry);
echo "Entry: $entryName\n";
}
zip_close($zip);
}
이 코드 스 니펫은 지퍼 파일에 모든 항목 (디렉토리 및 파일 포함)을 나열 할 수 있지만 목록은 충분하지 않으므로 중첩 구조를 더 깊이 처리해야합니다.
Zip 파일의 중첩 디렉토리에는 실제 파일 시스템과 같은 "트리와 같은"구조가 없습니다. 각 디렉토리 또는 파일은 경로 문자열로 표시됩니다.
photos/
photos/vacation/
photos/vacation/beach.jpg
documents/report.docx
따라서 / 에 따라 파일 경로의 깊이를 판단해야합니다. 각 계층은 Simple Exploit () 로 분석 할 수 있습니다.
$depth = substr_count($entryName, '/');
디렉토리 수준에 따라 특정 작업을 수행해야 할 때 매우 유용합니다.
zip 파일의 내용을 지정된 디렉토리로 추출하고 디렉토리 구조를 보존하려면 zip_entry_read () 및 file_put_contents () 와 함께 수행 할 수 있습니다. 아래 그림과 같이 :
$zip = zip_open("nested_directories.zip");
$extractPath = "extracted/";
if (is_resource($zip)) {
while ($entry = zip_read($zip)) {
if (zip_entry_open($zip, $entry, "r")) {
$entryName = zip_entry_name($entry);
$fullPath = $extractPath . $entryName;
// 디렉토리 인 경우,만들어야합니다
if (substr($entryName, -1) === '/') {
if (!is_dir($fullPath)) {
mkdir($fullPath, 0755, true);
}
} else {
// 파일 인 경우,이전 디렉토리가 있는지 확인하십시오
$dir = dirname($fullPath);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
$content = zip_entry_read($entry, zip_entry_filesize($entry));
file_put_contents($fullPath, $content);
}
zip_entry_close($entry);
}
}
zip_close($zip);
}
위의 코드는 완전한 중첩 구조 추출 기능을 구현하고 디렉토리 생성 및 파일 쓰기를 처리하며 원래 구조가 변경되지 않도록합니다.
zip 업로드 기능을 제공하기 위해 웹 사이트 (예 : https://m66.net/upload )를 개발했다고 상상해보십시오. 사용자가 업로드 한 ZIP 파일에는 복잡한 다층 중첩 디렉토리가 포함될 수 있습니다. 추가 처리를 위해 이러한 파일을 임시 디렉토리로 안전하게 압축하려면 먼저 위의 코드로 컨텐츠를 추출한 다음 처리를 위해 대상 폴더를 통과 할 수 있습니다.
경로 트래버스 취약성 (예 : ../../etc/passwd 포함)을 피하려면 경로 스티칭 후 보안 검증을 수행해야합니다.
$realBase = realpath($extractPath);
$realUserPath = realpath($fullPath);
if (strpos($realUserPath, $realBase) !== 0) {
// 불법 경로,뛰어 올라
continue;
}
불필요한 파일 읽기를 피하십시오 : 특정 확장 장치가있는 프로세스 필요한 디렉토리 또는 파일 만 있습니다.
주문형 파일의 경우 큰 파일의 경우 Zip_entry_Read ($ entry, Zip_entry_Filesize ($ Entry))를 사용하여 한 번에로드하지 않지만 스트리밍 읽기를 사용하지 마십시오.
배치 작업 : 최종 작업에 데이터베이스 또는 외부 서비스가 포함 된 경우 버퍼링 결과를 고려하고 배치로 제출하십시오.
zip_read () 함수를 사용하여 Zip 파일을 처리하는 것은 ZipAchive 만큼 직관적이지는 않지만 구조 제어 요구 사항이 높은 일부 시나리오에서는 여전히 매우 실용적입니다. 경로 문자열을 분석하여 다층 중첩 디렉토리를 효과적으로 처리하고 서버 지정된 경로로 내용을 안전하게 추출 할 수 있습니다. 적절한 보안 및 성능 최적화 측정을 결합한이 접근법은 복잡한 ZIP 파일 처리 로직을 구축하기위한 강력한 도구로 남아 있습니다.