简体   繁体   中英

Laravel 9: Can't write image data to path

I'm using Laravel 9 for making a forum project.

Now for this project, I need to upload some images.

So at the Controller, I added this:

if($request->has('filep')){
    $files = $request->file('filep');
    foreach ($files as $file) {
          $this->uploadImage($file, $questionCreated->id, 'question_image');
    }
}

And here is the uploadImage method:

public function uploadImage($request, $id, $type_image)
    {
        $imagesUrl = UploadFile::upload($request,"Question",$id);
        foreach ($imagesUrl['path'] as $path) {
            UploadedFile::create([
                'upf_object_id' => $id,
                'upf_object_type_id' => $this->objectTable('questions'),
                'upf_path' => $path['upf_path'],
                'upf_uploaded_as' => $type_image,
                'upf_dimension' => $path['upf_dimension'],
                'upf_type' => $imagesUrl['option']['upf_type'],
                'upf_category' => $imagesUrl['option']['upf_category'],
                'upf_mime_type' => $imagesUrl['option']['upf_mime_type'],
            ]);
        }
    }

As you can see I'm calling a helper class ( see_it_here ) named UploadFile and its upload method:

public static function upload($file,$cat,$queid)
    {
        self::directoryType($file->getClientOriginalExtension());
        self::$mimeType = $file->getMimeType();
        self::$catType = $cat;
        self::$objId = $queid;
        $fileName = self::checkExistFile($file->getClientOriginalName());

        if (in_array($file->getClientOriginalExtension(), self::resizeable())) {
            $file->storeAs(self::route(), $fileName);
            self::resize($file, $fileName);
        }
        $file->storeAs(self::route(), $fileName);
        $file_name_hash = md5($fileName);
        return [
            "path" =>
                array_merge(self::$urlResizeImage, [[
                    "upf_path" => self::route() . $fileName,
                    "upf_dimension" => "fullsize"
                ]]),
            "option" => [
                "upf_object_id" => "",
                "upf_object_type_id" => "",
                "upf_type" => self::$typeFile,
                "upf_category" => self::$catType,
                "upf_mime_type" => self::$mimeType,
                'upf_file_name' => $fileName,
                'upf_file_hash' => $file_name_hash,
            ]
        ];
    }

Now the problem is coming from the resize method which uses Image Intervention for resizing:

public static function resize($file, $fileName)
    {
        $path = self::route();
        foreach (self::size() as $key => $value) {
            $resizePath = self::route() . "{$value[0]}x{$value[1]}_" . $fileName;
            Image::make($file->getRealPath())
                ->resize($value[0], $value[1], function ($constraint) {
                    $constraint->aspectRatio();
                })
                ->save(storage_path($path));
            $urlResizeImage[] = ["upf_path" => $resizePath, "upf_dimension" => "{$value[0]}x{$value[1]}"];
        }
        self::$urlResizeImage = $urlResizeImage;
    }

And the line ->save(storage_path($path)); returns this error:

Can't write image data to path (C:\xampp\htdocs\forum\storage\upload/1401/10/images/questions/77)

在此处输入图像描述

I don't know what's really going on here.

So if you know, please let me know...

I would really appreciate any idea or suggestion from you guys.

Here is also my filesystems config.

Ensure that the way you are utilizing to save the picture is right and focuses to the right area.

Make sure that the information base field you are utilizing to store the picture way has the right information type (for example text or varchar) and is sufficiently long to store the whole way.

Confirm that the information base has the essential consents to keep in touch with where you are attempting to save the picture.

In the event that you are utilizing a web application, ensure that the picture way is appropriately encoded and that you are utilizing the right URL punctuation.

In the event that you are utilizing a data set administration framework (DBMS) like MySQL, you might have to utilize a getaway capability like mysql_real_escape_string() to save the picture way accurately.

Ensure that there are no punctuation blunders in your SQL question.

Assuming the issue continues to happen, take a stab at investigating the issue by printing out the picture way and the SQL question that you are utilizing to save it to the information base. This can assist you distinguish any issues with the information or the inquiry.

I havn't worked in Windows environment in a long time, but it seems to me, that the problem is the filepath.

C:\xampp\htdocs\forum\storage\upload/1401/10/images/questions/77

In Windows direcory separator is a backslash character \ , and you're appending a Route which has forward-slashes / as a directory separator (like *nix systems have).

This operation results in an incorrect filepath - one with combined backslashes and forward slashes.

Try doing str_replace('/', '\\', self::route()) .

PS. If I am correct, and filepath is the issue here, note, that this error would most likely not popup in *nix environment.

It is possible, that Laravel had problems creating the directory to write to. I am not sure if Laravel actively creates target directories if they don't exist, so a good practice would be to first check if given subdirectories exist, and if they don't - create them, and only then save the file.

There are 6 possible problems that I can see.

First: The directory does not exist.

Here you can both check for its existence and create it if it does not. Libraries will generally not create directories for you. Replace File here with whatever makes sense in your context:

File::isDirectory($path) or File::makeDirectory($path, 0777, true, true);

Second: The directory exists but is not writeable.

Use a guard function to first check for writability at the top of Resize.

if ( !File::isWritable($path)) throw new NotWritableException("The $path directory is not writable");

Third: the filename is not sanitized and uses characters the underlying OS cannot accept

A good general case to look for, but in this case it seems correct. In any case use a function like League\Flysystem\WhitespacePathNormalizer::normalizePath

Fourth: Using the right variable

You appear to save to $path rather than $resizePath .

Fifth: OS-level restrictions like disk space limits

The file_put_contents code in the library you use above makes a bunch of unhelpful assumptions. I'd check for disk space and permissions.

Sixth: a xampp-level constraint on writable paths in its configs

Just try to write a file in that directory from anywhere in your code to see if it works (after everything else has been tried), something like

file_put_contents('C:\xampp\htdocs\forum\storage\upload\1401\10\images\questions/77', 'test'); 

which will bubble up the correct exception, before delving into xampp configuration arcana.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM