Object of class ZipArchive could not be converted to string - php

I'm trying to zip files selected by the user but for some reason I'm getting this error.
I'm using laravel 4.2
Here is the portion of code where the error is originating from.
$zip_name = 'dris-sweet-16-pictures.zip';
$zip = new ZipArchive();
$zip->open($zip_name, ZipArchive::CREATE);
foreach ($lg_img as $img) {
$zip->addFile(public_path().'/'.$img);
}
Response::download($zip, $zip_name, array(
'content-type' => 'application/zip',
'Content-disposition:' => 'attachment; filename=filename.zip',
'Content-Length:' => filesize($zip_name)
));
$zip->close();

As described here : http://laravel.com/docs/responses#special-responses,
the arguments for this method are in the following order :
Response::download($pathToFile, $name, $headers);
In your code, you are passing $zip, your ZipArchive as the path to the file but the method expect here a string, so the path to your file on the disk.
Cheers.

Related

can't push file to s3 buket in php

I took the sample code from the aws documentation, and I always get this error : IncalculablePayloadException
<?php $filepath = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]";
require 'aws.phar';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$s3Key = 'mykey';
$s3Secret = 'mysecretkey';
$region = 'eu-west-3';
$s3Bucket = 'mybucket';
$bucket = $s3Bucket;
$file_Path = $filepath.'/msk.png';
$key = basename($filepath);
echo $file_Path;
try {
//Create a S3Client
$s3Client = new S3Client([
'profile' => 'default',
'region' => $region,
'version' => '2006-03-01',
// 'debug' => true
]);
$result = $s3Client->putObject([
'Bucket' => $bucket,
'Key' => $key,
'SourceFile' => $file_Path,
]);
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
I have checked that my file exist, the path is correct. I have no idea what to do, this should work, it's from their damned doc.
I have tried with other files, different code found else where but I always get the same error.
Thanks for the help.
EDIT --------- 1
I have change $file_Path to $file_Path = 'msk.png';
And it's now 'working'. It upload a file to S3, but not a png but an xml file. with at the end
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
Any idea why?
EDIT --------- 2
Ok, so now I know why, the permission of the file was not set to read for public access. How can i set the ACL with putObject ?
The AWS PHP SDK Documentation has this description of SourcePath:
The path to a file on disk to use instead of the Body parameter.
But you are not providing a file on disk, you are providing a URL.
You have two options:
Provide the disk location of the path, based on where it is on your server. For instance, using __DIR__ to refer to the directory of the current PHP file, it might be $file_Path = __DIR__ . '/../public/msk.png';
Download the content first, and pass it in as a string to the Body parameter instead of SourcePath, e.g. using $body = file_get_contents($File_Path);
The first option makes more sense if it's a file on your own server, but the second one might be useful if you've simplified the example.

Create & zip & Download an S3 folder/multiple-files with AWS SDK PHP

I'm willing to create a php function, trigger in js, that can :
Retrieve all AWS S3 bucket files from a specific folder (I can also provide the path of each files)
Create a Zip containing all S3 files
Download the Zip when the trigger is hit (cta)
I'm able to download a single file with the getObject method from this example However, I can't find any informations in order to download multiple file and Zip it.
I tried the downloadBucket method, however it download all files inside my project architecture and not as a zip file.
Here is my code:
<?php
// AWS Info + Connection
$IAM_KEY = 'XXXXX';
$IAM_SECRET = 'XXXXX';
$region = 'XXXXX';
require '../../vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$FolderToDownload="FolderToDownload";
// Connection OK
$s3 = S3Client::factory(
array(
'credentials' => array(
'key' => $IAM_KEY,
'secret' => $IAM_SECRET
),
'version' => 'latest',
'region' => $region
)
);
try {
$bucketName = 'XXXXX';
$destination = 'NeedAZipFileNotAFolderPath';
$options = array('debug'=>true);
// ADD All Files into the folder: NeedAZipFileNotAFolderPath/Files1.png...Files12.png...
$s3->downloadBucket($destination,$bucketName,$FolderToDownload,$options);
// Looking for a zip file that can be downloaded
// Can I use downloadBucket? Is there a better way to do it?
// if needed I can create an array of all files (paths) that needs to be added to the zip file & dl
} catch (S3Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
?>
If some one can help, would be nice.
Thanks
You can use ZipArchive, list the objects from a prefix (the bucket's folder). In the case, I also use 'registerStreamWrapper' to get the keys and added to the created zip file.
Something like that:
<?php
require '/path/to/sdk-or-autoloader';
$s3 = Aws\S3\S3Client::factory(/* sdk config */);
$s3->registerStreamWrapper();
$zip = new ZipArchive;
$zip->open('/path/to/zip-you-are-creating.zip', ZipArchive::CREATE);
$bucket = 'your-bucket';
$prefix = 'your-prefix-folder'; // ex.: 'image/test/folder/'
$objects = $s3->getIterator('ListObjects', array(
'Bucket' => $bucket,
'Prefix' => $prefix
));
foreach ($objects as $object) {
$contents = file_get_contents("s3://{$bucket}/{$object['Key']}"); // get file
$zip->addFromString($object['Key'], $contents); // add file contents in zip
}
$zip->close();
// Download de zip file
header("Content-Description: File Transfer");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"/path/to/zip-you-are-creating.zip\"");
readfile ('/path/to/zip-you-are-creating.zip');
?>
You can also delete the zip file after the download, if you prefer.
Must work in most of cases, but I don't want to save the file in the server, but I don't see how I can download multiple objects directly from the AWS S3 bucket by the browser without saving a file in my server. If anyone know, please share with us.

How to download latest file or recently added file from Aws S3 using PHP. (Yii2)

I have a non-versioned S3 bucket (VersionId is null for all files), files have different names.
My current code is:
$path = $this->key.'/primary/pdfs/'.$id.'/';
$result = $this->s3->listObjects(['Bucket' => $this->bucket,"Prefix" => $path])->toArray();
//get the last object from s3
$object = end($result['Contents']);
$key = $object['Key'];
$file = $this->s3->getObject([
'Bucket' => $this->bucket,
'Key' => $key
]);
//download the file
header('Content-Type: application/pdf');
echo $file['Body'];
The above is incorrect as it is giving the end file which is not the latest file.
Do I need to use the below api call ? if so, how to use it ?
$result = $this->s3->listObjectVersions(['Bucket' => $this->bucket,"Prefix" => $path])->toArray();
Since the VersionId of all files is null, there should be only one version of the files in the bucket

Two FileNotFoundException-s when trying to download

So i'm using Laravel for a while. I wrote this:
public function downloadUserFile(){
$result = $_POST['filename'];
$entry = File::where('filename', '=', $result)->firstOrFail();
$file = Storage::disk()->get(storage_path($entry->filePath));
$headers = array('Content-Disposition' => 'attachment; filename="'.basename($entry->filePath).'"', 'Content-Type' => $entry->mimetype );
return (new Response($file, 200))->header($headers);
}
With the hope that I can download a selected file. Well I get two exceptions in FilesystemAdapter.php line 58 and in Filesystem.php line 381: File not found at path: C:\xampp\htdocs\bluedrive\drive\storage\uploads\1\SHTURCITE - Ti I Az.mp3 ---- This file is in the directory and i can't understand why laravel can't find it.

How can I download file from s3 in php?

How can I download file from s3 in php. The following code not working for me...
Here is my code
upload file should work correct
try {
$s3->putObject([
'Bucket' => $config['s3']['bucket'],//'eliuserfiles',
'Key' => "uploads/{$name}",
'Body' => fopen($tmp_name, 'r+'),
//'SourceFile' => $pathToFile,
'ACL' => 'public-read',
]);
download gives me error
$objInfo = $s3->get_object_headers($config['s3']['bucket'], "uploads/{$name}");
$obj = $s3->get_object($config['s3']['bucket'], "uploads/{$name}");
header('Content-type: ' . $objInfo->header['_info']['content_type']);
echo $obj->body;
error
PHP Catchable fatal error: Argument 2 passed to Aws\\AwsClient::getCommand() must be of the type array, string given, called in /php_workspace/s3_php/vendor/aws/aws-sdk-php/src/AwsClient.php on line 167 and defined in /php_workspace/s3_php/vendor/aws/aws-sdk-php/src/AwsClient.php on line 211, referer: http://localhost/upload.php
Simple way to do this:
include Amazon S3 PHP Class in you're project.
instantiate the class:
1. OO method (e,g; $s3->getObject(...)):
$s3 = new S3($awsAccessKey, $awsSecretKey);
2. Statically (e,g; S3::getObject(...)):
S3::setAuth($awsAccessKey, $awsSecretKey);
Then get Objects:
// Return an entire object buffer:
$object = S3::getObject($bucket, $uri));
var_dump($object);
Usually, the most efficient way to do this is to save the object to a file or resource
<?php
// To save it to a file (unbuffered write stream):
if (($object = S3::getObject($bucket, $uri, "/tmp/savefile.txt")) !== false) {
print_r($object);
}
// To write it to a resource (unbuffered write stream):
$fp = fopen("/tmp/savefile.txt", "wb");
if (($object = S3::getObject($bucket, $uri, $fp)) !== false) {
print_r($object);
}
?>
S3 Class -With Examples
S3 Class -Documentation
You can try this :
$bucket= "bucket-name";
$filetodownload = "name-of-the-file";
$resultbool = $s3->doesObjectExist ($bucket, $filetodownload );
if ($resultbool) {
$result = $client->getObject ( [
'Bucket' => $bucket,
'Key' => $filetodownload
] );
}
else
{
echo "file not found";die;
}
header ( "Content-Type: {$result['ContentType']}" );
header ( "Content-Disposition: attachment; filename=" . $filetodownload );
header ('Pragma: public');
echo $result ['Body'];
die ();

Categories