I've been at this for a while. This actually worked one time, then never again. it simply does not create the zip file. The file does exist.
$zip = new ZipArchive();
$filename = "./test" . time() .".zip";
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
exit("cannot open <$filename>\n");
}
$thisdir = "$_SERVER[DOCUMENT_ROOT]/zip";
$zip->addFile($thisdir . "/trash-icon.png", "/gabage.png");
echo "numfiles: " . $zip->numFiles . "\n";
echo "status:" . $zip->status . "\n";
$zip->close();
If I add something like
$zip->addFromString("testfilephp.txt", "#1 This is a test string added as testfilephp.txt.\n");
it creates the zip with the txt file in it.. but a no go for anytype of existing file.
The ZipArchive::addFile() method accepts the path to the file as its first parameter, but not all paths are created equal. addFile() method silently rejects the file and you never know what went wrong. As can be derived from the question, an alternative approach would be:
// $zip->addFile($file);
$content = file_get_contents($file);
$zip->addFromString(pathinfo ( $file, PATHINFO_BASENAME), $content);
In addition to getting the code working, file_get_contents() also generates decent error messages.
The ZipArchive::addFile() method accepts the path to the file as its first parameter.
Here, you are using :
$zip->addFile("/trash-icon.png", "/gabage.png");
Which means you are trying to add the /trash-icon.png file to your archive.
Are you sure this file exists ?
Note there is a / at the beginning of that file's path, which indicates it's an absolute path.
Maybe that / should be removed, to use a relative path ?
I had similar kind of issue and it was related with the file that I was going to add to the zip archive.
Before adding file to zip archive, it's always better to check if the file exists.
$thisdir = "$_SERVER[DOCUMENT_ROOT]/zip";
if (file_exists($thisdir . "/trash-icon.png")) {
$zip->addFile($thisdir . "/trash-icon.png", "/gabage.png");
}
Related
Helo.
I have a question. Just now, when I tried to delete a picture using only unlink without the # symbol, it returned the "unlink is a directory" error. What is the reason that causes it? I received an advice that using the symbol # to the unlink is a bad practice, but somehow this is the method that works.
$file = $request->file('image');
if($file->getSize() < 2048000){
$path = storage_path('app/public/' . $event->img);
if (file_exists($path)) {
unlink($path);
}
$filename = Str::uuid() . "." . $file->getClientOriginalExtension();
$event->img = $request->image->storeAs('events', $filename, 'public');
}
// Create and save post with validated data
$event->save();
In the for loop, it is possible that one of the image names is empty and unlink is trying to delete a directory instead of file. unlink is only used to delete files and not directories. If you try to delete a directory using unlink, you will get an error. See the documentation for unlink.
The file_exists function checks whether a file or directory exists. Since you want to check if file exists and not directory, then you should use the is_file function instead of file_exists. See the documentation for is_file.
I am using Zipper to extract uploaded zip file and delete the file after extract.
So I upload and extract like this:
$f = $request['file']->move(public_path($directory), $fullFileName);
\Zipper::make($f)->extractTo(public_path($directory) . $fileName);
and it works great. I've tried to delete the file using these ways.
1 - Storage::disk('products')->delete($fullFileName);
2 - File::delete(public_path($directory) . $fullFileName);
3 - $del = unlink(public_path($directory) . $fullFileName);
but in all actions get resource temporarily unavailable error.
I found this error is because of the zipper (simple files and directories works).
so my question is, How can I delete upload zip file after extract, using a zipper?
Any idea would be great.
thanks in advance.
You need to call $zipper->close(); after you extract it, so if you do something like this it should work:
$zipper = new \Chumper\Zipper\Zipper;
$zipper->make($f)->extractTo(public_path($directory) . $fileName);
$zipper->close();
unlink(public_path($directory) . $fullFileName);
If you do not close the zipper it will not write the result to the disk and keep the original file locked. See the documentation.
$zip = new Zipper;
$zip->make($pathZipFile)->extractTo($destinationPath);
$zip->close(); // important
unlink($pathZipFile); // delete Zip file after
I was following a guide for creating a new file in php and I was using the following code:
function create($user, $name) {
/* Later on, this will connect to another server*/
$dir = $user->getFolder() . "/Projects/". $name;
if(file_exists($dir)) {
$this->error = "Directory: " . $dir . " already exists.";
} else {
mkdir($dir);
//Create the users.json file and add the owner
$json = fopen($dir . "/Data/users.txt", "w") or die("Cannot open file");
fclose($json);
}
}
The directory gets created but I receive the following error: "Warning: fopen(Jake/UserFolder//Projects/test/Data/users.txt): failed to open stream: No such file or directory in D:\xampp\htdocs\Collabs\Objects\Scripts\Project.php on line 14
Cannot open file"
The path shown in your error looks like it could be the problem.
Jake/UserFolder//Projects/test/Data/users.txt
There are two slashes between UserFolder and Projects. It looks like changing your code to
$dir = $user->getFolder() . "Projects/". $name;
Would get rid of the extra slash.
A couple of things that might have gone wrong:
You didn't pass path with a leading /, so fopen() will search relatively to the directory the script is executing in. I assume you'll want to pass an absolute path
you are testing for file_exists(), you should also check for is_dir(), to catch and handle the cases where a file with the same path already exists
you might consider calling mkdir($dir, 077, true) in order to create
the intermediary directories (see the mkdir() documentation)
So, I understand it's pretty easy to zip a folder and its contents given that php.net and stackoverflow are full of sample codes. I am trying to zip up a folder as well. This is my code:
$zip = new ZipArchive;
$zip->open('myzip.zip', ZipArchive::CREATE);
foreach (glob("/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder/*") as $file) {
$zip->addFile($file);
}
$zip->close();
My script is running in a folder, say on Desktop, and I want to zip thisFolder and its contents. The above code WORKS. But, the problem is that when I unzip the myzip.zip created, I get a structure like
Volumes>Data>Users>username>Desktop>Archive>some>thisFolder
and then I find the contents inside the 8th folder (thisFolder) in this case. How can I change this code so that when I unzip myzip.zip,I would straightaway see the folder thisFolder with the contents inside it instead of having to navigate through folders 7 times before getting my content?
I tried to change the path and silly things like that. But, it doesn't work.
Thanks
If you want everything in the file to be a name relative to your starting folder, use chdir() to start from there:
chdir("/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder");
foreach (glob("*") as $file) {
$zip->addFile($file);
}
Actually, I don't think this will work when $file is a subdirectory -- addFile doesn't recurse automatically. There's a comment in the documentation that shows how to write a recursive zip function:
http://www.php.net/manual/en/ziparchive.addemptydir.php
bool ZipArchive::addFile ( string $filename [, string $localname ] )
filename
The path to the file to add.
localname
local name inside ZIP archive.
You can use the pathinfo function to each $file in your loop, in order to retrieve the filename without the path, and then, use it as second parameter to the addFile method.
pathinfo doc here
Here is an example that could solve your problem:
// Create your zip archive
$zip = new ZipArchive;
// open it in creation mode
$zip->open('myzip.zip', ZipArchive::CREATE);
// Loop on all your file
$mask = "/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder";
$allAvailableFiles = glob($mask . "/*")
foreach ($allAvailableFiles as $file)
{
// Retrieve pathinfo
$info = pathinfo($file);
// Generate the internal directory
$internalDir = str_replace($mask, "", $info['dirname']);
// Add the file with internal directory
$zip->addFile($file, $internalDir . "/" . $info['basename']);
}
$zip->close();
I am creating something like easy installer\setupper for my CMS. When user downloads .zip with my CMS and unpacks it into some folder on his php server he sees a file - install.php and a zip folder named - Contents.zip I need some php function to extract files from that Contents.zip zip file and than delete that file. (If it is possible I want to give different rights to files\folders extracted from there right after folder unZipping)
How to do such a thing?
you could use PHP ZipArchive library to for you purpose.
also, an code example from the documentation you might find useful.
<?php
$zip = new ZipArchive();
$filename = "./test112.zip";
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
exit("cannot open <$filename>\n");
}
$zip->addFromString("testfilephp.txt" . time(), "#1 This is a test string added as testfilephp.txt.\n");
$zip->addFromString("testfilephp2.txt" . time(), "#2 This is a test string added as testfilephp2.txt.\n");
$zip->addFile($thisdir . "/too.php","/testfromfile.php");
echo "numfiles: " . $zip->numFiles . "\n";
echo "status:" . $zip->status . "\n";
$zip->close();
?>
for changing the file permissions you can use PHP builtin function chmod.
for example
chmod("/somedir/somefile", 0600);
to delete the file you can use, php builtin unlink
for example,
unlink('test.html');
unlink('testdir');
I would strongly recommend yuo to go through the official PHP documentation.