يتوفّر إطار العمل Laravel على واجهة تطبيقات برمجيّة API موّحّدة للتعامل مع الملفات. تأتي واجهة التطبيقات هذه مجهّزة مبدئيا بتعريفات Drivers تمكّن من إدارة الملفات على نظام الملفات المحلّي، خادوم FTP أو على خدمتي Amazon S3 وRackspace السّحابيتين. سنعرض في هذا الدرس لأساسيّات إدارة الملفات: رفعها Upload، تخزينها والعثور عليها في الإصدار 5.3 من إطار العمل Laravel.
أقراص التخزين في Laravel
تُضبَط إعدادات تخزين الملفات ضمن الملف config/filesystems.php
عن طريق ما يُسمّيه Laravel الأقراص Disks. يُمثّل كل قرص تعريفا، مسارا للتخزين وإعدادات خاصّة بالقرص. يعرّف ملفّ الإعداد مبدئيا ثلاثة أقراص public
، local
وs3
:
'disks' => [ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), ], 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), 'visibility' => 'public', ], 's3' => [ 'driver' => 's3', 'key' => 'your-key', 'secret' => 'your-secret', 'region' => 'your-region', 'bucket' => 'your-bucket', ], ],
يستخدم القرصُ local
في المثال المبدئي أعلاه التعريفَ local
(نظام الملفات المحلّي) ومسار التخزين storage/app
. بالنسبة للقرص s3
فهو يستخدم التعريف s3
(خدمة Amazon S3) ويتطلّب قيما ضرورية للولوج إلى الخدمة.
يشبه القرص public
القرصَ local
؛ إلا أنّ بينهما فرقًا جوهريًّا: هذا القرص مهيّأ للملفات التي نريد إتاحتها للعموم. تُخزَّن ملفات هذا القرص على المسار storage/app/public
. يمكن ملاحظة أن المسار storage/app/public
يوجد خارج المجلّد public
الذي يحوي ملفّات المشروع المتاحة للعموم. نستخدم أمر Artisan التالي لجعل ملفات القرص public
متاحة على الوِب:
php artisan storage:link
ينشئ الأمر وصلة رمزيّة على المسار public/storage
ويجعلها تحيل إلىstorage/app/public
الذي هو مسار تخزين القرص public
. سنرى بعد قليل كيف نصل إلى الملفات الموجودة في هذا القرص.
ملحوظة: يتطلّب استخدام التعريفيْن s3
وrackspace
تثبيت الحزمتييْن التاليّتيْن على التوالي (عن طريق composer
):
league/flysystem-aws-s3-v3 ~1.0 league/flysystem-rackspace ~1.0
رفع ملفات وعرض روابطها في Laravel 5.3
سنهيّئ في بقيّة الدرس مشروع Laravel 5.3 للعمل عليه. سيكون هدفنا رفع صورة في المتصفّح ثم عرض هذه الصورة في صفحة الوِب.
نضيف مسارين إلى ملف مسارات الوِب routes/web.php
:
Route::get('image-upload','ImageController@imageUpload'); Route::post('image-upload','ImageController@imageUploadPost');
يتلقّى الإجراء get
طلبات عرض الصفحة، في ما نستخدم الإجراء post
لتخزين الصّورة المحمَّلة في الصفحة التي سننشئها بعد قليل.
الخطوة التاليّة هي إنشاء المتحكّم ImageController
وكتابة الدالتين imageUpload
وimageUploadPost
:
php artisan make:controller ImageController
كلّ ما تفعله الدالة imageUpload
هو استدعاء العرض image-upload
:
public function imageUpload() { return view('image-upload'); }
بالنسبة للدالة imageUploadPost
فستستقبل الصورة المحمّلة من المتصفّح، تخزّنها ثم ترسلها إلى image-upload
الذي يعرضها:
public function imageUploadPost(Request $request) { // TODO: return view('image-upload') ->with('message', "Image uploaded successfully") ->with('path', $imagePath); }
الدالة غير مكتملة لحد الساعة، فكل ما يظهر منها هو استدعاء القالب وتمرير رسالة إليه تفيد بنجاح رفع الصورة، إضافة إلى متغيّر يمثّل رابط الصورة. استقبال الصورة، تخزينها والحصول على رابط تخزينها سيكون محلّ التعليق TODO
.
ننشئ القالب image-upload
قبل العودة إلى الدالة imageUploadPost
.
ننشئ الملف image-upload.blade.php
على المسار resources/views
ونضع فيه المحتوى التالي:
<!DOCTYPE html> <html> <head> <title>Laravel 5.3 Image Upload example</title> </head> <body> <div> @if (isset($path)) <p>{{ $message }}</p> <img src="{{ url($path) }}"> @endif <form action="{{ url('image-upload') }}" enctype="multipart/form-data" method="POST"> {{ csrf_field() }} <div> <div> <input type="file" name="image" /> </div> <div> <button type="submit">Upload</button> </div> </div> </form> </div> </body> </html>
نتحقّق أولا، عن طريق الدالة isset
، من وجود متغيّر باسم path
في المعطيات الممرّرة إلى القالب. يمثّل المتغيّر path
مسار الصورة التي نعرضها في حال وجود المتغيّر path
. ثم يأتي دور استمارة الرّفع التي ترسل طلبا بإجراء POST
إلى المسار image-upload
. نحدّد نوع المُدخَل input
الذي نريد استقبال الصورة عن طريقه بالنوع file
ونحدّد اسمه بـimage
.
نستطيع الآن العودة إلى الدالة imageUploadPost
لإكمالها:
public function imageUploadPost(Request $request) { // TODO: return view('image-upload') ->with('message', "Image uploaded successfully") ->with('path', $imagePath); }
نستقبل الطلب في المعطى request
؛ حيث يمكننا تطبيق الدالة file
للحصول على الصورة التي حمّلها المتصفّح بتحديد اسم المُدخَل input
الذي استقبلها في صفحة الوٍب:
$request->file('image');
نطبّق على الملف الدالة store
لتخزينه:
$image = $request->file('image')->store('images', 'public');
تأخذ الدالة store
معطَيَيْن، الأول منهما هو اسم المجلّد حيثُ نريد تخزين الملفّ والثاني اسم القرص الذي نريد استخدامه. إن لم نحدّد اسمَ القرص فسيُستخدَم القرص المبدئي المعرّف بالتعليمة default
ضمن ملف الإعداد config/filesystems
(تأخذ التعليمة مبدئيا القيمة local
).
نريد أن تكون الصورة متاحة للعموم ضمن مجلد خاصّ بالصور اسمه images
، لذا نمرّر القيمتيْن images
وpublic
للمعطييْن الأول والثاني على التوالي.
خزّنا الآن الصورة على القرص المتاح للعموم. الخطوة التاليّة هي الحصول على مسارها من أجل إرساله إلى القالب image-upload
لعرضه. نستخدم الدالة url
ضمن الصنف Storage
والتي يمكن تطبيقها على أقراص تستخدم أحد التعريفيْن local
أو s3
:
$imagePath = Storage::url($image);
لا ننسى استيراد الصّنف Storage
:
use Illuminate\Support\Facades\Storage;
أصبحت دالة المتحكّم مكتملة على النحو التالي:
public function imageUploadPost(Request $request) { $image = $request->file('image')->store('images','public'); $imagePath = Storage::url($image); return view('image-upload') ->with('message', "Image uploaded successfully") ->with('path', $imagePath); }
لا ننسى إنشاء الوصلة الرمزية:
php artisan storage:link
نشغّل خادوم التطوير المضمَّن في Laravel:
php artisan serve
ثم نفتح المتصفّح لزيارة المسار http://localhost:8000/image-upload
. نختار صورة لرفعها ثم نضغط على الزّر Upload
. يخزّن Laravel الصّورة في المجلّد storage/app/public
، ثم يطلُب عرض القالب image-upload
مع تمرير رابط الصّورة في المتغيّر path
، إضافة إلى رسالة في المتغيّر message
تفيد بنجاح الرّفع.
ملحوظة: يختار Laravel عند استخدام الدالة store
اسما مميّزا للملف بتطبيق دالة تجزئة Hash عليه. إن أردت اختيار الاسم الذي يُخزَّن به الملف فيمكنك ذلك بالدالة storeAs
:
-
تخزين الملف في القرص المبدئي:
$image = $request->file('image')->storeAs('images','fileName');
-
تخزين الملف مع تحديد القرص:
$image = $request->file('image')->storeAs('images','fileName','public');
العمليّات على الملفات المرفوعة
يوفّر Laravel الصّنفَ Storage للتعامل مع الملفات والأقراص.
إضافة ملفات إلى التخزين
تُستخدَم الدالة put
في الصّنف Storage
لتخزين ملفات على النحو التالي:
Storage::put('images', $fileContents);
يُمثّل المعطى الأوّل الممرَّر إلى الدالة اسمَ المجلّد الذي تريد حفظ الملفّ فيه والثاني محتوى الملفّ. تستخدم الدالة أعلاه القرص المبدئي (التعليمة default
في ملف الإعداد). إن أردت استخدام قرص مغاير فيمكنك الاستعانة بالدالة disk
:
Storage::disk('public')->put('images', $fileContents);
يُحدَّد المجلّد المُمرَّر إلى الدالة put
(المعطَى الأول) اعتمادا على المسار الجذر للقرص المستخدَم؛ أي أن المقصود بالمجلّد images
في المثال السابق هو المجلد storage/app/public/images
؛ نظرا لكون storage/app/public
هو المسار الجذر للقرص public
. يُعيَّن المسار الجذر بالتعليمة root
أثناء إعداد الأقراص في ملف الإعداد config/filesystems
.
استرجاع ملف من التخزين
يتيح الصّنف Storage
الدالة get
لاسترجاع محتوى ملف مخزّن في القرص المبدئي:
$contents = Storage::get('images/file.jpg');
يمكن تحديد القرص المستهدَف باستدعاء الدالة disk
قبل تطبيق get
.
يتوفّر الصّنف Storage
على الدالة exists
التي تتيح التأكد من وجود الملفّ:
$exists = Storage::disk('s3')->exists('file.jpg');
الحصول على بيانات ملفّ
استخدم الدالة size
على النحو التالي لمعرفة حجم ملفّ موجود في القرص المبدئي:
$size = Storage::size('file1.jpg');
أو بتحديد القرص المستهدَف:
$size = Storage::disk('s3')->size('file1.jpg');
يمكن على نفس المنوال معرفة تاريخ آخر تعديل على الملف على صيغة ختم زمني Timestamp:
$time = Storage::lastModified('file1.jpg');
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.