Cannot extract zip file in php, no feedbackor error - php

I am retrieving my google map in a kmz format like this:
file_put_contents($_SERVER['DOCUMENT_ROOT'].'/temp/map.kmz', file_get_contents('https://mapsengine.google.com/map/kml?mid=zLucZBnh_ipg.kS906psI1W9k') );
$zip = new ZipArchive;
$res = $zip->open($_SERVER['DOCUMENT_ROOT'].'/temp/map.kmz');
if ($res === true)
{
trace("Number of files: $res->numFiles".PHP_EOL);
for( $i = 0; $i < $res->numFiles; $i++ )
{
$stat = $res->statIndex( $i );
print_r( basename( $stat['name'] ) . PHP_EOL );
}
}
But no files are showing and $zip->extractTo() is not working either. The file is downloaded on the server and I can extract it manually though. I have tried renaming the file to .zip or .kmz, still not working. I have opened the map.kmz file in Winrar and it does indeed say that it is a zip file format.
Any idea why it's not working? Do I need some special permissions to read the number of files or extract?

Check your file types .mkz and .kmz.
file_put_contents($_SERVER['DOCUMENT_ROOT'].'/temp/map.mkz',
file_get_contents('https://mapsengine.google.com/map/kml? mid=zLucZBnh_ipg.kS906psI1W9k') );
$zip = new ZipArchive;
$res = $zip->open($_SERVER['DOCUMENT_ROOT'].'/temp/map.kmz');

Got tired of the damn class not working, tried this method instead and it works:
$data = file_get_contents("https://mapsengine.google.com/map/kml?mid=zLucZBnh_ipg.kS906psI1W9k");
file_put_contents($_SERVER['DOCUMENT_ROOT'].'/temp/kmz_temp', $data);
ob_start();
passthru("unzip -p {$_SERVER['DOCUMENT_ROOT']}/temp/kmz_temp");
$xml_data = ob_get_clean();
header("Content-type: text/xml");
echo $xml_data;
exit();

Related

How to save the image fetched from DOCX by PHP using ZipArchive

Brief description: I have a Docx file. I have done a simple code in PHP which extracts the images in that file and display it on the page.
What I want to achieve: I want that these images should be saved beside my php file with the same name and format.
My folder has sample.docx (which has images), extract.php (which extracts the images from docx) and display.php
Below is the code of extract.php
<?php
/*Name of the document file*/
$document = 'sample.docx';
/*Function to extract images*/
function readZippedImages($filename) {
/*Create a new ZIP archive object*/
$zip = new ZipArchive;
/*Open the received archive file*/
if (true === $zip->open($filename)) {
for ($i=0; $i<$zip->numFiles;$i++) {
/*Loop via all the files to check for image files*/
$zip_element = $zip->statIndex($i);
/*Check for images*/
if(preg_match("([^\s]+(\.(?i)(jpg|jpeg|png|gif|bmp))$)",$zip_element['name'])) {
/*Display images if present by using display.php*/
echo "<image src='display.php?filename=".$filename."&index=".$i."' /><hr />";
}
}
}
}
readZippedImages($document);
?>
display.php
<?php
/*Tell the browser that we want to display an image*/
header('Content-Type: image/jpeg');
/*Create a new ZIP archive object*/
$zip = new ZipArchive;
/*Open the received archive file*/
if (true === $zip->open($_GET['filename'])) {
/*Get the content of the specified index of ZIP archive*/
echo $zip->getFromIndex($_GET['index']);
}
$zip->close();
?>
How can I do that?
I not sure that you need to open the zip archive multiple times like this - especially when another instance is already open but I'd be tempted to try something like the following - I should stress that it is totally untested though.
Updated after testing:
There is no need to use display.php if you do like this - seems to work ok on different .docx files. The data returned by $zip->getFromIndex yields the raw image data ( so I discovered )so passing that in a query string is not possible due to the length. I tried to avoid opening/closing the zip archive unnecessarily hence the approach below which adds the raw data to the output array and the image is then displayed using this base64 encoded data inline.
<?php
#extract.php
$document = 'sample.docx';
function readZippedImages($filename) {
$paths=[];
$zip = new ZipArchive;
if( true === $zip->open( $filename ) ) {
for( $i=0; $i < $zip->numFiles;$i++ ) {
$zip_element = $zip->statIndex( $i );
if( preg_match( "([^\s]+(\.(?i)(jpg|jpeg|png|gif|bmp))$)", $zip_element['name'] ) ) {
$paths[ $zip_element['name'] ]=base64_encode( $zip->getFromIndex( $i ) );
}
}
}
$zip->close();
return $paths;
}
$paths=readZippedImages( $document );
/* to display & save the images */
foreach( $paths as $name => $data ){
$filepath=__DIR__ . '/' . $name;
$dirpath=pathinfo( $filepath, PATHINFO_DIRNAME );
$ext=pathinfo( $name, PATHINFO_EXTENSION );
if( !file_exists( $dirpath ) )mkdir( $dirpath,0777, true );
if( !file_exists( $filepath ) )file_put_contents( $filepath, base64_decode( $data ) );
printf('<img src="data:image/%s;base64, %s" />', $ext, $data );
}
?>

PHP | Get file that is most similar to string

Currently I have a zip folder with files in it that I do not know the filenames of. The only thing I know is that one filename is very similar to a string a have. It is literally one character off.
What I am trying to do right now is to extract only the file that is the most similar to the string I have. To extract only one file from a zip I use the following code that works:
$zip = new ZipArchive;
if ($zip->open('directory/to/zipfile') === TRUE)
{
$zip->extractTo('directory/where/to/extract', array('the/filename/that/is/most/similair/most/go/here'));
$zip->close();
echo 'ok';
}
else
{
echo 'failed';
}
I know that to check the similarity of strings I can use the following code:
$var_1 = 'PHP IS GREAT';
$var_2 = 'WITH MYSQL';
similar_text($var_1, $var_2, $percent);
And based on the percentage I can tell which file is most similar to the string I have. The only thing I am worried about is that ZipArchieve doesn't have a function to retrieve files from a zip without knowing the exact filename.
So I was wondering if there is a way to retrieve a single file from a zip based on a string that is most similar to the filename.
This comment in the docs mentions how to list the files in a zip archive, so, all you would have to do is loop through all the file names and find the one that closest matches the string you have and then extract it.
$search = 'Closefilename.doc';
$za = new ZipArchive();
$za->open('theZip.zip');
$similarity = 0;
for( $i = 0; $i < $za->numFiles; $i++ ){
$stat = $za->statIndex( $i );
similar_text($stat['name'], $search, $sim);
if ($sim > $similarity) {
$similarity = $sim;
$filename = $stat['name'];
}
}
// Now extract $filename;
Try this code:
// Your Zip File path
$zip = zip_open( $fileName );
if ( is_resource( $zip ) ) {
while( $zip_entry = zip_read( $zip ) ) {
$zip_entry_string = zip_entry_read ( $zip_entry );
// Compare here with similar_text
// If success you can write this string to file
}
}
zip_close( $zip );
?>

Unzip php files

I'm trying to extract a zip file witch contains php files.
Taking for example a zip name 'test.zip' and inside, a zip.php file with this code:
<?php
class php{
}
?>
I've tried with two differents snippets to extract the zipe file:
$zip = zip_open ( 'test.zip' );
while($file = zip_read($zip)){
$archivo = (zip_entry_name($file));
zip_entry_open($zip, $file);
$contenido = zip_entry_read($file);
$fopen = fopen($archivo,'w+');
fwrite($fopen, $contenido);
}
<?php
$zip = new ZipArchive;
$res = $zip->open('test.zip');
if ($res === TRUE) {
$zip->extractTo('./');
$zip->close();
echo 'ok!';
} else {
echo 'ko!';
}
?>
But in both cases, the result is always the same:
<?php
class phpclass{
function clase(){
}
}
?>
The file extracted is twice longer, and has twice of empty breaklines than original.
Is there anyway to extract an identical copy of files contained in the zip file?
Please replace this:
$fopen = fopen($archivo,'w+');
... with this:
$fopen = fopen($archivo,'w+b');
The b flag stands for "binary" and disables line feed conversion. Flags are described in the fopen() manual page.

Delete file from directory inside zip

I have a zip file called project.zip with the following structure:
project.zip
\project
\file.pdf
I need to delete file.pdf. I tried the following code but I'm getting an error.
Thanks
$zip = new ZipArchive();
$zip_name = 'path\to\project.zip';
$zip->open( $zip_name );
$zip->deleteName( 'project\file.pdf' );
$zip->close();
I Also tried with a leading backslash but with no success,
$zip->deleteName( 'prject\file.pdf' );
It's weird, but it seems you need to include the base name of the zip file in the filename like this:
$zip->deleteName( 'project/project/file.pdf' );
Try something like this to see what the filename values look like in your zip:
for ($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
echo $filename . "<br>";
}
Also don't forget to close the zip when you are done
$zip->close();
use forward slashes :
$zip->deleteName( 'project/file.pdf' );

PHP Word File line counter

I need to make a PHP function that will count the number of lines in a Word File (.doc, docx)
This code does not seem to work correctly for me :
$name = 'test.doc';
$line_count = count(file($name));
echo $line_count
My guess is that this script does not work well with .doc or .docx but works good in .txt files. Are there any alternatives available out there? Tnx!
Only .docx can be opened with simple PHP as it is a zip file:
$zip = new ZipArchive;
if ($zip->open('test.docx') === TRUE) {
$xml = $zip->getFromName('docProps/app.xml');
$zip->close();
} else {
$xml = false;
}
if($xml){
$xml = simplexml_load_string($xml);
echo $xml->Lines;
}

Categories