ZipArchive: `не удалось открыть поток: является каталогом`
Я продолжаю получать failed to open stream: Is a directory
ошибка при попытке разархивировать файл с помощью PHP.
Обычно это проблема с путем назначения.
Тем не менее, в моем случае, назначение в порядке: я могу разархивировать разные файлы, используя один и тот же код, или разархивировать один и тот же файл без PHP.
Документация ZipArchive::extract для не помогла. Также не было других тем в этом сообщении об ошибке.
К вашему сведению, это вопрос и ответы.
Вот исходный код в соответствии с просьбой в комментарии. Я публично поделился ссылкой Dropbox, видя, как этот вопрос зависит от формата ввода ZIP (/
Путь в ZIP-файле, см. ответ.)
/** Config **/
$url = 'https://www.dropbox.com/sh/nx5792q9syppaoo/AAAJZBWlGNAd_EkmQaFvEwe0a?dl=1';
/** Where to save **/
$zipped = ABSPATH . 'tmp/updates/dialogues.zip'; /* Keep in mind this is public-facing. */
$outputdirectory = ABSPATH . 'tmp/updates/testing'; /* The trailing slash is optinal. */
/** Download the dialogues **/
echo 'Fetching the dialogues...<br>';
if ( ( $dropboxfile = fopen( $url, 'r' ) ) === FALSE ) { /* == has higher precedent over = */
echo 'FATAL ERROR: could not open Dropbox file.';
die();
} else if ( file_put_contents( $zipped, $dropboxfile ) === FALSE ) {
echo 'FATAL ERROR: could not copy Dropbox file.';
die();
}
echo "Dialogues downloaded as zip OK. (See {$zipped})<br>";
/** Unzip the dialogues **/
print 'Unzipping...<br>';
$zip = new ZipArchive;
$res = $zip->open( $zipped );
if ( $res === TRUE ) {
// Does not work
// $zip->extractTo( ABSPATH . 'tmp/updates/testing' );
// Works
for( $i = 0 ; $i < $zip->numFiles ; $i++ ) {
if ( $zip->getNameIndex( $i ) != '/' && $zip->getNameIndex( $i ) != '__MACOSX/_' ) {
print $zip->getNameIndex( $i ) . '<br>';
$zip->extractTo( $outputdirectory, array($zip->getNameIndex($i)) );
}
}
$zip->close();
print 'Done unzipping.<br>';
} else {
print 'FATAL ERROR: unzipping failed.';
}
1 ответ
Как оказалось, у меня был /
"папка" внутри архива ZIP.
Это подтверждается просмотром ZIP-архива через командную строку. например, на OS X, используя unzip -vl dialogues.zip
дал мне это:
Archive: dialogues.zip
Length Method Size Ratio Date Time CRC-32 Name
-------- ------ ------- ----- ---- ---- ------ ----
0 Defl:N 2 0% 08-22-15 12:07 00000000 /
2154 Defl:N 1064 51% 06-08-15 15:18 602c6793 dialogue001-en.txt
...
4379 Defl:N 1793 59% 08-21-15 13:56 75e1ef52 dialogue106-en.txt
70 Defl:N 39 44% 08-22-15 12:07 985af458 __MACOSX/_
-------- ------- --- -------
775512 343864 56% 312 files
Файл загружен из Dropbox, и я бы предпочел работать с ним как есть.
Поэтому я просто отфильтровал список файлов, содержащихся в ZIP-архиве, прежде чем распаковать любой данный файл:
print 'Unzipping...<br>';
$zip = new ZipArchive;
$res = $zip->open( $zipped );
if ( $res === TRUE ) {
//
for( $i = 0 ; $i < $zip->numFiles ; $i++ ) {
if ( $zip->getNameIndex( $i ) != '/' && $zip->getNameIndex( $i ) != '__MACOSX/_' ) {
print $zip->getNameIndex( $i ) . '<br>';
$zip->extractTo( $tempdirectory, array($zip->getNameIndex($i)) );
}
}
$zip->close();
print 'Done unzipping.<br>';
} else {
print 'FATAL ERROR: unzipping failed.';
}
Нигде не видел этого документально и потратил на это почти час. Надеюсь, это кому-нибудь поможет.
Я до сих пор не ясно, является ли /
ссылка внутри ZIP-файла верна. (Комментарии приветствуются.)