I wrote this code to create a ZIP file and to save it. But somehow it just doesn't show any error, but it doesn't create a ZIP file either. Here's the code:
$zip = new ZipArchive;
$time = microtime(true);
$res = $zip->open("maps/zips/test_" . $time . ".zip", ZipArchive::CREATE);
if ($res === TRUE) {
echo "RESULT TRUE...";
$zip->addFile("maps/filename.ogz","filename.ogz"); //Sauerbraten map format
$zip->addFromString('how_to_install.txt', 'Some Explanation...');
$zip->close();
$zip_created = true;
echo "FILE ADDED!";
}
What am I doing wrong, and how can I fix it?
Probably apache or php has not got permissions to create zip archives in that directory. From one of the comments on ZipArchice::open:
If the directory you are writing or
saving into does not have the correct
permissions set, you won't get any
error messages and it will look like
everything worked fine... except it
won't have changed!
Instead make sure you collect the
return value of ZipArchive::close().
If it is false... it didn't work.
Add an else clause to your if statement and dump $res to see the results:
if($res === TRUE) {
...
} else {
var_dump($res);
}
There are 2 cases when zip doesn't generate the error.
Make sure every file you are adding to the zip is valid. Even if
one file is not available when zip->close is called then the archive
will fail and your zip file won't be created.
If your folder doesn't
have write permissions zip will not report the error. It will finish
but nothing will be created.
I had an exactly same issue, even when with full writing/reading permissions.
Solved by creating the ".zip" file manually before passing it to ZipArchive:
$zip = new ZipArchive;
$time = microtime(true);
$path = "maps/zips/test_" . $time . ".zip"
touch($path); //<--- this line creates the file
$res = $zip->open($path, ZipArchive::CREATE);
if ($res === TRUE) {
echo "RESULT TRUE...";
$zip->addFile("maps/filename.ogz","filename.ogz"); //Sauerbraten map format
$zip->addFromString('how_to_install.txt', 'Some Explanation...');
$zip->close();
$zip_created = true;
echo "FILE ADDED!";
}
Check out that each of your file exists before calling $zip->addFile otherwise the zip won't be generated and no error message will be displayed.
if(file_exists($fichier->url))
{
if($zip->addFile($fichier->url,$fichier->nom))
{
$erreur_ouverture = false;
}
else
{
$erreur_ouverture = true;
echo 'Open error : '.$fichier->url;
}
}
else
{
echo 'File '.$fichier->url.' not found';
}
break it into steps.
if ($res === TRUE) {
check if file_exist
check if addFile give any error
}
if($zip->close())
{
$zip_created = true;
echo "FILE ADDED!"
}
Check the phpinfo for zip is enabled or not :)
One of the reasons for zip file is not created is due to missing check if you are adding file and not a directory.
if (!$file->isDir())
I found the solution here.
Related
I'm trying to create a script that will send across files from one server to another. My script successfully does that as well as checks if the file has something in it or not. My next step is to check whether the file already exists on the server; if the file already exists it does not send and if it does not exist, it does send.
I've tried a few different things and can't seem to get my head around it. How can I get it to check whether the file already exists or not? Any help would be appreciated!
(I had a look at some similar questions but couldn't find anything specific to my issue.)
require('constants.php');
$files = $sftp->nlist('out/');
foreach($files as $file) {
if(basename((string) $file)) {
if(strpos($file,".") > 1) { //Checks if file
$filesize = $sftp->size('out/'.$file); //gets filesize
if($filesize > 1){
if (file_exists('import/'.$file)){
echo $file.' already exists';
}
else {
$sftp->get('out/'.$file, 'import/'.$file); //Sends file over
//$sftp->delete('out/'.$file); //Deletes file from out folder
}
else {
echo $file. ' is empty.</br>';
}
}
}
}
}
EDIT: To try and get this to work, I wrote the following if statement to see if it was finding the file test.php;
if (file_exists('test.txt')){
echo 'True';
} else {
echo 'False';
}
This returned true (a good start) but as soon as I put this into my code, I just get a 500 Internal Server Error (extremely unhelpful). I cannot turn on errors as it is on a server that multiple people use.
I also tried changing the file_exists line to;
if (file_exists('test.txt'))
in the hopes that would work but still didn't work.
Just to clarify, I'm sending the files from the remote server to my local server.
There is a closing curly brace missing right before the second else keyword.
Please try to use a code editor with proper syntax highlighting and code formatting to spot such mistakes on the fly while you are still editing the PHP file.
The corrected and formatted code:
require('constants.php');
$files = $sftp->nlist('out/');
foreach ($files as $file) {
if (basename((string)$file)) {
if (strpos($file, ".") > 1) { //Checks if file
$filesize = $sftp->size('out/' . $file); //gets filesize
if ($filesize > 1) {
if (file_exists('import/' . $file)) {
echo $file . ' already exists';
} else {
$sftp->get('out/' . $file, 'import/' . $file); //Sends file over
}
} else {
echo $file . ' is empty.</br>';
}
}
}
}
Your code checks the file exist in your local server not in remote server.
if (file_exists('import/'.$file)){
echo $file.' already exists';
}
You need to check in remote server using sftp object like
if($sftp->file_exists('import/'.$file)){
echo $file.' already exists';
}
Edit:
Add clearstatcache() before checking file_exists() function as the results of the function get cached.
Refer: file_exists
So, I creating a zip file with a password:
function createZip($fileName,$fileText,$zipFileName,$zipPassword)
{
shell_exec('zip -P '.$zipPassword.' '.$zipFileName.'.zip '.$fileName);
unlink($fileName);
return file_exists($zipFileName.'.zip');
}
$filex = "/backup/home/fyewhzjp/long_location_of_a_file/temp/data/map10/data.txt";
// $file_content = 'test';
$archive = "/backup/home/fyewhzjp/long_location_of_a_file/temp/data/map10/archive";
createZip($filex,$file_content,$archive,$pass);
And it works. I'm getting a archive.zip in my /temp/data/map folder on the website. But, when I open my archive I can see a bunch of folders, and data.txt at the end, let's say it will be
/backup/home/fyewhzjp/long_location_of_a_file/temp/data/map10/data.txt
So, I need to leave only data.txt in my folder, without other folders. How can I do it?
If anyone will face the same problem as I did, here is the solution:
Just add -jrq after zip in shell_exec like this:
shell_exec('zip -jrq -P '.$zipPassword.' '.$zipFileName.'.zip '.$fileName);
After that, full path will be ignored.
In addition to #Script47...
Pure PHP Available as of PHP 7.2.0 and PECL zip 1.14.0, respectively, if built against libzip ≥ 1.2.0.
<?php
$zip = new ZipArchive;
$res = $zip->open('test.zip', ZipArchive::CREATE);
if ($res === TRUE) {
// Add files
$zip->addFromString('test.txt', 'file content goes here');
$zip->addFile('data.txt', 'entryname.txt');
// Set global (for each file) password
$zip->setPassword('your_password_here');
// This part will set that 'data.txt' will be encrypted with your password
$zip->setEncryptionName('data.txt', ZipArchive::EM_AES_128); // Have to encrypt each file in zip
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
?>
Rather than using shell_exec why don't you just use the ZipArchive class with the functions ZipArchiveOpen::open and ZipArchive::setPassword, it seems that that would make things a lot easier.
<?php
$zip = new ZipArchive;
$res = $zip->open('test.zip', ZipArchive::CREATE);
if ($res === TRUE) {
$zip->addFromString('test.txt', 'file content goes here');
$zip->addFile('data.txt', 'entryname.txt');
$zip->setPassword('your_password_here');
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
?>
Note:
This function only sets the password to be used to decompress the archive; it does not turn a non-password-protected ZipArchive into a password-protected ZipArchive.
I am trying to extract a zip-file using a wildcard. The point of this is to find out the said file. The file has a changing name after today's date when I download it: test-18-02-2016.zip. I tried like this:
<?php
$myFile = 'C:/Users/Acer/Downloads/test*.zip';
$zip = new ZipArchive();
if($zip->open($myFile) === true) {
$zip->extractTo('C:/Users/Acer/Downloads/');
$zip->close();
echo 'ok';
} else {
echo 'NOT ok!';
}
I am getting NOT ok ..of course, but when i switch on to test-18-02-2016.zipI get ok.
Any help to figure out why and how to resolve this is very appreciate it.
A ZipArchive can only represent one file at a time. If you absolutely must use wildcards, consider passing the wildcard string into glob() and using the results it returns.
For example:
$myFileList = glob('C:/Users/Acer/Downloads/test*.zip');
foreach ($myFileList as $myFile) {
echo 'Unzipping ' . $myFile . PHP_EOL;
$zip = new ZipArchive();
if($zip->open($myFile) === true) {
$zip->extractTo('C:/Users/Acer/Downloads/');
$zip->close();
echo 'ok';
} else {
echo 'NOT ok!';
}
}
I don't see anything in the documentation that says ZipArchive->open accepts a wildcard path in this way. Besides, what would happen if several files matched?
Instead, find the file you want. If it's today's date...
$myFile = 'C:/Users/Acer/Downloads/test-'.date("d-m-Y").'.zip';
I am trying to debug this script to run on localhost. $zip->status returns 0, which, according to The Manual means "no error", yet file_exists() still returns false.
I checked manually and the file does in fact not exist. I am running WAMP on localhost.
Why is this behaving this way? How can I fix it?
Here is my exact code:
$destination = "C:\wamp\www\temp\temp.zip";
$zip = new ZipArchive();
echo var_dump($zip);
echo "<br />";
$zzz = $zip->open($destination, ZipArchive::CREATE);
if($zzz === true) {
echo "created archive<br />";
}else{
//Var dump says it's true.. is that not a contradiction??
echo var_dump($zzz)."<br />Couldn't create zipArchive<br />";
}
//add the files
foreach($_SESSION['images'] as $file) {
$zip->addFile($file);
}
echo "Files ".$zip->numFiles."<br />Status ".$zip->status."<br />";
$zip->close();
if(!file_exists($destination)){
echo "destination doesnt exist";
}
And here is the output of that page..
object(ZipArchive)[1]
public 'status' => int 0
public 'statusSys' => int 0
public 'numFiles' => int 0
public 'filename' => string '' (length=0)
public 'comment' => string '' (length=0)
created archive
Files 16
Status 0
destination doesnt exist
Update: After some discussion in chat we found out, that $_SESSION['images'] contains http:// urls but ZipArchive itself does not support adding files from remote sources. If you want to add remote images you'll have to download them before. So we've changed the addFile() related part to:
//add the files
foreach($images as $file) {
$tmpname = tempnam(sys_get_temp_dir(), 'test');
file_put_contents($tmpname, file_get_contents($file));
$zip->addFile($tmpname, basename($file));
unlink($tmpname);
}
Also there is is a logic error, or better, a typo. Replace
$zzz = $zip->open($destination, ZipArchive::CREATE);
if($zzz !== true) {
echo "created archive<br />";
} ...
by
$zzz = $zip->open($destination, ZipArchive::CREATE);
if($zzz === true) {
echo "created archive<br />";
} ...
Further note, that the zip is created in memory and will be written to disk not until calling ZipArchive::close(). Check the first comment on the manual page:
If you have created a zip file and added a file to it without error, yet the ZipArchive::close call fails (with ER_TMPOPEN: "Failure to create temporary file") and the zip file is not created, check to see if your ZipArchive::open call specifies a pathname containing nonexisting directories. If you expect a containing hierarchy of one or more directories, you must create them yourself before using using ZipArchive. You can write a simple function to recurse using dirname to find each parent directory, creating those that don't exist by using mkdir when leaving the recursion.
Probably because you have if($zzz !== true) when it should be if($zzz === true). xD
When the tmp directory is full, file_put_contents returns FALSE but the file is created with size of 0. file_put_contents should either complete the creation of the file or have no effect at all. For example:
$data = 'somedata';
$temp_name = '/tmp/myfile';
if (file_put_contents($temp_name, $data) === FALSE) {
// the message print that the file could not be created.
print 'The file could not be created.';
}
But when I go to the tmp directory, I can find the file "myfile" created in the directory with size 0. This makes it difficult to maintain. The file should not be created and I would like to see a message or warning the the tmp directory is full. Am I missing anything? And is this normal behaviors?
You are probably missing that if you do the error messages, you need to take care of that scenario, too:
$data = 'somedata';
$temp_name = '/tmp/myfile';
$success = file_put_contents($temp_name, $data);
if ($success === FALSE)
{
$exists = is_file($temp_name);
if ($exists === FALSE) {
print 'The file could not be created.';
} else {
print 'The file was created but '.
'it could not be written to it without an error.';
}
}
This will also allow you to deal with it, like cleaning up if the transaction to write to the temporary file failed, to reset the system back into the state like before.
The problem is that file_put_contents will not necessarily return a boolean value and therefore your condition may not be appropriate you could try:
if(!file_put_contents($temp_name, $data)){
print 'The file could not be created.';
if(file_exists ($temp_name))
unlink($temp_name);
}
hi bro i found the Solution,
i know its old but its maybe help other people like me,
i was search about this code long time.
$data = 'somedata';
$temp_name = '/tmp/myfile';
$success = file_put_contents($temp_name, $data);
if (!$success){
$exists = is_file($temp_name);
if (!$exists) {
print 'The file could not be created.';
} else {
print 'The file was created but '.
'it could not be written to it without an error.';
}
}