PHP + ZipArchive + Russian language - php

i have the followed code
$zip = new ZipArchive;
$res = $zip->open('tmp/articles.zip');
if ($res === TRUE) {
$zip->extractTo('tmp/');
$zip->close();
}
It works fine for archives with english filenames, but if i made archieve with russian characters, i have unreadable filenames. What should I do?
UPD: It doesn't work correctly when i use "unzip" from bash too.

Look at this code:
$z = new ZipArchive();
$res = $z->open('C:\Temp\Temp.zip');
if ($res)
{
$z->extractTo('C:\Temp\Temp');
$z->close();
}
$files = scandir('C:\Temp\Temp');
foreach ($files as $filename)
{
print iconv('cp866', 'utf-8', $filename).PHP_EOL;
}
This code prints normal filenames.
So, WinRar uses old ms-dos charset 'cp866' for Cyrillic.
Hope you can change this code to create rename algorithm :)

This method not always works. I've found myself installing an external library like 7zip to do this job and it soves the problem. It's hard to know the encoding charset used for a file in windows.
In my case I had to do this for avoiding errors in filenames after extraction.
Here are my variables:
// Extract file.
$tmp_dir = uniqid();
$zip_uri = "test.zip";
$destination_dir = "C:\\Users\\user\\AppData\\Local\\Temp\\$tmp_dir";
This is the ZipArchive method:
$zip = new ZipArchive();
$zip->open($zip_uri);
if (!$zip->extractTo($destination_dir)) {
die("Error extracting files.");
}
$zip->close();
This method not always worked, but the following does work beautifully (using 7Zip):
exec("C:\\7zip\\7za.exe e $zip_uri -o$destination_dir");
Hope it helps somebody to not spend hours trying with to figure out the encoding charset of a particular zipped file.

Related

PHP : Why extracted zip filename is changed for Japanese characters in lhaplus software?

I am working on zip file creation and downloading using PHP (Laravel).
Zip created and download works well. But the problem is in lhaplus software. When extracting the zip file using lhaplus, it has been changing the file name. But in another extractor like 7zip, WinRAR works well. In lhaplus software shows "03510063220_00016501tñ+sÉìtñ+sÉì_spt.pdf" but it should be 03510063220_00016501社名社名_spt.pdf.
Please help in this case. Any suggestion is appreciated.
The code is given below:
$date_time = static::getCurrentTime();
$zip_name = $date_time."_spt";
$zip = new ZipArchive;
if(!file_exists('zip/downloadedZip')){
mkdir('zip/downloadedZip',0777,true);
}
$zipFileName = 'zip/downloadedZip/'.$zip_name.'.zip';
if ($zip->open(public_path($zipFileName), ZipArchive::CREATE) === TRUE){
$fileName = "pdf/03510063220_00016501社名社名_spt.pdf";
$baseName = "03510063220_00016501社名社名_spt.pdf";
if (!$zip->addFile($fileName, mb_convert_encoding($baseName, "SJIS", "UTF-8"))) {
throw new \RuntimeException(sprintf('Add file failed: %s', $fileName));
}
$zip->close();
}
return URL($zipFileName);

php zip extract makes file empty

Ok so this is making me crazy... I abstracted the code because it comes from a big project. But in my project I ended up commenting everything and only have this left which is still causing problems and I have no idea why.
$f = fopen('tmp/'.$name.'.zip', 'wb');
fwrite($f, $myzip);
fclose($f); //I can open this file manually and everything is fine
$zip = new ZipArchive;
$res = $zip->open('tmp/'.$name.'.zip'); //$res is "1"
$zip->extractTo("final/" . $unique);
$zip->close();
As you can see I write a zip file in /tmp, at this point, I can open the file manually and it contains all files with the correct size.
But after I extract it to /final, for some reason some files are empty...
Any idea what could cause this?
You can do this way by throwing Exception at zip archive open time,
function DecompressFile()
{
$zip = new ZipArchive;
if ($zip->open('tmp/'.$name.'.zip') === TRUE) {
$zip->extractTo("final/" . $hwidDir);
$zip->close();
return 'completed';
}
else {
throw new Exception ("Decompress operation from ZIP file failed.");
}
}

How to add a file from web to a zip file on my server using php?

Imagine there is a picture at http://example.com/icon.jpg and I want to add it to a zip file on my own sever named "Stack.zip" using php. This is my code, but it doesn't work.
$url="http://example.com/icon.jpg"
$zip = new ZipArchive;
echo $zip->open("Stack.zip");
$zip->addFile($url);
$zip->close();
P.S. I was able to do it with local files, but I had no success on doing it with internet addresses. So that's why I asked this question.
From the PHP manual: http://php.net/manual/en/ziparchive.addfile.php
(PHP 5 >= 5.2.0, PHP 7, PECL zip >= 1.1.0)
This assumes you want to add to an existing zip file on your server.
$url = 'https://www.stackoverflowbusiness.com/hubfs/logo-so-color.png?t=1499443352566';
$local_path = '/your/local/folder/';
$img = 'icon.jpg';
file_put_contents($local_path.$img, file_get_contents($url));
$zip = new ZipArchive;
if ($zip->open($local_path.'Stack.zip') === TRUE) {
$zip->addFile($local_path.$img, $img);
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
If you want to keep the same folder structure as the original source file, change this line ..
$zip->addFile($local_path.$img, $img);
...to this...
$zip->addFile($local_path.$img);
If you want the same script to create the zip, you can find a PHP function here: Add files to the zip

Yii2 : Arabic language filename not support in `addFromString` of ZipArchive

I have used ZipArchive for creating zip. but i have problem with filename assign in Arabic language that is not supported.
I want to get filename like 21_بينل.pdf but i getting 21_.pdf.
I have refer following question.
PHP ZipArchive non-English filenames return funky filenames within archive
but still not working.
My sample code:
<?php
$zip = new ZipArchive;
$res = $zip->open('test.zip', ZipArchive::CREATE);
$fileName = $v->certificateLetter->fileName.'/'.$v->dslStu->stu_unique_id.'_'.'بينل';
$zip->addFromString($fileName.'.pdf', $letterString);
$zip->close();
?>
Thanks in Advance.
Try this:
$zip = new ZipArchive;
$res = $zip->open('test.zip', ZipArchive::CREATE);
$fileName = $v->certificateLetter->fileName.'/'.$v->dslStu->stu_unique_id.'_'.'بينل';
iconv('CP1256', 'utf-8', $fileName).PHP_EOL;
$zip->addFromString($fileName.'.pdf', $letterString);
$zip->close();

PHP Zip Archive - open or extractTo is not working

I'm completely at a loss for explaining why this isn't working. HELP!
$archive = "x.zip";
$zip = new ZipArchive();
$res = $zip->open($archive);
if ($res === 'TRUE') {
$unzip_success= $zip->extractTo('/temp/', "inscriptions.txt")
$zip->close();
}
the target dir "temp" is "0777" permissions
the code obtained from $res is "11" and not "TRUE" as required by the documentation on PHP.net
note: must put the full url for $archive and the first argument of extractTo
if nothing works then check if your server is linux.
if its linux you can run unzip command to unzip your file via php's system/exec function.
i.e
system("unzip archive.zip");
to extract specific file you can check man docs for unzip. many times due to server parameters zip library doesn't work as expected in that cases i switch back to linux commands.
The problem is that you are quoting TRUE, which is a keyword and should be left without single quotes. Plus, you could check if the file exists in the zip archive prior to its extraction with locateName:
$archive = "x.zip";
$zip = new ZipArchive();
$res = $zip->open($archive);
if ($res === true && $zip->locateName('inscriptions.txt') !== false) {
$unzip_success= $zip->extractTo('/tmp/', "inscriptions.txt");
$zip->close();
}
ZipArcive::extractTo is case-sensitive. If file's name to be extracted do not meet zipped one exactly, the method returns false.
I faced the same problem, I have fixed this :)
Use $_SERVER['DOCUMENT_ROOT'] for url.
My code (codeigniter):
$this->load->library('unzip');
$file = $this->input->GET('file');
$this->unzip->extract($_SERVER['DOCUMENT_ROOT'].'/TRAS/application/uploads/' . $file,$_SERVER['DOCUMENT_ROOT'].'/TRAS/application/views/templates/' . $file);
If $res is equal to 11, that means that ZipArchive can't open the specified file.
To test this:
$archive = "x.zip";
$zip = new ZipArchive();
$res = $zip->open($archive);
if($res == ZipArchive::ER_OPEN){
echo "Unable to open $archive\n";
}
Adding document root is what worked for me as well. here is my code
$zip = new ZipArchive;
if ($zip->open($_SERVER['DOCUMENT_ROOT'].'/'.$folder.$file_path) === TRUE) {
$zip->extractTo($_SERVER['DOCUMENT_ROOT'].'/$folder');
$zip->close();
echo 'ok';
}
I meet same problem, but I can open the zip file, it returns true after open.
My issue is I got false after $zip->extractTo().
I finally success after delete files named in CHINESE (NO-ENGILISH) in the zip file.
I had the same problem on Windows 10. The only solution I found was just to try extractTo twice, even though the open() was successful:
$zip = new ZipArchive;
if ($open === true) {
$result = $zip->extractTo($destination);
if ($result === false) {
$result = $zip->extractTo($destination);
}
$zip->close();
}
The fact that the second extractTo() works (with no intervening action) would seem to indicate that there's nothing wrong with the archive or the destination directory.

Categories