Download random files as zip - php

I posted my code a few days back and I am now at this point with it. I have acquired the random files however, when they zip it becomes a zip.cpgz file after unzipping. I am sure that this has something to do with the way I used array in my loop but I am not quite sure of how to fix this.
<?php
//./uploads
$dir = "./uploads";
$nfiles = glob($dir.'*.{aiff}', GLOB_BRACE);
$n=1;
while ($n<=10){
$n ++;
$arr[$n] = rand(2, sizeof($nfiles)-1);
print($arr[$n]);
print(" ");
}
$zip = new ZipArchive();
$zip_name = "zipfile.zip";
if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE){
$error .= "* Sorry ZIP creation failed at this time";
}
foreach($arr as $file){
$path = "./uploads".$file;
$zip->addFromString(basename($path), file_get_contents($path));
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zip_name);
readfile('zipfile.zip');
?>
Also if you are kinda lost here is my website I am trying to implement it on. (click the download button)

Recently helped another user get something similar to work ( without the random selection ) and you might find the following useful. This does search a directory for a particular file extension and then randomly select 10 files which get zipped and sent. Change the $sourcedir and $ext to suit - hope it helps.
/* From David Walsh's site - modified */
function create_zip( $files = array(), $destination = '', $overwrite = false ) {
if( file_exists( $destination) && !$overwrite ) { return false; }
$valid_files = array();
if( is_array( $files ) ) {
foreach( $files as $file ) if( file_exists( $file ) ) $valid_files[] = $file;
}
if( count( $valid_files ) ) {
$zip = new ZipArchive();
if( $zip->open( $destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE ) !== true) return false;
foreach( $valid_files as $file ) $zip->addFile( $file, pathinfo( $file, PATHINFO_FILENAME ) );
$zip->close();
return file_exists( $destination );
}
return false;
}
/* Simple function to send a file */
function sendfile( $filename=NULL, $filepath=NULL ){
if( file_exists( $filepath ) ){
if( !is_file( $filepath ) or connection_status()!=0 ) return FALSE;
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime( date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
header("Content-Type: application/octet-stream");
header("Content-Length: ".(string)( filesize( $filepath ) ) );
header("Content-Disposition: inline; filename={$filename}");
header("Content-Transfer-Encoding: binary\n");
if( $file = #fopen( $filepath, 'rb' ) ) {
while( !#feof( $file ) and ( connection_status()==0 ) ) {
print( fread( $file, 1024*8 ) );
flush();
}
#fclose( $file );
}
return( ( connection_status()==0 ) and !connection_aborted() );
}
}
/* Select a random entry from the array */
function pick( $arr ){
return $arr[ rand( 0, count( $arr )-1 ) ];
}
/* The directory to which the zip file will be written before sending */
$target=__DIR__.'\zipfile.zip';
/* The directory you wish to scan for files or create an array in some other manner */
$sourcedir = 'C:\Temp\temp_uploads';
/* File extension to scan for */
$ext='txt';
/* Placeholder to store files*/
$output=array();
/* Scan the dir, or as mentioned, create an array of files some other way */
$files=glob( realpath( $sourcedir ) . DIRECTORY_SEPARATOR . '*.'.$ext );
/* Pick 10 random files from all possible files */
do{
$rnd=pick( $files );
$output[ $rnd ] = $rnd;
}while( count( $output ) < 10 );
/* streamline array */
$output=array_values($output);
if( $target ) {
/* Zip the contents */
$result=create_zip( $output, $target, true );
/* Send the file - zipped! */
if( $result ) {
$res=call_user_func( 'sendfile', 'zipfile.zip', $target );
if( $res ) unlink( $target );
}
}

You sure it doens't work? I've donwloaded your zip file and extracted it and I got UploadsX files. So I don't get a zip.cpgz file.

Related

Error http uploading images on Wordpress

I'm working with Imagick and I don't know what happens because when I upload an file "png" or "jpg" It returns:
Error HTTP
but when I upload an file "jpge" it works perfectly.
This is the code on functions.php:
add_filter( 'wp_generate_attachment_metadata', 'generate_watermarked_image' );
function watermark_image( $filename, $upload_dir ) {
$original_image_path = trailingslashit( $upload_dir['path'] ) . $filename;
$image_resource = new Imagick( $original_image_path );
$watermark_resource = new Imagick( get_stylesheet_directory() . '/images/logo.png' );
$image_resource->compositeImage( $watermark_resource, Imagick::COMPOSITE_DEFAULT, 0, 0 );
return save_watermarked_image( $image_resource, $original_image_path );
}
function save_watermarked_image( $image_resource, $original_image_path ) {
$image_data = pathinfo( $original_image_path );
$new_filename = $image_data['filename'] . '-watermarked.' . $image_data['extension'];
$watermarked_image_path = str_replace($image_data['basename'], $new_filename, $original_image_path);
if ( ! $image_resource->writeImage( $watermarked_image_path ) )
return $image_data['basename'];
unlink( $original_image_path ); // Because that file isn't referred to anymore
return $new_filename;
}
I'm sorry for my english.

How to unzip a zip file that has another zip file inside using PHP

I have a file xyz.zip and in this file there are two more files test.xml and another abc.zip file that contains test2.xml. When i use this code it only extract xyz.zip file. But i also need to extract abc.zip.
xyz.zip
- test.xml
- abc.zip
- test2.xml
<?php
$filename = "xzy.zip";
$zip = new ZipArchive;
if ($zip->open($filename) === TRUE) {
$zip->extractTo('./');
$zip->close();
echo 'Success!';
}
else {
echo 'Error!';
}
?>
Can somebody please tell me how can i extract everything in zip files? Even abc.zip. So that the output will be in a folder (test.xml and test2.xml).
Thanks
this might help you.
This function will flatten a zip file using the ZipArchive class.
It will extract all the files in the zip and store them in a single destination directory. That is, no sub-directories will be created.
<?php
// dest shouldn't have a trailing slash
function zip_flatten ( $zipfile, $dest='.' )
{
$zip = new ZipArchive;
if ( $zip->open( $zipfile ) )
{
for ( $i=0; $i < $zip->numFiles; $i++ )
{
$entry = $zip->getNameIndex($i);
if ( substr( $entry, -1 ) == '/' ) continue; // skip directories
$fp = $zip->getStream( $entry );
$ofp = fopen( $dest.'/'.basename($entry), 'w' );
if ( ! $fp )
throw new Exception('Unable to extract the file.');
while ( ! feof( $fp ) )
fwrite( $ofp, fread($fp, 8192) );
fclose($fp);
fclose($ofp);
}
$zip->close();
}
else
return false;
return $zip;
}
/*
How to use:
zip_flatten( 'test.zip', 'my/path' );
*/
?>
You should use a recursive function that check all the extracted files and if it finds out one of them is a zip, then call itself again.
function scanDir($path) {
$files = scandir($path);
foreach($files as $file) {
if (substr($file, -4)=='.zip')
unzipRecursive($path, $file);
elseif (isdir($path.'/'.$file))
scanDir($path.'/'.$file);
}
}
function unzipRecursive($absolutePath, $filename) {
$zip = new ZipArchive;
$newfolder = $absolutePath.'/'.substr($file, 0, -4);
if ($zip->open($filename) === TRUE) {
$zip->extractTo($newfolder);
$zip->close();
//Scan the directory
scanDir($newfolder)
} else {
echo 'Error unzipping '.$absolutePath.'/'.$filename;
}
}
I didn't try the code but it's only to debug a little I guess

Return ZIP archive in CakePHP 3.0

In CakePHP controller I have the logic to generate a ZIP which is as follows and works perfectly fine, I can find the ZIP archive on the server:
function getAttachmentsInZip( $meetingId = null ){
$this->autoRender = false;
$this->request->allowMethod( ['post'] );
$allTasksWithFiles_query = $this->Tasks->find('all')
->where(['Tasks.uploaded_file_path != ' => 'NULL']);
$allTasksWithFiles = $allTasksWithFiles_query->toArray();
$files = array();
foreach( $allTasksWithFiles as $taskWithFile ){
$files[] = $taskWithFile['uploaded_file_path'];
}
if( !empty( $files ) ){
$destination = 'uploads/archives/meeting_' . $meetingId .'.zip';
$zip = new ZipArchive();
$zip->open( $destination, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE );
foreach( $files as $file ){
$zip->addFile('uploads/uploaded_files/' . $file, $file);
}
$zip->close();
}
}
However, I am completely unable to return the archive straight to user's browser. The closest I got was the following snippet, but the archive is broken and cannot be opened:
header("Content-type: application/zip");
header('Content-Disposition: attachment; filename="' . $destination . '"');
header("Pragma: no-cache");
header("Expires: 0");
readfile("asd");
Any help or guidance is much appreciated. If I should have/could have provided more code — please ask.

PHP script doesn't end

So I got my script doing this:
I got a list of filenames (images), I loop through the array and load the images from Amazon S3 to my local storage. We are talking about 35k pictures which takes more than 3 hours.
After I downloaded all the images I want to make a redirect via header Location. But the script won't execute that. It's like it's stopping after the loop.
When I have a very small list of images to load it will work with no issues.
The apache error log doesn't show any errors. There is no php process running on the server after that. But the request is still running in the browser.
Ini settings are as followed:
ini_set( 'max_execution_time', 60 * 30 );
ini_set( 'memory_limit', '4096M' );
Foreach loop lookes like this:
foreach( $arrImages as $file ) {
$strPath = $strBasePath . DIRECTORY_SEPARATOR . $file['name'];
// check directory
$pos = strrpos( $strPath, DIRECTORY_SEPARATOR );
$dir = substr( $strPath, 0, $pos );
if( !is_dir( $dir ) ) {
exec( "mkdir -p " . $dir );
exec( "chmod -R 777 " . $strBasePath . DIRECTORY_SEPARATOR );
}
// check if file or path
if( !is_dir( $strPath ) ) {
// build filename
$lastSeparatorPos = strrpos( $strPath, DIRECTORY_SEPARATOR );
$filename = explode( '.', substr( $strPath, $lastSeparatorPos + 1, strlen( $strPath ) - 1 ) );
$clearedFilename = explode( '_', $filename[0] );
if( !in_array( $clearedFilename[0], $arrOrdernumbers ) && strpos( $dir, 'groups' ) == false && strpos( $dir, 'background' ) == false ) {
$intCountNotImported++;
}
else {
$handle = fopen( $strPath, 'wb' );
if( $handle == false ) {
\ImportLogger::log( $strPath . ' - Bild konnte nicht uebertragen werden' );
}
else {
// get File/Folder
$objImage = \S3::getObject( C_S3_BUCKET, $file['name'] );
fwrite( $handle, $objImage->body );
$intAmount++;
// Log every 100 Files
if( $intAmount % 100 == 0 ) {
\ImportLogger::log( $intAmount . ' Bilder uebertragen' );
}
}
fclose( $strPath );
}
}
}
\Debugger::sendEmail( 'xx#xxxx.de', 'Fetchimages', $intAmount . ' - Images loaded' ); // This E-Mail I still get
// Redirect is not happening
$strUrl = '/string/configurator2/compressimages';
header( 'Location: ' . $strUrl );
exit;
Any ideas what could cause this?
Thanks for your help!

copy file from one server to another programmatically in php

I've hosted my all code files on one server whose domain is like example.com and I'm at one of those html pages. I want some files of example.com to move on another server whose domain is like example2.com. I've searched through Internet but I couldn't find any good solution. Please tell me is this possible without FTP client or without browser where we upload files manually. Or is there any way to submit file from HTML form from one server to another like if on action we'll write
<form action="http://example2.com/action_page.php">
Any help would be much appreciated.
If you set the contents of this file: example2.com/action_page.php to:
<?php
$tobecopied = 'http://www.example.com/index.html';
$target = $_SERVER['DOCUMENT_ROOT'] . '/contentsofexample/index.html';
if (copy($tobecopied, $target)) {
//File copied successfully
}else{
//File could not be copied
}
?>
and run it, through command line or cron (as you have written a php related question, yet banned use of browsers!) it should copy the contents of example.com/index.html to a directory of your site (domain: example2.com) called contentsofexample.
N.B. If you wanted this to copy the whole website you should place it in a for loop
There are still 2 possible ways which can used to copy your files from another server.
-One is to remove your .htaccess file from example.com or allow access to all files(by modifying your .htaccess file).
-Access/Read those files via their respective URLs, and save those files using 'file_get_contents()' and 'file_put_contents()' methods. But this approach will made all files accessible to other people too.
$fileName = 'filename.extension';
$sourceFile = 'http://example.com/path-to-source-folder/' . $fileName;
$targetLocation = dirname( __FILE__ ) . 'relative-path-destination-folder/' + $fileName;
saveFileByUrl($sourceFile, $targetLocation);
function saveFileByUrl ( $source, $destination ) {
if (function_exists('curl_version')) {
$curl = curl_init($fileName);
$fp = fopen($destination, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
} else {
file_put_contents($destination, file_get_contents($source));
}
}
Or you can create a proxy/service on example.com to read a specific file after validating a pass key or username/password combination(whatever as per your requirement).
//In myproxy.php
extract($_REQUEST);
if (!empty($passkey) && paskey == 'my-secret-key') {
if (!empty($file) && file_exists($file)) {
if (ob_get_length()) {
ob_end_clean();
}
header("Pragma: public");
header( "Expires: 0");
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0");
header( 'Content-Type: ' . mime_content_type($file) );
header( "Content-Description: File Transfer");
header( 'Content-Disposition: attachment; filename="' . basename( $file ) . '"' );
header( "Content-Transfer-Encoding: binary" );
header( 'Accept-Ranges: bytes' );
header( "Content-Length: " . filesize( $file ) );
readfile( $file );
exit;
} else {
// File not found
}
} else {
// You are not authorised to access this file.
}
you can access that proxy/service by url 'http://example.com/myproxy.php?file=filename.extension&passkey=my-secret-key'.
You can exchange files between servers by also using zip method.
You own both servers so you shouldn't have security issues.
On the server that hosts the file or folder you want, create a php script and create a cron job for it. Sample code below:
<?php
/**
* ZIP All content of current folder
/* ZIP File name and path */
$zip_file = 'myfiles.zip';
/* Exclude Files */
$exclude_files = array();
$exclude_files[] = realpath( $zip_file );
$exclude_files[] = realpath( 'somerandomzip.php' );
/* Path of current folder, need empty or null param for current folder */
$root_path = realpath( '' ); //or $root_path = realpath( 'folder_name' ); if the file(s) are in a particular folder residing in the root
/* Initialize archive object */
$zip = new ZipArchive;
$zip_open = $zip->open( $zip_file, ZipArchive::CREATE );
/* Create recursive files list */
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( $root_path ),
RecursiveIteratorIterator::LEAVES_ONLY
);
/* For each files, get each path and add it in zip */
if( !empty( $files ) ){
foreach( $files as $name => $file ) {
/* get path of the file */
$file_path = $file->getRealPath();
/* only if it's a file and not directory, and not excluded. */
if( !is_dir( $file_path ) && !in_array( $file_path, $exclude_files ) ){
/* get relative path */
$file_relative_path = str_replace( $root_path, '', $file_path );
/* Add file to zip archive */
$zip_addfile = $zip->addFile( $file_path, $file_relative_path );
}
}
}
/* Create ZIP after closing the object. */
$zip_close = $zip->close();
?>
Create another php script and cron job on the server to receive the copy as below:
/**
* Transfer Files Server to Server using PHP Copy
*
*/ /* Source File URL */
$remote_file_url = 'url_of_the_zipped';
/* New file name and path for this file */
$local_file ='myfiles.zip';
/* Copy the file from source url to server */
$copy = copy($remote_file_url, $local_file );
/* Add notice for success/failure */
if( !$copy ) {
echo "Failed to copy $file...\n"; }
else{
echo "Copied $file successfully...\n"; }
$file = 'myfiles.zip';
$path = pathinfo( realpath( $file ), PATHINFO_DIRNAME );
$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
$zip->extractTo( $path );
$zip->close();
echo "$file extracted to $path"; }
else {
echo "Couldn't open $file";
}
?>
Voila!
<?php
/* Source File URL */
$remote_file_url = 'http://origin-server-url/files.zip';
/* New file name and path for this new file */
$local_file = 'files.zip';
/* Copy the file from source url to server */
$copy = copy( $remote_file_url, $local_file );
/* Add notice for success/failure */
if( !$copy ) {
echo "Doh! failed to copy $file...\n";
}
else{
echo "WOOT! Thanks Munshi and OBOYOB! success to copy $file...\n";
}
?>

Categories