Error uploading images using Slim framework - php

I am trying to create an API endpoint using Slim that allows people upload images. I am however having issues as I keep getting this error message,
"Argument 2 passed to moveUploadedFile() must be an instance of
UploadedFile, instance of Slim\Http\UploadedFile given"
This is what I am doing:
$directory = __DIR__.'/uploads';
function moveUploadedFile($directory, UploadedFile $uploadedFile)
{
$extension = pathinfo($uploadedFile->getClientFilename(), PATHINFO_EXTENSION);
// see http://php.net/manual/en/function.random-bytes.php
$basename = bin2hex(random_bytes(8));
$filename = sprintf('%s.%0.8s', $basename, $extension);
$uploadedFile->moveTo($directory . DIRECTORY_SEPARATOR . $filename);
return $filename;
}
$files = $request->getUploadedFiles();
$uploadedFile = $files['photo'];
if ($uploadedFile->getError() === UPLOAD_ERR_OK) {
$filename = moveUploadedFile($directory, $uploadedFile);
}
Please how I solve this?

The error tells you that PHP is looking for class UploadedFile in current namespace because you add typehint for it. Since there is no class named UploadedFile in your current namespace, hence the error.
Add use clause for example
use Slim\Http\UploadedFile;
...
function moveUploadedFile($directory, UploadedFile $uploadedFile)
{
...
}
or typehint full class name
function moveUploadedFile($directory, Slim\Http\UploadedFile $uploadedFile)
{
...
}

Related

Unable to write in the \"/var/www/symfony/public/uploads/photos\"

I wish to upload files usering a multipart formData in a directory inside my project folder but I receive the error mentioned
The .env file
PHOTO_PATH=/public/uploads/photos
the service.yaml
parameters:
photo_path: '%kernel.project_dir%%env(PHOTO_PATH)%'
the upload function
<?php
namespace App\Service;
use App\DTO\UserRequest;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\String\Slugger\SluggerInterface;
class UserService extends BaseService
{
private SluggerInterface $slugger;
private string $photoPath;
public function __construct(
SluggerInterface $slugger,
ParameterBagInterface $parameters
) {
$this->slugger = $slugger;
$this->photoPath = $parameters->get('photo_path');
}
private function addPhoto(UserRequest $userRequest): string
{
$file = $userRequest->photo;
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $this->slugger->slug($originalFilename);
$fileName = $safeFilename . '-' . uniqid('', true) . '.' . $file->guessExtension();
$file->move($this->photoPath, $fileName);
return $fileName;
}
}
I receive the following error when i call the function
request.CRITICAL: Uncaught PHP Exception Symfony\Component\HttpFoundation\File\Exception\FileException: "Unable to write in the "/var/www/symfony/public/uploads/photos" directory." at /var/www/symfony/vendor/symfony/http-foundation/File/File.php line 131 {"exception":"[object] (Symfony\\Component\\HttpFoundation\\File\\Exception\\FileException(code: 0): Unable to write in the \"/var/www/symfony/public/uploads/photos\" directory. at /var/www/symfony/vendor/symfony/http-foundation/File/File.php:131)"} []

laravel file upload using custam library

"I'm tring to upload file using custome library in laravel file goes in folder successfully but file isn't upload in database
this is my custom library:-
namespace App\Classes;
use Illuminate\Http\Request;
class Hello
{
static function jai(Request $request)
{
if($request->hasfile('name'))
{
$image=$request->file('name');
$new_image=time().'.'.$image->getClientOriginalName();
$image->move(public_path('image/'),$new_image);
}
}
}
?>
and this is my controller store function :-
Hello::jai($request);
$x=$request->all();
$x['name']=
$j=Hello::jai($request)->new_image;
Cruds::create($x);
The file "[000004].jpg" was not uploaded due to an unknown error.
Hope this will help.
public function upload(Request $request){
if($file = $request->file('file')){
$name = $file->getClientOriginalName();
if($file->move('files',$name)){
$file= new Files();//DB instance modal
$file->url= $name;
$file->save();
return "success";
}
}
You forgot the file extension. See if this help you.
$image = $request->file('your_input_form_file_name');
$image = time() . '_' . $image->getClientOriginalName() . '.' . $file->getClientOriginalExtension();
$image->move(public_path('images/'), $name);

manually creating an Symfony UploadedFile

I'm facing following problem and can't seem to figure this one out.
I wrote an API endpoint accepting a POST with binary data (header: content-type:image/jpeg).
I know i can read out the raw string with file_get_content('php://input') or Laravel's $request->getContent().
PHP also has a function createimagefromstring($string) which also seems to read the string in correctly.
What i'd like to do is create an UploadedFile from this raw data , so that I can handle it with already written functions.
Is this possible?
Thank you in advance
I think I found it... Still curious if there are improvements that can be made..
$imgRaw = imagecreatefromstring( $request->getContent() );
if ($imgRaw !== false) {
imagejpeg($imgRaw, storage_path().'/tmp/tmp.jpg',100);
imagedestroy($imgRaw);
$file = new UploadedFile( storage_path().'/tmp/tmp.jpg', 'tmp.jpg', 'image/jpeg',null,null,true);
// DO STUFF WITH THE UploadedFile
}
You can try to use base64 encoding. Symfony have some nice stuff for this.
Your code will be smthng like this:
$base64Content = $request->request->get('base64Content'); // this is your post data
$yourFile = new UploadedBase64EncodedFile(new Base64EncodedFile($base64Content)); // this is an instance of UploadedFile
Hope it helps!
As per Laravel 8
Just follow the constructor:
* #param string $path The full temporary path to the file
* #param string $originalName The original file name of the uploaded file
* #param string|null $mimeType The type of the file as provided by PHP; null defaults to application/octet-stream
* #param int|null $error The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants); null defaults to UPLOAD_ERR_OK
* #param bool $test Whether the test mode is active
$file = new UploadedFile(
$pathIncludingFilename,
$fileName,
'image/jpeg',
null,
false
);
There is no need to manually create it, Symfony parses received $_FILES array for you. Http Request object has a FileBag property called $files with a get() method which returns an UploadedFile instance.
/** #var UploadedFile $file */
$file = $request->files->get('user-pictures-upload')[0];
$cmd = new UploadPictureCmd($file, $this->getUser()->getId());
Here is the example of generating images files using fzaninotto/faker in Symfony 4 Fixtures
class FileFixtures extends Fixture
{
private $faker;
private $parameterBag;
public function __construct(ParameterBagInterface $parameterBag)
{
$this->faker = Factory::create();
$this->parameterBag = $parameterBag;
}
public function load(ObjectManager $manager)
{
$tempFixturesPath = $this->parameterBag->get('kernel.project_dir') . '/tmp';
if (!file_exists($tempFixturesPath)) {
mkdir($tempFixturesPath);
}
$fileName = $this->faker->image($tempFixturesPath, 640, 480, 'cats', false, true);
$file = new UploadedFile($tempFixturesPath . '/' . $fileName, $fileName, 'image/jpeg', null, null, true);
//do something with $file
}
}
If it counts for anything, this is how I did it in Laravel 5.4. In my case, I wanted to be able to easily resize an image and be able to do something like this.
request()->file('image')->resize(250, 250)->store('path/to/storage');
This is what I did to the UploadedFile class.
Illuminate\Http\UploadedFile.php ~this file ships with the Laravel framework
public function resize($w, $h) {
$image = Intervention::make($this)->fit($w, $h)->save($this->getPathname());
$filesize = filesize($this->getPathname());
return new static(
$this->getPathname(),
$this->getClientOriginalName(),
$this->getClientMimeType(),
$filesize,
null,
false
);
}
Using Intervention, I resized the image that is stored in the /tmp/ folder when files are uploaded and then I saved it in the same place. Now all I do after that is create an instance of UploadedFile so that I can keep using Laravel's methods on request()->file('image'). Hope this helps.

Manipulate Symfony 2 UploadFile object in a unit test

I'm working on a Symfony2 project.
I created a simple TempFile class to manipulate an UploadFile. Here is my constructor :
public function __construct(UploadedFile $file, $destination, $suffix)
{
$this->file = $file;
$this->destination = $destination;
$this->fileId = sprintf('%s_%s', uniqid(), (string) $suffix);
}
And my move method
public function move()
{
$extension = $this->file->guessExtension();
if (!$extension) {
throw new \Exception(__METHOD__ . ' -> Unable to detect extension');
}
$this->tmpFileName = sprintf('%s.%s', $this->fileId, $extension);
$this->file->move($this->destination, $this->tmpFileName);
}
I try to create an UploadFile object in my test and here is what I did :
protected function setUp()
{
$this->file = tempnam(sys_get_temp_dir(), 'upload');
imagepng(imagecreatetruecolor(10, 10), $this->file);
$this->uploadedFile = new UploadedFile($this->file, "test.png");
}
public function testMoveWithAValidUploadedFile()
{
$tempFile = new TempFile($this->uploadedFile, '/tmp', 'tmp');
$tempFile->move();
// Future assertion
}
I have the following error :
Symfony\Component\HttpFoundation\File\Exception\FileException: The file "test.png" was not uploaded due to an unknown error
Any ideas ?
Thx,
Regards
From memory, Symfony2 checks if a file was uploaded as part of the request using is_uploaded_file(). This can be overridden using the test mode of the UploadedFile class. You can also define which PHP upload error code constitutes success.
copy(__DIR__ . '/Fixtures/test.pdf', '/tmp/test.pdf');
new UploadedFile(
'/tmp/test.pdf',
'original.pdf',
null,
null,
UPLOAD_ERR_OK,
true /* test */
)

Trying to get property of non-object when accessing from called function

I'm using yii framework but I think this is related to PHP
In my controller, I have the following code
$model = new Events;
$model->type_id = $type_id;
$checkFileUpload = checkFileUpload($model);
the function checkFileUpload is a custom function which contains
function checkFileUpload($model)
{
$rnd = rand(0, 9999);
$uploadedFile = CUploadedFile::getInstance($model, 'image');
if($uploadedFile->error == 0)
{
$fileName = "{$rnd}-{$uploadedFile}"; // random number file name
$model->image = $fileName;
...
I got the error get property of non-object in $uploadedFile->error.
I've tried to use reference to the model instead, but it is deprecated and does not work for me.
If I use the code of the called function (checkFileUpload) within the controller code, it works fine. I suspect that object is not passed in a correct way.
Any help?
This is because your call to CUploadedFile::getInstance returns null and not the instance you desired.
Null is returned if no file is uploaded for the specified model attribute.
— Yii Documentation
It seems like your file was not correctly uploaded. I am not a Yii Framework user, but the documentation states:
The file should be uploaded using CHtml::activeFileField.
— Yii Documentation
So you should verify that the file was actually correctly uploaded with the proper method from the Yii Framework.
PS: Objects are always passed by reference.
$model = new Events;
$type_id=$model->type_id;
$checkFileUpload = checkFileUpload($model);
function checkFileUpload($model)
{
$rnd = rand(0, 9999);
$uploadedFile = CUploadedFile::getInstance($model, 'image');
if(!isset($uploadedFile->getHasError()))
{
$fileName = "{$rnd}-{$uploadedFile}"; // random number file name
$model->image = $fileName;
The problem occurred because at the time when you are using $uploadedFile->error,the value of $uploadedFile is null.
The following line is not giving you the desired value
$uploadedFile = CUploadedFile::getInstance($model, 'image');
Which means no file has been uploaded.
Try CVarDumper::dump($_FILES,10,true);
This will tell you whether the problem is with the UPLOADING OF THE FILE or GETTING THE DETAILS OF THE UPLOADED FILE
you cant access the private property $_error $uploadedFile->_error if you are trying to. you must call $uploadedFile->getError() in your code. Also $uploadedFile will return null if no file uploaded so you must take care of that as well.
$rnd = rand(0, 9999);
$uploadedFile = CUploadedFile::getInstance($model, 'image');
if(!empty($uploadedFile) && !$uploadedFile->getHasError())
{
$fileName = "{$rnd}-{$uploadedFile}"; // random number file name
$model->image = $fileName;
will work for you.

Categories