7

I have the following code:

$ipaFile= '/path/file.ipa';
$iconFilePath = "Payload/myapp.app/AppIcon40x40@2x.png"; // the pathway to my image file if the ipa file is unzipped.
$iconFile = "AppIcon40x40@2x.png";
$iconSaveFile = '/path/';

$zip = new ZipArchive();

if ($zip->open($ipaFile) === TRUE) {
    if($zip->locateName($iconFilePath) !== FALSE) {

     $zip->extractTo($iconSaveFile, $iconFile);

    }
}

My purpose is to dive into this zipped file and only pull out an image file. The code as is creates a a new image file in the directory I want it to go into (The file it creates has the right name and extension, but it is blank, 0 bytes). If I change $iconFile to iconFilePath then PHP correctly extracts the whole pathway. At the end of the pathway is the file (only the single file is extracted) I want, and it is correctly extracted. However, I don't want the folders preceding the file to be extracted, just the one file.

SO, in summary, I can correctly extract the entire zip archive, I can correctly extract the single file, but the file pathway to get to the file is also extracted, but I CANNOT correctly extract the single file all by itself.

I've done lots of searching on it and I can't spot my error. Thanks for your help.

miken32
  • 42,008
  • 16
  • 111
  • 154
Pete_1
  • 981
  • 3
  • 14
  • 23

2 Answers2

7

ZipArchive::extractTo() extracts the whole folder structure into the filesystem; you should use ZipArchive::getFromName() instead. According to the documentation, it's what you're looking for:

Returns the entry contents using its name


$ipaFile= '/path/file.ipa';
// the pathway to my image file if the ipa file is unzipped.
$iconFilePath = "Payload/myapp.app/AppIcon40x40@2x.png";
$iconFile = "AppIcon40x40@2x.png";
$iconSaveFile = '/path/';

$zip = new ZipArchive();

if ($zip->open($ipaFile) === true) {
    if ($iconData = $zip->getFromName($iconFilePath)) {
        file_put_contents("$iconSaveFile$iconFile", $iconData);
    }
}
miken32
  • 42,008
  • 16
  • 111
  • 154
1

There are quite a few ways to individually extract and/or read, then write files that reside within a .zip archive. getStream is one possible way:

$iconSaveFile = "/path/";              // external path
$ipaFile = "file.ipa";                 // zipped file
$iconFilePath = "Payload/myapp.app/";  // archive path
$iconFile = "AppIcon40x40@2x.png";     // file to extract

$iconData = '';
$zp = new ZipArchive();

if ($zp->open($iconSaveFile . $ipaFile)) {
    $fp = $zp->getStream($iconFilePath . $iconFile);
    if(!$fp) exit("failed\n");
    while (!feof($fp)) {
        $iconData .= fread($fp, 8192);
    }
    fclose($fp);
    file_put_contents($iconSaveFile . $iconFile, $iconData);
}

Using getStream we are able to read into a buffer only what we're really after, then write the data to a new .png to our new path. Simple, and quick.

l'L'l
  • 44,951
  • 10
  • 95
  • 146