ZipArchive not working

I’ve got a zipped file (called a.xml.zip) that I want to extract and reserve but every time I try it fails. This is the code I’m using to extract and save:

$zip = new ZipArchive;
if ($zip->open('a.xml.zip') === TRUE) {
    $zip->extractTo('/home/domain/public_html/');
    $zip->close();
    echo 'ok';
} else {
    echo 'failed';
}

I’ve tried changing the permissions of the public_html folder but then the site didn’t load. I’ve also tried creating a new folder called feeds and setting the permissions of that to 777 but that still failed.

Instead of echoing “failed”, echo the code of the result. That will at least tell you what the problem is.

$code = $zip->open('a.xml.zip');
if($code === TRUE) {
    //Do your thing
} else {
   echo $code;

}

I change the code to what you suggested:

$zip = new ZipArchive;
$code = $zip->open('a.xml.zip');
if($code === TRUE) {
    $code->extractTo('home/domain/public_html/');
    $code->close();
    echo 'ok';
} else {
   echo $code;
}

and the output I got was 19 - I’m not sure what that means to be honest

Status Code Returns:
ZIPARCHIVE::ER_EXISTS - 10
ZIPARCHIVE::ER_INCONS - 21
ZIPARCHIVE::ER_INVAL - 18
ZIPARCHIVE::ER_MEMORY - 14
ZIPARCHIVE::ER_NOENT - 9
ZIPARCHIVE::ER_NOZIP - 19
ZIPARCHIVE::ER_OPEN - 11
ZIPARCHIVE::ER_READ - 5
ZIPARCHIVE::ER_SEEK - 4

The code is telling you it doesnt think the thing you’re targetting is actually a ZIP Archive.

Aww okay I didn’t realise that. I’m not sure what I’m doing wrong then, this is the full code:

<?php
$url = "http://datafeed.api.productserve.com/datafeed/download/apikey/_api_key_value_/fid/3712/columns/aw_product_id,merchant_product_id,merchant_category,aw_deep_link,merchant_image_url,search_price,description,product_name,merchant_deep_link,aw_image_url,merchant_name,merchant_id,category_name,category_id,delivery_cost,currency,store_price,display_price,data_feed_id,rrp_price,specifications,condition,promotional_text,warranty,merchant_thumb_url,aw_thumb_url,brand_name,brand_id,delivery_time,valid_from,valid_to,web_offer,pre_order,in_stock,stock_quantity,is_for_sale,product_type,commission_group,upc,ean,mpn,isbn,model_number,parent_product_id,language,last_updated,dimensions,colour,keywords,custom_1,custom_2,custom_3,custom_4,custom_5,saving,delivery_weight,delivery_restrictions,reviews,average_rating,number_stars,number_available,rating,alternate_image,large_image,basket_link/format/xml/dtd/1.4/compression/gzip/adultcontent/1/";
$zipFile = "a.xml.zip"; // Local Zip File Path
$zipResource = fopen($zipFile, "w");
// Get The Zip File From Server
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_FILE, $zipResource);
$page = curl_exec($ch);
if(!$page) {
 echo "Error :- ".curl_error($ch);
}
curl_close($ch);


$zip = new ZipArchive;
$code = $zip->open('a.xml.zip');
if($code === TRUE) {
    $code->extractTo('home/domain/public_html/');
    $code->close();
    echo 'ok';
} else {
   echo $code;
}
?>

Well that would be my first suspicion.

Try looking at the zlib functions instead, and see if those will open your file.

http://php.net/gzopen

@coding_noobie, I removed what looked to be your API Key in your code, you may want to be a bit more cautious when you post additional logic.

@cpradio Thank you, I didn’t realise that was there. I’ll be more curious in future

@StarLion I had a look at that and tried the examples there but I got this error: Warning: filemtime(): stat failed for then it output the compressed file too. :frowning:

So a WARNING isnt necessarily a bad thing. Your server’s filesystem failed to return an mtime (last modified time) for the file.

What did you do with the file after gzopen’ing it?

I’ve never done anything like this at all before (I’m just a beginner but have been told to get this done by the weekend :frowning: ) so am not sure I’m doing things right.

What I’m trying to do it save the compressed url on a server as whatever.xml but when I do that it’s compressed.

I can save it or I can uncompress it (using file_get_contents) but I can’t seem to do both.

I tried this (this is when I got the mtime error) but don’t understand half of it:

<?php
$file = "http://datafeed.api.productserve.com/datafeed/download/apikey/api_id_key/fid/columns/aw_product_id,merchant_product_id,merchant_category,aw_deep_link,merchant_image_url,search_price,description,product_name,merchant_deep_link,aw_image_url,merchant_name,merchant_id,category_name,category_id,delivery_cost,currency,store_price,display_price,data_feed_id,rrp_price,specifications,condition,promotional_text,warranty,merchant_thumb_url,aw_thumb_url,brand_name,brand_id,delivery_time,valid_from,valid_to,web_offer,pre_order,in_stock,stock_quantity,is_for_sale,product_type,commission_group,upc,ean,mpn,isbn,model_number,parent_product_id,language,last_updated,dimensions,colour,keywords,custom_1,custom_2,custom_3,custom_4,custom_5,saving,delivery_weight,delivery_restrictions,reviews,average_rating,number_stars,number_available,rating,alternate_image,large_image,basket_link/format/xml/dtd/1.4/compression/gzip/adultcontent/1/";
$fin = fopen($file, "rb");
if ($fin !== FALSE) {
    $fout = fopen("php://output", "wb");
    if ($fout !== FALSE) {
    // write gzip header
    fwrite($fout, "\x1F\x8B\x08\x08".pack("V", filemtime($file))."\0\xFF", 10);
    // write the original file name
    $oname = str_replace("\0", "", basename($file));
    fwrite($fout, $oname."\0", 1+strlen($oname));
    // add the deflate filter using default compression level
    $fltr = stream_filter_append($fout, "zlib.deflate", STREAM_FILTER_WRITE, -1);
    // set up the CRC32 hashing context
    $hctx = hash_init("crc32b");
    // turn off the time limit
    if (!ini_get("safe_mode")) set_time_limit(0);
    $con = TRUE;
    $fsize = 0;
    while (($con !== FALSE) && !feof($fin)) {
        // deflate works best with buffers >32K
        $con = fread($fin, 64 * 1024);
        if ($con !== FALSE) {
        hash_update($hctx, $con);
        $clen = strlen($con);
        $fsize += $clen;
        fwrite($fout, $con, $clen);
        }
    }
    // remove the deflate filter
    stream_filter_remove($fltr);
    // write the CRC32 value
    // hash_final is a string, not an integer
    $crc = hash_final($hctx, TRUE);
    // need to reverse the hash_final string so it's little endian
    fwrite($fout, $crc[3].$crc[2].$crc[1].$crc[0], 4);
    // write the original uncompressed file size
    fwrite($fout, pack("V", $fsize), 4);
    fclose($fout);
    }
    fclose($fin);
}
?>

Thanks for helping me with this.

if the file is small enough,

<?php
 file_put_contents("a_file_name.whateveritis",gzuncompress(file_get_contents($url)));
?>

should work?

That give’s me this error: gzuncompress(): data error

The code I’m now using is:

<?php
$url = "http://datafeed.api.productserve.com/datafeed/download/apikey/api_key/fid/3712/columns/aw_product_id,merchant_product_id,merchant_category,aw_deep_link,merchant_image_url,search_price,description,product_name,merchant_deep_link,aw_image_url,merchant_name,merchant_id,category_name,category_id,delivery_cost,currency,store_price,display_price,data_feed_id,rrp_price,specifications,condition,promotional_text,warranty,merchant_thumb_url,aw_thumb_url,brand_name,brand_id,delivery_time,valid_from,valid_to,web_offer,pre_order,in_stock,stock_quantity,is_for_sale,product_type,commission_group,upc,ean,mpn,isbn,model_number,parent_product_id,language,last_updated,dimensions,colour,keywords,custom_1,custom_2,custom_3,custom_4,custom_5,saving,delivery_weight,delivery_restrictions,reviews,average_rating,number_stars,number_available,rating,alternate_image,large_image,basket_link/format/xml/dtd/1.4/compression/gzip/adultcontent/1/";

 file_put_contents("a_file_name.xml",gzuncompress(file_get_contents($url)));
?>

So i got the wrong function. uncompress is for zlib data. what you want to do is gzdecode() it instead.

Thank you so much that works perfectly now :smile:

I know I’m pushing my luck but is it possible to get this to loop through a database?
IE: it gets the url (the feed_url column) from the database then saves the file with a name set by the filename field in the database?

This is what I’ve got at the moment but I don’t know if it works:

<?php
$query="select feed_url,filename from feeds where atcivie = 1";
    $xml_convert=dbselect( $query,"dbLinkInt" );
	if( is_array( $xml_convert ) ) { 
	foreach( $xml_convert as $key=>$value ) { 
	$url = $value['feed_url'];

 file_put_contents("".$value['filename'].".xml",gzdecode(file_get_contents($url)));
  } } ?>

EDIT: It did work but I initially had a typo in the code. I corrected that and it now works

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.