0

I have a laravel project that has a image upload. I used image intervention library for uploading. The problem is i got a 500 error and saying Malformed UTF-8 characters, possibly incorrectly encoded. But when I look my directory for saving, the image was saved but the data was not saved to the database. Only the image was saved. Seems like the image save was successful but the request is not. What seems to be the problem?

Controller

 public function store(Request $request)
    {
        $product = new Product;
        $validator = \Validator::make($request->all(), [
            'product_name' => 'required',
            'barcode' => 'required|unique:products',
            'price'=> 'required',
            'category' => 'required',
            'supplier' => 'required',
            // 'image' => 'required|image64:jpeg,jpg,png'
        ]);

        if ($validator->fails()) {
            $errors = json_encode($validator->errors());
            return response()->json([
                'success' => false,
                'message' => $errors
            ],422);
        } else {
            $product->barcode = $request->barcode;
            $product->product_name = $request->product_name;
            $product->price = $request->price;
            $product->quantity = 0;
            $product->category = $request->category;
            $product->supplier_id = $request->supplier;

            //image
            $imageData = $request->image;
            $fileName = time().'.'. explode('/', explode(':', substr($imageData, 0, strpos($imageData, ';'))) [1])[1];
            $product->image = \Image::make($request->image)->save(public_path('img/').$fileName);

            $product->save();

            broadcast(new ProductsEvent(\Auth::user()->name, 'add', $product))->toOthers();
        }
    }

Vue component event when form is changed

  onFileChange(e) {
                let file = e.target.files[0];
                console.log(file);
                var reader = new FileReader();
                reader.onloadend = (file)=>{this.image = reader.result}
                reader.readAsDataURL(file);
            },        
draw134
  • 1,053
  • 4
  • 35
  • 84

2 Answers2

1

It seems that problem is appearing in your $filename generation.

As long as you have the correct image saved the naming convention is all in your hands.

I'd recommend you to go with simpler approach like $fileName = now()->timestamp . '_' . $imageData->name; and there would be no need for you to go fancy with the name of the file.

The value of the $imageData can not be predicted and all the operations you execute could lead to that problem.

The question has been already asked Laravel "Malformed UTF-8 characters, possibly incorrectly encoded", how to fix?

--- Edit ---

You can get the filename directly from your javascript as you do all the manipulation at that end so you could for example add this.name = file.name; to your sent data, then in your ajax you can send that data like so -

axios.post('/image/store',{
    image: this.image,
    imageName: this.name
}).then(response => {...});

in your backend $fileName = now()->timestamp . '_' . $request->imageName;

  • also have a look at https://stackoverflow.com/questions/31115982/malformed-utf-8-characters-possibly-incorrectly-encoded-in-laravel/38398648 – Martin Daskalov May 14 '20 at 17:35
  • i cannot write the image with like this `$fileName = now()->timestamp . '_' . $imageData->name;` since it is encoded with `base64` from my front end – draw134 May 14 '20 at 17:38
  • So then in your js you could send the filename with the request, or simply save it only as a timestamp as it will be unique `$fileName = now()->timestamp . '.jpg'` (extension can be get by regex, or still send by the js) – Martin Daskalov May 14 '20 at 17:45
0

The problem was this line, I was saving the actual image object in the db.

 $product->image = \Image::make($request->image)->save(public_path('img/').$fileName);

I changed it into

$imageData = $request->image;
$fileName = time().'.'. explode('/', explode(':', substr($imageData, 0, strpos($imageData, ';'))) [1])[1];

\Image::make($request->image)->save(public_path('img/').$fileName);

$product->image = $fileName;
$product->save();;
draw134
  • 1,053
  • 4
  • 35
  • 84