PHP에서 일반 프로세스는 다음과 같습니다.
$zip = zip_open("example.zip");
if (is_resource($zip)) {
while ($entry = zip_read($zip)) {
echo "Name: " . zip_entry_name($entry) . "\n";
if (zip_entry_open($zip, $entry, "r")) {
$contents = zip_entry_read($entry, 1024);
echo "Content: " . $contents . "\n";
zip_entry_close($entry);
}
}
zip_close($zip);
}
위의 코드는 공식 PHP 문서에서 제공하는 일반적인 사용입니다. 많은 시나리오에서 잘 작동하지만 조금 더 복잡하거나 내용이 특정 크기를 초과하는 한 문제가 발생합니다.
내용을 읽을 수 없습니다 : Zip_entry_read ()는 빈 문자열을 반환합니다.
일부 파일은 읽기 중간에 중단됩니다 . 부분 내용 만 읽을 수 있습니다.
오류를보고하거나 고정 : 일부 압축 패키지로 인해 PHP 실행이 발생합니다.
읽기 순서는 혼란 스럽습니다 . 여러 항목의 내용은 서로 대화됩니다.
이러한 문제는 공통점이 있습니다. Ziparchive와 같은 다른 라이브러리로 전환하는 한 일반적으로 문제가 사라집니다. 이것은 문제가 ZIP 파일 자체가 아니라 Zip_* 함수의 사용 또는 구현 메커니즘에있을 가능성이 있음을 보여줍니다.
Zip_Read () 는 본질적으로 호출 할 때마다 Zip의 읽기 포인터를 내부적으로 유지하는 반복자입니다. 읽기 과정에서 다음 Zip_read ()를 호출하면 (예 : 항목 읽기를 마치기 전에) 이전 항목의 읽기 상태가 파괴됩니다.
Zip_entry_Read ()는 모든 데이터가 한 번에 읽히도록 보장하지 않습니다. 특히 고정 길이 (예 : 1024)로 전달할 때 빈 문자열이 반환 될 때까지 읽기 위해 루프를 반복해야합니다. 그렇지 않으면 컨텐츠가 손실됩니다.
이것은 또한이 기사의 핵심입니다. Zip_entry_Read ()는 본질적으로 Zip_Read ()가 현재 유지 관리하는 항목 상태에 따라 다릅니다. zip_entry_read () (다른 논리 분기에서도) 호출 할 때 zip_read ()를 다시 호출하면 이전 동작이 중단됩니다.
현재 입력 내용을 읽지 않은 경우 다음 zip_read ()를 입력하지 마십시오. 그렇지 않으면 읽기 포인터가 미리 이동하여 콘텐츠가 손실되거나 잘못되게됩니다.
while ($entry = zip_read($zip)) {
zip_entry_open($zip, $entry, "r");
$content = "";
while ($data = zip_entry_read($entry, 1024)) {
$content .= $data;
}
echo $content;
zip_entry_close($entry);
}
일부 ZIP 파일은 비표준 도구로 압축 될 수 있으며 불규칙한 구조를 포함 할 수 있습니다. ziparchive 클래스를 사용하여 IsReadable () 메소드와 협력하여 무결성을 먼저 확인하는 것이 좋습니다.
$zip = new ZipArchive();
if ($zip->open('example.zip') === TRUE) {
// 검증 로직
$zip->close();
}
zip_open () 과 같은 기능은 간결하고 사용하기 쉽지만, 초기에는 실험적 (또는 권장되지 않음)으로 표시되었지만 Ziparchive 클래스는 더 강력하고 안정적이며 복잡한 Zip 파일에 더 잘 대처할 수 있습니다.
$zip = new ZipArchive();
if ($zip->open('example.zip') === TRUE) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$entryName = $zip->getNameIndex($i);
echo "File: " . $entryName . "\n";
$stream = $zip->getStream($entryName);
if ($stream) {
while (!feof($stream)) {
echo fread($stream, 1024);
}
fclose($stream);
}
}
$zip->close();
}
이 방법은 더 효율적일뿐만 아니라 Zip_entry_read () 읽기 중단 문제가 없으며 생산 환경에서 사용하기에 더 적합합니다.
Zip_Read () 및 Zip_entry_read () 가 함께 사용될 때 자주 발생하는 이유는 내부 포인터 상태에 대한 의존성이 높기 때문입니다. 처리 순서와 리듬을 읽는 데주의를 기울이지 않으면 논리적 장애가 발생하기 쉽습니다. 이 기본 기능 세트 대신 ZipArichive를 사용하는 데 우선 순위가 우선 순위가 높아야하는 것이 좋습니다.
Zip_* 기능 패밀리를 사용해야하는 경우 항상 읽기 순서가 엄격한 지 확인하고 각 항목의 내용을 그대로 읽고 항목을 닫지 않고 다음 라운드에 들어가지 마십시오.