How to get the size of the image? - php

I have this array wanna get the size of the image:
$main_image = $product->images()->where('main_image', 1)->first();
if($main_image){
$url = asset('uploads/products/'. $main_image['image']);
$image[] = [
"name" => $main_image->image,
"type" => FileUploader::mime_content_type($main_image->image_path),
"size" => filesize($url),
"file" => $main_image->image_path,
"local" => $main_image->image_path,
];
}
I got this error:
filesize(): stat failed for http://myapp.test/uploads/products/83QhiRFarGpV.jpeg
Even my image exists in the folder!:
I tried all the options in this one but still same error at all!

Your code is using asset() to generate the $url:
http://myapp.test/uploads/products/83QhiRFarGpV.jpeg
The filesize() function works with local files, not URLs.
filesize($main_image->image_path) should work since you are using it in the line above to get the file type.
You probably also have another issue with
"file" => $main_image->image_path,
"local" => $main_image->image_path,
Where you probably want the file to be $url instead.

Related

Send unknown number of files using Guzzle

I am now using Guzzle to send multiple files uploaded by users to another server.
From my understanding, we can send files using Guzzle by using this code:
'multipart' => [
[
'name' => 'FileContents',
'contents' => file_get_contents($path . $name),
'filename' => $name
],
[
'name' => 'FileInfo',
'contents' => json_encode($fileinfo)
]
],
However, as the number of the files uploaded may not be the same and the code above can be used to send only one file. How can I send the unknown number of files using Guzzle? Thank you very much!
It depends on the server you sending request to. Is it able to handle an array inside FileContents and FileInfo? Or something like FileContents_1, FileContents_2, FileContents_N? It depends on your server.
Anyway in Guzzle you can easily fill the array with a loop:
$multipart => []
foreach ($files as $file) {
$multipart[] = [
'name' => 'FileContents[]',
'contents' => fopen($path . $name, 'r'),
'filename' => $name
];
$multipart[] = [
'name' => 'FileInfo[]',
'contents' => json_encode($fileinfo)
]
}
P.S.
Also it's better to use fopen() instead of file_get_contents(), because you don't need to read the files in your script, only to pass them to Guzzle.

How to handle file in Laravel?

The client sends file to server. It look like this:
array:1 [▼
"file" => array:5 [▼
"name" => "MMM1(one row).TXT"
"type" => "application/octet-stream"
"tmp_name" => "/tmp/phpaKnJzE"
"error" => 0
"size" => 1365
]
]
If to make the following operation:
dd($_FILES);
I tried to handle thi file like:
foreach ($_FILES["file"] as $file) {
$file->store('tests');
$file->getClientOriginalName();
}
But it does not work for me.
It involke an error:
Call to a member function getClientOriginalName() on array
$this->file->getClientOriginalName()
You need to set below code in your post action
$photo = $request->file('img');
$path = storage_path('app/public/avatars/');
$photo->move($path, $request->file('img')->getClientOriginalName());
If You're uploading an image then you can also use intervention/image package.
Using this, you'll also be able to do basic image manipulation.
In you controller post action do the following:
use Intervention\Image\Facades\Image;
if($request->hasFile('image')){
$image = \Image::make( $request->file( 'image' ) );
$image->save( storage_path('images/'. $request->file('image')->getClientOriginalName()));
}

Uploading to S3 with Laravel 5.2

Having an issue with the s3 driver for Laravel 5.2. The error i'm getting is this:
Found 1 error while validating the input provided for the HeadObject operation:
[Key] must be at least 1 characters long. Value provided is 0 characters long.
I'm using the league flysystem V3 as stated in Laravel docs. When I follow the stack track and start dumping out the vars the 'Key' value is always empty but i've set it all up in my config file.
Here are the top lines from my stack trace
in Validator.php line 38
at Validator->validate('HeadObject', object(StructureShape), array('Bucket' => 'monstervsl', 'Key' => '', '#http' => array())) in Middleware.php line 77
at Middleware::Aws\{closure}(object(Command), null) in S3Client.php line 710
at S3Client::Aws\S3\{closure}(object(Command), null) in S3Client.php line 729
at S3Client::Aws\S3\{closure}(object(Command), null) in Middleware.php line 53
at Middleware::Aws\{closure}(object(Command), null) in SSECMiddleware.php line 59
at SSECMiddleware->__invoke(object(Command)) in AwsClient.php line 208
As you can see it's getting the bucket from my config but not the key it's empty.
Here is my filesystem.php file
's3' => [
'driver' => 's3',
// 'key' => env('S3_KEY'),
// 'secret' => env('S3_SECRET'),
'key' => '8tfnxo8abgn7voaex8rgv', // <- Not my real key
'secret' => 'aw7btx49wXNF7AGWV', // <- not my real secret
'region' => 'eu-west-1',
'bucket' => 'monstervsl',
],
Here is my controller, it's fairly straight forward, I don't think the put contents stuff is relevant but added it anyway
// Write the contents to a new file on disk
$view = view('iframe')->with('json', $video->toJson());
$contents = $view->render();
$token = '12345';
$filePath = public_path() .'/iframes/' . $token . '.html';
file_put_contents($filePath, $contents);
Storage::disk('s3')->put('/', file_get_contents($filePath));
You have to give the destination file path/name where you want to save this file on S3 bucket as the first argument of put function. Currently you are trying to save the file at the root of bucket without any name. Try something like this:
Storage::disk('s3')->put('filename.html', file_get_contents($filePath));
This full path of the file is the Key in this context & that is what's missing in your original request.

AWS Lambda PHP Create Function with Zip

I'm trying to create a PHP script that creates a function from some code that i zip up on our server. I uploaded the file manually to lambda, and it works fine. But when i try to use the aws sdk to create the function, it fails with an error message. Anyone got any clue?
Code:
private function createLambdaFunction() {
$result = $this->lambdaConn->createFunction(array(
'FunctionName' => $this->lambdaFunctionName,
'Runtime' => $this->runtime,
'Role' => $this->role,
'Handler' => $this->lambdaFunctionName.".".$this->handler,
'Description' => $this->description,
'Timeout' => $this->timeout,
'MemorySize' => $this->memorySize,
'Code' => array(
'ZipFile' => 'fileb://test.zip'
)
));
Error:
PHP Fatal error: Uncaught Aws\Lambda\Exception\LambdaException: AWS
Error Code: InvalidParameterValueException,
Status Code: 400, AWS Request ID: asdf, AWS Error Type: user,
AWS Error Message: Could not unzip uploaded file. Please check
your file, then try to upload again., User-Agent:
aws-sdk-php2/2.8.10 Guzzle/3.9.3 curl/7.35.0 PHP/5.5.9-1ubuntu4.9
I can't seem to find a good example on google, and the documentation is...less than ideal. I created the zip file with php, so I've tried passing that var, the full path to the file, relative path to file, etc. Finally learned you have to use fileb:// preface, but that didn't end up fixing anything.
Okay, I'm not sure why this is the case, but you need to base64 encode your zip file like:
$result = $this->lambdaConn->createFunction(array(
'FunctionName' => $this->lambdaFunctionName,
'Runtime' => $this->runtime,
'Role' => $this->role,
'Handler' => $this->lambdaFunctionName . "." . $this->handler,
'Description' => $this->description,
'Timeout' => $this->timeout,
'MemorySize' => $this->memorySize,
'Code' => array(
'ZipFile' => 'fileb://'.base64_encode(file_get_contents('test.zip'))
)
));
I'm not sure why this is required, as accourding to the doumentation and a post by an AWS employee, you dont have to have base64 encoding for create function. They must have mixed up something or another.

Amazon S3 setting metadata fails using AWS SDK PHP v2 upload()

I'm having problems setting the "Metadata" option when uploading files to Amazon S3 using the AWS SDK PHP v2. The documentation that I'm reading for the upload() method states that the the 5th parameter is an array of options...
*$options Custom options used when executing commands: - params: Custom
parameters to use with the upload. The parameters must map to a
PutObject or InitiateMultipartUpload operation parameters. -
min_part_size: Minimum size to allow for each uploaded part when
performing a multipart upload. - concurrency: Maximum number of
concurrent multipart uploads. - before_upload: Callback to invoke
before each multipart upload. The callback will receive a
Guzzle\Common\Event object with context.*
My upload() code looks like this..
$upload = $client->upload(
'<BUCKETNAME>',
'metadatatest.upload.jpg',
fopen('metadatatest.jpg','r'),
'public-read',
array('Metadata' => array(
'SomeKeyString' => 'SomeValueString'
))
);
...and no meta data is set after upload.
If however I use putObject() as documented here, which I assume is a "lower level" method compared to upload()...
$putObject = $client->putObject(
array(
'Bucket' => '<BUCKETNAME>',
'Key' => 'metadatatest.putobject.jpg',
'Body' => file_get_contents('metadatatest.jpg'),
'ACL' => 'public-read',
'Metadata' => array(
'SomeKeyString' => 'SomeValueString'
)
)
);
The meta data is successfully returned when I call getObject() or view the file directly in my browser when uploaded using putObject()
$getObject = $client->getObject(
array(
'Bucket' => '<BUCKETNAME>',
'Key' => 'metadatatest.putobject.jpg'
)
);
I would prefer to use the $client->upload() method as the documentation states
Upload a file, stream, or string to a bucket. If the upload size exceeds the specified threshold, the upload will be performed using
parallel multipart uploads.
I'm not sure what I've missed?
There's really no difference in using upload() or putObject() if you don't do multipart uploads. You can have a look at the AWS PHP SDK source code but basically the upload method just calls putObject like this:
// Perform a simple PutObject operation
return $this->putObject(array(
'Bucket' => $bucket,
'Key' => $key,
'Body' => $body,
'ACL' => $acl
) + $options['params']);
This isn't very clear in the SDK documentation, but you need to send the last parameter as an array with the key params and its value being a second array with the Metadata key and value like this:
$upload = $client->upload(
'<BUCKETNAME>',
'metadatatest.upload.jpg',
fopen('metadatatest.jpg','r'),
'public-read',
array('params' => array(
'Metadata' => array(
'SomeKeyString' => 'SomeValueString'
)))
);
However, I you could just use the putObject call to achieve the same thing.

Categories