Laravel загружает изображение в хранилище в Windows

#php #laravel

#php #laravel

Вопрос:

Для разработки я работаю в Windows над своим проектом laravel. Я пытаюсь заставить загрузку файлов работать локально.

Мой код загрузки:

 public function addPicture(Request $request, $id)
{
    $bathroom = Bathroom::withTrashed()->findOrFail($id);
    $validatedData = Validator::make($request->all(), [
        'afbeelding' => 'required|image|dimensions:min_width=400,min_height=400',
    ]);
    if($validatedData->fails())
    {
        return Response()->json([
            "success" => false,
            "errors" => $validatedData->errors()
        ]);
    }
    if ($file = $request->file('afbeelding')) {
        $img = Image::make($file);
        $img->resize(3000, 3000, function ($constraint) {
            $constraint->aspectRatio();
            $constraint->upsize();
        });
        $img->stream();
        $uid = Str::uuid();
        $fileName = Str::slug($bathroom->name . $uid).'.jpg';

        $this->createImage($img, 3000, "high", $bathroom->id, $fileName);
        $this->createImage($img, 1000, "med", $bathroom->id, $fileName);
        $this->createImage($img, 700, "thumb", $bathroom->id, $fileName);
        $this->createImage($img, 400, "small", $bathroom->id, $fileName);

        $picture = new Picture();
        $picture->url = '-';
        $picture->priority = '99';
        $picture->alt = Str::limit($bathroom->description,100);
        $picture->margin = 0;
        $picture->path = $fileName;
        $picture->bathroom_id = $id;
        $picture->save();

        return Response()->json([
            "success" => true,
            "image" => asset('/storage/img/bathroom/'.$id.'/small/'.$fileName),
            "id" => $picture->id
        ]);
    }
    return Response()->json([
        "success" => false,
        "image" => ''
    ]);
}

public function createImage($img, $size, $quality, $bathroomId, $fileName){
    $img->resize($size, $size, function ($constraint) {
        $constraint->aspectRatio();
        $constraint->upsize();
    });
    Storage::put(  $this->getUploadPath($bathroomId, $fileName, $quality), $img->stream('jpg',100));

}

public function  getUploadPath($bathroom_id, $filename, $quality = 'high'){
    $returnPath = asset('/storage/img/bathroom/'.$bathroom_id.'/'.$quality.'/'.$filename);
    echo $returnPath;

}
  

Я запустил: php artisan storage:link

И доступен следующий путь D:Documentsreposprojectnamestorageapp . Когда я загружаю файл, я получаю:

«сообщение»: «открыть (D:Documentsreposprojectnamestorageapp ): не удалось открыть поток: нет такого файла или каталога», «исключение»: «Ошибка исключения», «файл»: «D:DocumentsreposprojectnamevendorleagueflysystemsrcAdapterLocal.php «, «строка»: 157,

И далее в журнале:

  "file": "D:\Documents\repos\projectname\app\Http\Controllers\Admin\BathroomController.php",
        "line": 141, . 
  

который указывает на следующую строку.

 Storage::put(  $this->getUploadPath($bathroomId, $fileName, $quality), $img->stream('jpg',100));
  

функции createImage.
Как я могу заставить его работать в Windows, чтобы я мог протестировать свой веб-сайт локально?

Комментарии:

1. Что возвращает $img->stream('jpg',100) ?

2. Что-нибудь произойдет, если вы удалите конечную / часть пути?

Ответ №1:

Обычно я сохраняю изображения непосредственно в общую папку, вот рабочий код из одного из моих проектов

  $category = new Categories;
//get icon path and moving it
$iconName = time().'.'.request()->icon->getClientOriginalExtension();
 // the icon in the line above indicates to the name of the icon's field in 
 //front-end
$icon_path = '/public/category/icon/'.$iconName;
//actually moving the icon to its destination
request()->icon->move(public_path('/category/icon/'), $iconName);  
$category->icon = $icon_path;
//save the image path to db 
$category->save();
return redirect('/category/index')->with('success' , 'Category Stored Successfully');
  

с некоторыми изменениями, чтобы соответствовать вашему коду, он должен работать правильно

Ответ №2:

Я столкнулся с аналогичной проблемой и решил ее следующим образом

Чтобы загрузить файл по любому пути, выполните следующие действия.

Создайте новый диск в config/filesystem.php и укажите на него любой путь, который вам нравится, например, на D:/test или что-то еще

 'disks' => [

    // ...

     'archive' => [
            'driver' => 'local',
            'root' => 'D:/test',
         ],

    // ...

  

Помните archive , что это имя диска, которое вы можете изменить на любое.
После этого выполните config:cache

затем, чтобы загрузить файл в указанный каталог, выполните что-то вроде

   $request->file("image_file_identifier")->storeAs('SubFolderName', 'fileName', 'Disk');
  

например

   $request->file("image_file")->storeAs('images', 'aa.jpg', 'archive');
  

Теперь, чтобы получить файл, используйте следующий код

       $path = 'D:testimagesaa.jpg';



    if (!File::exists($path)) {
        abort(404);
    }

    $file = File::get($path);
    $type = File::mimeType($path);

    $response = Response::make($file, 200);
    $response->header("Content-Type", $type);

    return $response;


  

Комментарии:

1. «Чтобы загрузить файл на другой диск Windows, кроме этой папки хранения, выполните следующие действия». Я хочу загрузить файл в stroage.

2. @SvenvandenBoogaart я тогда указываю этот путь в config file

3. @SvenvandenBoogaart нравится 'disks' => [ // ... 'archive' => [ 'driver' => 'local', 'root' => 'D:/Documents/repos/projectname/storage/app', ],

4. @SvenvandenBoogaart я обновил свой ответ, надеюсь, это поможет вам, метод тот же, какой бы путь вы ни указали, загрузки будут сохранены

Ответ №3:

Я надеюсь, что вы используете здесь вмешательство в изображение. Если нет, вы можете запустить команду:

       composer require intervention/image
  

Это установит вмешательство в ваш проект. Теперь используйте следующий код для локальной загрузки изображений.

Вы можете вызвать функцию для сохранения изображений таким образом:

 if ($request->hasFile('image')) {
   $image = $request->file('image');
   //Define upload path
   $destinationPath = public_path('/storage/img/bathroom/');//this will be created inside public folder
   $filename = round(microtime(true) * 1000) . "." .$image->getClientOriginalExtension();

  //upload file
  $this->uploadFile($image,$destinationPath,$filename,300,300);

//put your code to Save In Database
//just save the $filename in the db. 

//put your return statements here    


}

    


public function  uploadFile($file,$destinationPath,$filename,$height=null,$width=null){
    
//create folder if does not exist
if (!File::exists($destinationPath)){
   File::makeDirectory($destinationPath, 0777, true, true);
}
    
//Resize the image before upload using Image        Intervention
            
if($height!=null amp;amp; $width!=null){
   $image_resize = Image::make($file->getRealPath());
   $image_resize->resize($width, $height);
   //Upload the resized image to the project path
   $image_resize->save($destinationPath.$filename);
}else{
     //upload the original image without resize. 
     $file->move($destinationPath,$filename);
     }
}
  

Если вы в любом случае хотите использовать фасад хранилища, я изменил ваш код с помощью Image-> resize()-> encode() перед использованием Storage::put(). Пожалуйста, посмотрите, работает ли следующий код. (Извините, у меня нет времени на тестирование)

 public function addPicture(Request $request, $id)
{
  $bathroom = Bathroom::withTrashed()->findOrFail($id);
  $validatedData = Validator::make($request->all(), [
    'afbeelding' =>'required|image|dimensions:min_width=400,min_height=400']);
if($validatedData->fails())
{
    return Response()->json([
        "success" => false,
        "errors" => $validatedData->errors()
    ]);
}
if ($file = $request->file('afbeelding')) {
    $img = Image::make($file);
    $img->resize(3000, 3000, function ($constraint) {
        $constraint->aspectRatio();
        $constraint->upsize();
    });
    //Encode the image if you want to use Storage::put(),this is important step
    $img->encode('jpg',100);//default quality is 90,i passed 100
    $uid = Str::uuid();
    $fileName = Str::slug($bathroom->name . $uid).'.jpg';

    $this->createImage($img, 3000, "high", $bathroom->id, $fileName);
    $this->createImage($img, 1000, "med", $bathroom->id, $fileName);
    $this->createImage($img, 700, "thumb", $bathroom->id, $fileName);
    $this->createImage($img, 400, "small", $bathroom->id, $fileName);

    $picture = new Picture();
    $picture->url = '-';
    $picture->priority = '99';
    $picture->alt = Str::limit($bathroom->description,100);
    $picture->margin = 0;
    $picture->path = $fileName;
    $picture->bathroom_id = $id;
    $picture->save();

    return Response()->json([
        "success" => true,
        "image" => asset('/storage/img/bathroom/'.$id.'/small/'.$fileName),
        "id" => $picture->id
    ]);
}
return Response()->json([
    "success" => false,
    "image" => ''
]);
}
  public function createImage($img, $size, $quality, $bathroomId,$fileName){
$img->resize($size, $size, function ($constraint) {
    $constraint->aspectRatio();
    $constraint->upsize();
});
Storage::put(  $this->getUploadPath($bathroomId, $fileName, $quality), $img);

}
public function  getUploadPath($bathroom_id, $filename, $quality ='high'){
$returnPath = asset('/storage/img/bathroom/'.$bathroom_id.'/'.$quality.'/'.$filename);
return $returnPath; //changed echo to return

}
  

Используемый источник: репозиторий вмешательства, Github

Также, пожалуйста, обратите внимание, что метод хранения put работает с выводом изображения для вмешательства, тогда как метод PutFile работает как с IlluminateHttp UploadedFile, так и с IlluminateHttpFile и экземплярами.

Комментарии:

1. Я использую обработку изображений, но моя цель — использовать фасад хранилища laravel.

2. @SvenvandenBoogaart Я обновил свой ответ, если вы хотите использовать фасад хранилища. Пожалуйста, проверьте, работает ли это. Я не тестировал код.

Ответ №4:

я рекомендовал использовать функции из хранилища laravel, которые просты для любой загрузки