تجربه آپلود تصاویر با کدگذاری base64 در لاراول

سلام ^_^

موضوع چیه ؟

اگه شما هم از پلاگین های جاوااسکریپتی استفاده کرده باشین حتما لازمتون شده که تصویر رو به صورت کدگذاری شده برای API ارسال کنین. توی این پست قصد دارم هم اعتبارسنجی (Validation) تصویر رو انجام بدم و هم ذخیره سازی روی دیسک.


چی لازم دارم ؟

باید یه اعتبارسنج بنویسم که بتونم به صورت زیر ازش استفاده کنم :


و البته خوبه که یک مبدل داشته باشم که تصویر کدگذاری شده رو بازیابی کنه و اطلاعات فایل رو برگردونه.


من چیکار کردم ؟

ابتدا یک هلپر (Helper) برای تبدیل فایل کدگذاری شده نوشتم :

هلپر برای آماده سازی فایل کدگذاری شده
هلپر برای آماده سازی فایل کدگذاری شده


این تابع رشته ی ورودی از سمت کاربر رو میگیره و اطلاعات کامل فایل رو برمیگردونه.


چطور اعتبارسنجی کردم ؟

حالا باید کلاس اعتبارسنج لاراول (Validator) رو توسعه بدم و متد دلخواه خودم رو به اون اضافه کنم. طبق مستندات لاراول سه روش برای این کار وجود داره که من ساده ترینش رو انتخاب می کنم ^_^


داخل متد boot از کلاس AppServiceProvider کد های زیر رو اضافه می کنم :

خب اینم از اعتبارسنجمون.


چطور ذخیره اش کردم ؟

حالا توی کنترلر تصویر رو دریافت و ذخیره می کنم.

به همین سادگی !

الان تصویرمون به خوبی و خوشی آپلود میشه ^_^



سپاسگزارم که تا اینجا رو خوندین، بیشتر سپاسگزار خواهم بود اگر دیدگاهتون رو هم با من به اشتراک بذارین
کد ها رو در ادامه مطلب قرار دادم
فقط الگوی regex رو نمیشه اینجا وارد کرد، به طور خودکار حذف میشه !


کد ها :

بخش اول :‌

/****************** 1 **********************/
function decodeBase64File( $encodedFile )
{
     // اینجا اطلاعات اضافی رو پاک میکنم تا کد اصلی رو بگیرم
     $file = str_replace(' ', '+', $encodedFile );
     $file = substr( $file, strpos( $file,';base64,' ) + 8 );
     $decodedFile = base64_decode($file);      
     
     // با کمک توابع پی اچ پی، مشخصات فایل رو بررسی می کنم      
     $fileMimeType = finfo_buffer( finfo_open() , $decodedFile , FILEINFO_MIME_TYPE );   
     $fileExt = substr($fileMimeType, strpos($fileMimeType,'/')+1);      
     
     return [         
          'file' => $decodedFile, // فایل آماده برای ذخیره سازی در دیسک         
          'mime'  => $fileMimeType, // نوع فایل        
          'ext'   => $fileExt, // اکستنشن فایل         
          'size'  => (int)strlen( $decodedFile ) // حجم فایل با واحد بایت     
     ]; 
}


بخش دوم :



/****************** 2 **********************/
Validator::extend(
     'base64image',
     function($attribute, $value, $params, $validator)
     {
          // اگه پارامتری برای اعتبارسنج ثبت نشه مقادیر پیش فرض زیر رو میگیره
          $validExtensions = $params ?: ['png','jpeg','bmp','gif','webp'];
     
          // الگوی تصاویر کدگذاری شده با بیس64 به این صورته
          $pattern = "****";
          // اگه طبق الگو نبود خب خطا داره :)
          if(!preg_match( $pattern , $value)) return false;
     
          // اطلاعات ارسالی رو  به هلپری که قبلا نوشتم میدم تا صحیح بودنش رو چک کنم
          $decodedImage = decodeBase64File($value);
     
          // اینم آخرین گام اعتبار سنجی
          // چک میکنیم که اکستنشن فایل، جزو آرایه ی پارامترهای ورودی باشه
          return in_array( $decodedImage['ext'] , $validExtensions );
     }
);


بخش سوم :

/****************** 3 **********************/
$validator = Validator::make($request->all(), [
    'image' => 'required|base64image:png,jpeg' // از همون اعتبارسنج خودم استفاده میکنم 
]);

if ($validator->fails())  return abort(400 , $validator->errors());

// اطلاعات تصویر آپلود شده رو میگیرم
$imageData = decodeBase64File($request->image);
$extension = $imageData['ext'];
$file= $imageData['file'];

// اسم فایل رو انتخاب میکنم
$imageName = 'uploaded_image.'.$extension;

// فایل رو یه جایی که میخوام ذخیره می کنم 
Storage::put('uploads/'.$imageName , $file );