اذهب إلى المحتوى

سمير عبود

الأعضاء
  • المساهمات

    3558
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    34

كل منشورات العضو سمير عبود

  1. في لغة بايثون لجمع عناصر مصفوفة نستخدم الدالة sum: print(sum([1, 2, 3])) # 6 لترتيب عناصر مصفوفة نستخدم الدالة sorted: print(sorted([11, 2, 1, 9, 7])) # [1, 2, 7, 9, 11] الدالة sorted تُرتب تصاعدياً لقلب الترتيب نستخدم الدالة sorted و نُمرر لها مُعامل آخر: print(sorted([11, 2, 1, 9, 7], reverse=True)) # [11, 9, 7, 2, 1] لأخذ قطعة من مصفوفة نستخدم slice كما هو موضح أدناه: a[start:stop] # نُحدد البداية و النهاية مثلاً: print([11, 2, 1, 9, 7][0:3]) # [11, 2, 1] إجمع كل هذه النقاط مع بعض للوصول للشيء الذي تُريده أولاً الترتيب بشكل تنازلي ثانياً أخذ قطعة من المصفوفة المرتبة مكونة من 3 أعداد ثم إستعمال الدالة sum. و هذا مثال بسيط: print(sum(sorted([11, 2, 1, 9, 7], reverse=True)[0:3])) # 27 يُمكنك إستخدام هذه المراحل لإنشاء دالة تفعل ما تريد.
  2. الفكرة ككل هي في جلب رقم الآحاد لعدد مُعين و نحصل على هذا الرقم بإجراء قسمة إقليدية للعدد على 10 حيث باقي القسمة هو رقم الآحاد مثلاً لنأخذ العدد 62 عندما نقسمه على 10 نتحصل على 6 و باقي قسمة هو 2 و هو الرقم المطلوب. غالباً في لغات البرمجة علامة باقي القسمة هي: % بعد هذه المعلومة تُصبح الأمور واضحة المعالم فكل ما يتبقى لك هو تعريف دالة تستقبل مُعامل واحد بالشكل التالي مثلاً بلغة بايثون: def sumRightDigit(numbers): تعريف متغير داخل الدالة لتخزين المجموع و إسناد القيمة 0 له: def sumRightDigit(numbers): sum = 0 عمل حلقة على عناصر المصفوفة و إضافة رقم الآحاد في كل لفة من الحلقة. def sumRightDigit(numbers): sum = 0 for number in numbers: sum += number % 10 في الأخير إرجاع قيمة المُتغير الذي يحمل مجموع الآحاد، ثم إستخدام الدالة: def sumRightDigit(numbers): sum = 0 for number in numbers: sum += number % 10 return sum print(sumRightDigit([10,21,3,8,9,11,44,62,100])) # 28 بنفس الطريقة يُمكننا إستخدام لغة جافاسكربت الفرق فقط في بعض الsyntax: function sumRightDigit(numbers) { sum = 0 for (i in numbers) sum += numbers[i] % 10 return sum } console.log(sumRightDigit([10,21,3,8,9,11,44,62,100])) // 28 إتبع نفس الطريقة في اي لغة تريد.
  3. بما أنك تستخدم الحزمة عبر API فإنك تحتاج إلى إستخدام stateless في كل من الطلب الأول و الطلب الثاني فبدل: <?php Socialite::with('facebook')->stateless()->redirect()->getTargetUrl(); $fb_user = Socialite::with('facebook')->user(); إستخدم: <?php Socialite::with('facebook')->stateless()->redirect()->getTargetUrl(); $fb_user = Socialite::with('facebook')->stateless()->user();
  4. يُمكنك إستخدام حزمة symfony/process فلارافيل تستخدمها من المفروض تكون مُثبتة مُسبقاً مع الإعتماديات. للتأكد أنها مُثبتة: composer show symfony/process أمر التثبيت: composer require symfony/process الإستخدام: <?php // إستدعاء الكلاسات use Symfony\Component\Process\Process; use Symfony\Component\Process\Exception\ProcessFailedException; // الإستخدام $process = new Process(['python','/path/to/your_script.py']); $process->run(); if (!$process->isSuccessful()) { throw new ProcessFailedException($process); } echo $process->getOutput();
  5. حتى تستطيع إستخدام التحميل الحثيث بإستخدام التابع with يجب عليك تحديد المفتاح الثانوي ضمن الحقول التي تختارها في التابع select تأكد تماما أن إسم المفتاح الثانوي هو payment_method_category_id ثم قم بتغيير: return PaymentMethod::select('name', 'slug') ->with(['category' => function($query){ $query->select('id', 'name')->where('status', 1); }])->get(); إلى الشكل التالي بإضافة تحديد حقل المفتاح الثانوي: <?php return PaymentMethod::select('name', 'slug', 'payment_method_category_id') ->with(['category' => function($query){ $query->select('id', 'name')->where('status', 1); }])->get(); و بهذا الشكل سيتم إرجاع بيانات العلاقة بنفس الحقول التي حددتها.
  6. أولا يجب إضافة قواعد التحقق في المُكون بالشكل التالي مثلاً: protected $rules = [ 'title' => 'required|min:10', 'description' => 'required' ]; بعد ذلك تستدعي دالة التحقق في الدالة addTask: <?php public function addTask() { $this->validate(); // ... } ثم تضيف التابع updated للمُكون ليُصبح بالشكل التالي: <?php class AppAddTask extends Component { public $title; public $description; protected $rules = [ 'title' => 'required|min:10', 'description' => 'required' ]; public function render() { return view('livewire.app-add-task'); } public function updated($property) { $this->validateOnly($property); } public function addTask() { $this->validate(); // ... } } ثم في صفحة عرض المُكون تعرض رسائل الخطأ: <div> <h3 class="text-center">Add New Task</h3> <div class="form-group"> <label for="title">Title</label> <input type="text" wire:model="title" class="form-control @error('title') is-invalid @enderror"> @error('title') <span class="error" role="alert"> <strong class="text-danger">{{ $message }}</strong> </span> @enderror </div> <div class="form-group"> <label for="description">Description</label> <textarea wire:model="description" class="form-control @error('description') is-invalid @enderror"></textarea> @error('description') <span class="error" role="alert"> <strong class="text-danger">{{ $message }}</strong> </span> @enderror </div> <div class="form-group"> <button wire:click.prevent="addTask" class="btn btn-primary btn-block">Add</button> </div> </div> و بهذا الشكل سيتم التحقق في الوقت الفعلي و يتم عرض أي رسالة خطأ إن وجدت.
  7. الأفضل دائماً إستخدام إطار عمل جاهز عند إنشاء مشاريعك التي تريد أن تطلقها على شبكة الإنترنيت أو مشاريع لعُملائك لأن هناك العديد من الثغرات و المشاكل التي قابلت المُطورين من قبل و قامو بإيجاد حل لها في أطر العمل و هذا من أجل حماية موقعك و ضمان خصوصية مستخدمين تطبيقك. و لهذا تجد مُعظم الخبراء في المجال ينصحون بهذا الأمر فإطار العمل لا يُسهل و يُسرع الإنتاجية فقط و إنما يحميك من مُعظم الثغرات الموجودة، و إذا حاولت أن تُعالج موضوع الحماية بنفسك ستتعب كثيراً و ستقل إنتاجيتك فبدل أن تُركز على خصائص التطبيق نفسه تجد نفسك تبحث عن الثغرات و كيفية مُعالجتها خصوصاً إن كان الشخص مبتدئ و لا يفقه شيء في مواضيع الحماية. أيضاً عملية صيانة و تحديث المواقع في أطر العمل تكون سهلة مُقارنة ب php native. أخيراً إن كنت تريد التعلم فلا مانع من إستخدام php native لكن في مشاريعك الحقيقية الأفضل إستخدام إطار عمل، أما إن كنت تريد أخذ المُخاطرة فأنت حر في ذلك.
  8. يُمكنك إستخدام الtrait WithPagination الذي يسمح لك بإضافة التصفح لمكون livewire ثم تحدد القالب على أنه bootstrap بهذا الشكل: use Livewire\WithPagination; class AppTasks extends Component { use WithPagination; protected $paginationTheme = 'bootstrap'; protected $listeners = ['taskAdded' => '$refresh']; public function render() { $totalTasks = auth()->user()->tasks()->count(); $tasks = auth()->user()->tasks()->latest()->paginate(5); return view('livewire.app-tasks', [ 'totalTasks' => $totalTasks, 'tasks' => $tasks ]); } } ثم إضافة السطر: {{ $tasks->links() }} لصفحة العرض. و سيظهر ترقيم الصفحات بشكل عادي، يُمكنك أيضاً إستخدام قالب خاص بك للصفحات إن رغبت في ذلك و الطريقة موجودة في التوثيق الرسمي : Pagination
  9. نعم فالفكرة تكمن في إستخدام الأحداث و هناك عدة طرق لإستخدامها من بينها إرسال أو عمل emit للحدث من خلال المُكون الأول و التسمع على الحدث في المُكون الثاني لكن بما أننا نريد عمل تحديث ف livewire توفر طريقة خاصة إسمها $refresh، يُمكن التعامل مع الأحداث بعدة طرق عن طريق القالب أو عن طريق كلاس المُكون أو عن طريق javascript و هذا شرح الطريقة الثانية: إرسال الحدث من المكون الأول: class AppAddTask extends Component { public $title; public function render() { return view('livewire.app-add-task'); } public function addTask() { auth()->user()->tasks()->create([ 'title' => $this->title, 'status' => false, ]); $this->title = ""; $this->emit('taskAdded'); // هنا قمنا بإرسال الحدث } } التسمع على الحدث من خلال المُكون الثاني و عمل refresh: class AppTasks extends Component { protected $listeners = ['taskAdded' => '$refresh']; // التسمع و عمل تحديث public function render() { $totalTasks = auth()->user()->tasks()->count(); $tasks = auth()->user()->tasks()->latest()->get(); return view('livewire.app-tasks', [ 'totalTasks' => $totalTasks, 'tasks' => $tasks ]); } }
  10. هذا غالباً يحدث بسبب فشل ال validation حيث أنك تتحقق من mime type لكن في الإختبار الملف الوهمي لا يحتوي على نفس mime type هنا: <?php $file = UploadedFile::fake()->create( 'video.mp4', $sizeInKilobytes, 'mp4' ); لذلك حاول تغيير هذه الأسطر: <?php $file = UploadedFile::fake()->create( 'video.mp4', $sizeInKilobytes, 'mp4' ); إلى mime type صحيح بهذا الشكل: <?php $file = UploadedFile::fake()->create( 'video.mp4', $sizeInKilobytes, 'video/mp4' );
  11. المُشكلة أن حقول الإدخال لا تكون موجودة عند تحميل الصفحة و إنما يتم إضافتها عن طريق جافاسكربت فيما بعد، لذلك حتى تعمل يجب أن تُغير هذه: $(function () { $('.marker-hight-production, .layers-count').keyup (function() { let x = $(".marker-hight-production").val(), y = $(".layers-count").val(); $('.consumption-m').val(x * y); }); }); إلى هذا الشكل: $(function () { $(document).on('keyup', '.marker-hight-production, .layers-count', function() { let x = $(".marker-hight-production").val(), y = $(".layers-count").val(); $('.consumption-m').val(x * y); }); }); و ستعمل.
  12. نعم يُمكنك عمل ذلك بإستخدام بإستخدام مُعامل الشرط الثلاثي داخل الدالة update كما هو موضح أدناه: <?php Company::find($id)->update([ 'company_name' => $request->company_name, 'former_company' => $request->former_company ] + ($imageName ? [ 'company_logo' => $imageName ] : [])); و هذا يعني أننا نريد إضافة مصفوفة جديدة للمصفوفة الأولى تضم الحقل company_name في حالة ما إذا كان imageName لا يساوي null أما في الحالة المُعاكسة نضيف مصفوفة فارغة. أو يُمكنك إستخدام التالي: <?php Company::find($id)->update($request->only('company_name', 'former_company') + ($imageName ? [ 'company_logo' => $imageName ] : [])); هذا بطريقة مُختصرة يُمكنك أيضاً إنشاء المصفوفة خارج الدالة update. ثم تتفحص إن كان imageName يساوي null و على أساسه تضيف حقل جديد للمصفوفة ثم تمررها للدالة update
  13. يوجد ملفات ناقصة، لا يُمكنني تجربة المشروع بدونها، و لا أدري ماهي المُشكلة أو الخطأ الذي يظهر لك.
  14. هل يُمكنك رفع الملفات التي تعمل عليها حتى أجرب عندي و أخبرك بالحل
  15. يُمكنك عمل ذلك عن طريق التالي: لنفترض أنه لديك الحقول بالشكل التالي: <input type="number" class="marker-hight-production" placeholder="marker-hight-production" value="0"> <input type="number" class="layers-count" placeholder="layers-count" value="0"> <input type="number" class="consumption-m" placeholder="consumption-m"> بعد ذلك يُمكنك إستخدام jQuery للتسمع على حدث keyup أو الحدث الذي تريده في كل من الحقلين و على أساسه تقوم بتغير قيمة الحقل الثالث كما هو موضح أدناه: $(function () { $('.marker-hight-production, .layers-count').on('keyup', function() { let x = $(".marker-hight-production").val(), y = $(".layers-count").val(); $('.consumption-m').val(x * y); }); }); و هذه الpen توضح العملية: إضغط هنا
  16. يُمكنك إستخدام when بالشكل التالي: $getSales = Shoppingcart::when($this->searchTerm, function ($query, $searchTerm) { return $query->where('trans_code', 'LIKE', "%{$searchTerm}%"); }, function ($query) { return $query->with('user'); })->select('trans_code', 'created_at', DB::raw("SUM(sub_total) as total")) ->groupBy('trans_code') ->paginate(10); يُمكنك الإطلاع على توثيق موسوعة حسوب: البنود المشروطة (Conditional Clauses) و ستجد مثال يُشابه لما تريد في هذه الفقرة: يُنفّذ التابع when النطاق المُغلق المحدّد Closure فقط عندما تكون المعاملة الأولى true. في حالة كانت المعاملة الأولى false لن يُنفّذ النطاق المغلق Closure. تستطيع تمرير نطاق مُغلق Closure آخر كثالث معامل للتابع when. سيُنفّذ هذا النطاق المُغلق في حالة كانت المعاملة الأولى false.
  17. هذه المُشكلة تحدث لأن الأمر: php artisan queue:work سيُواصل العمل لحين يتم إنهاؤه يدوياً او إغلاق الطرفية. لذلك laravel تُوفر الأمر: php artisan queue:work --tries=3 يُمكنك تمرير عدد مرات المُحاولة بإستخدام --tries لتجنب الحلقة الغير مُنتهية التي تحدث بسبب خطأ في تنفيذ ال job و لمعرفة الخطأ الذي يُسبب المُشكلة يُمكنك الإطلاع على ملف laravel.log و ستجد سبب المُشكلة أيضاً يُمكنك الإطلاع على جدول failed_jobs في العمود exception لتعرف سبب المُشكلة إذا كنت تستخدم database driver.
  18. إذا كان المطلوب هو حساب مجموع عناصر كل مصفوفة جزئية و عرضه لوحده يُمكنك إستخدام حلقة foreach عادية بهذا الشكل: <?php $matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; foreach ($matrix as $numbers) { $sum = 0; foreach ($numbers as $number) { $sum += $number; } echo "$sum \n"; } او يُمكنك إستخدام الدالة array_sum بهذا الشكل: <?php $matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; foreach ($matrix as $numbers) { $sum = array_sum($numbers); echo "$sum \n"; }
  19. للتخلص من الإستعلامات الإضافية او تخفيض عدد الإستعلامات إستخدم دائماً التحميل الحثيث Eager loading او التحميل المُسبق للعلاقات لأنه عند إستخدامك للعلاقة كخاصية من دون التحميل الحثيث سيتم إجراء إستعلام إضافي في كل مرة و هذه المُشكلة تُسمى ب N + 1 أي من أجل كل كائن تستعلم N مرة إضافية. ففي حالتك مثلاً: في النموذج Comment public function children() { return $this->hasMany(Comment::class, 'parent_id'); } في المُتحكم: public function show($slug) { $article = Article::with(['comments' => function ($query) { $query->with('children')->where('status', true); }])->where('slug', $slug)->firstOrFail(); return view('article.show', compact('article')); } في صفحة العرض تكون بهذا الشكل مثلاً: @foreach($article->comments as $comment) {{ $comment->body }} @foreach($comment->children as $subComment) {{ $subComment->body }} @endforeach @endforeach
  20. مرحباً @آية جمال سالم و عليكم السلام: يمكنكِ الاستفسار عن ذلك عن طريق التواصل مع مركز المساعدة عبر الرابط التالي: مركز المُساعدة تواصلي معهم وسيقومون بتوضيح ما تريدين بكل سهولة وشفافية.
  21. المُشكلة التي ظهرت لك بسبب هذا السطر: let name = fares; لان جافاسكربت لا تعرف الكلمة fares فهي ليست كلمة محجوزة في اللغة، كما أنه لا يوجد في السكربت أي مُتغير بالإسم fares. أعتقد أنك تريد تعريف مُتغير name و إسناد إسمك له كقيمة. لكن لعمل هذا تحتاج أن تُخبر جافاسكرت بأنه نص بإستعمال علامتي التنصيص بهذا الشكل مثلاً: let name = "fares"; و هذا ما تُوضحه رسالة الخطأ: Uncaught ReferenceError: fares is not defined
  22. يُمكنك عمل هذا الأمر بإستخدام أحد هذه الطرق: تمرير قيمة ال slug أثناء إنشاء السجل في المُتحكم: <?php use Illuminate\Support\Str; Post::create([ 'title' => request('title'), 'body' => request('body'), 'slug' => Str::slug(request('title')) ]); إعادة تعريف الدالة boot في المُتحكم Post و التسمع على الحدث creating: <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Post extends Model { use HasFactory; protected $guarded = []; protected static function boot() { parent::boot(); static::creating(function ($post) { $post->slug = Str::slug($post->title); }); } } يُمكن التسمع على عدة أحداث: creating، created ، deleting، deleted، updating، updated ... لكن إن كانت الأحداث التي تُريد التسمع عليها كثيرة و ترغب بعمل شيء ما عند كل حدث فسيُصبح النموذج مُكتض بالشيفرات و ستصعب عليك عملية ال refactoring ففي هذه الحالة الأفضل إستخدام مُراقب (observer) لهذا النموذج. إستخدام مراقب (observer): أولاً إنشاء المُراقب: php artisan make:observer PostObserver --model=Post سيُنشئ الأمر ملف جديد في المسار: app/Observers و من خلاله يُمكنك مراقبة النموذج الخاص بك. ثانياً في حالتنا سنُضيف الدالة: creating : <?php namespace App\Observers; use App\Models\Post; use Illuminate\Support\Str; class PostObserver { public function creating(Post $post) { $post->slug = Str::slug($post->title); } // others methods } ثالثاً نقوم بربط المُراقب بالنموذج الذي سيُراقبه و يتم ذلك على مُستوى مُزود الخدمة EventServiceProvider في الدالة boot: <?php use App\Models\Post; use App\Observers\PostObserver; public function boot() { Post::observe(PostObserver::class); }
  23. يُمكن أيضاً إستخدام حزمة Laravel Localization التي تُوفر العديد من الميزات فيما يخص موضوع localization تثبيت الحزمة: composer require mcamara/laravel-localization إستدعاء ملف إعدادات الحزمة ضمن ملفات المشروع: php artisan vendor:publish --provider="Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider" سيتم إنشاء ملف config/laravellocalization.php الذي من خلاله يُمكنك تحديد اللغات التي سيدعمها المشروع بالإضافة إلى بعض الإعدادات الأخرى. إضافة ال middlewares الخاصة بالحزمة ضمن ملف app/Http/Kernel.php: <?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel { /** * The application's route middleware. * * @var array */ protected $routeMiddleware = [ /**** OTHER MIDDLEWARE ****/ 'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class, 'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class, 'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class, 'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class, 'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class ]; } بعد ذلك يُمكنك إستخدام الحزمة: في المسارات: // routes/web.php Route::group(['prefix' => LaravelLocalization::setLocale()], function() { /** المسارات التي تعتمد على عدة لغات **/ }); /** المسارات الأخرى **/ أما في العرض: <ul> @foreach(LaravelLocalization::getSupportedLocales() as $localeCode => $properties) <li> <a rel="alternate" hreflang="{{ $localeCode }}" href="{{ LaravelLocalization::getLocalizedURL($localeCode, null, [], true) }}"> {{ $properties['native'] }} </a> </li> @endforeach </ul> لمعلومات أكثر يُمكنك تصفح توثيق الحزمة.
  24. يُمكنك ذلك من خلال إنشاء ملف php عادي في أي مسار تريده مثلاً في: tests |_ Utilities |_|___ functions.php و تضع الدوال التي تحتاجها فيه مثلاً: <?php function create($class, $attributes = []) { return $class::factory()->create($attributes); } function make($class, $attributes = []) { return $class::factory()->make($attributes); } الآن ستقوم بإضافة عملية التحميل التلقائي للملف من خلال composer و لعمل ذلك تحتاج التعديل على ملف composer.json: إن كنت تحتاج أن تتم عملية التحميل التلقائي للملف فقط في مرحلة التطوير ستُضيف مسار الملف داخل مصفوفة files ضمن الخاصية autoload-dev: "autoload-dev": { "psr-4": { "Tests\\": "tests/" }, "files": ["tests/Utilities/functions.php"] }, أما إن أردت أن تشمل العملية مرحلة الإنتاج فستضع مسار الملف داخل مصفوفة files في الخاصية autoload: "autoload": { "psr-4": { "App\\": "app/", "Database\\Factories\\": "database/factories/", "Database\\Seeders\\": "database/seeders/" }, "files": ["tests/Utilities/functions.php"] }, بعد ذلك قم بتنفيذ أمر: composer dump-autoload ثم ستتمكن من إستخدام الدوال التي أنشأتها في أي مكان تريد، في المثال أرفقت دالتين إحداهما لإنشاء سجل جديد من نموذج معين و الثانية تُنشئ السجل و تقوم بتخزينه في قاعدة البيانات، و هاتين الدالتين تحتاج لهما كثيرا في الإختبارات: و هذا مثال عن إستخدامها: <?php /** @test */ function an_authenticated_user_may_participate_in_forum_threads() { $this->signIn(); $reply = make(Reply::class); $this->post($this->thread->path . "/replies", $reply->toArray()); $this->get($this->thread->path) ->assertSee($reply->body); }
  25. تحدث هذه المُشكلة لك بسبب أنك حددت إسم المُجلد في المُعامل الأول للدالة put، مثلاً إن كنت تريد وضع الملفات داخل مُجلد images يُمكنك ذلك من خلال: public function test(Request $request) { $fileInForm = 'file'; if ($request->hasFile($fileInForm)) { $file = $request->file($fileInForm); if ($file->isValid()) { // Filename is hashed filename + part of timestamp $hashedName = hash_file('md5', $file->path()); $timestamp = microtime(); $newFilename = $hashedName . $timestamp . '.' . $file->getClientOriginalExtension(); Storage::disk('local')->putFile('images', $file); } } } في هذه الحالة سيتم حفظ الملفات داخل مُجلد images و ستُعطي لارافيل إسم مُختلف للملف المرفوع في كل مرة تلقائياً، و ستُرجع الدالة putFile المسار الذي تم حفظ الملف فيه يُمكنك حفظه إن احتجت له. إن كنت ترغب في وضع الإسم الذي يُحفظ به الملف بنفسك يُمكنك إستخدام الدالة putFileAs بنفس الطريقة و تُمرر الإسم الذي ترغب فيه كمعامل ثالث: public function test(Request $request) { $fileInForm = 'file'; if ($request->hasFile($fileInForm)) { $file = $request->file($fileInForm); if ($file->isValid()) { // Filename is hashed filename + part of timestamp $hashedName = hash_file('md5', $file->path()); $timestamp = microtime(); $newFilename = $hashedName . $timestamp . '.' . $file->getClientOriginalExtension(); Storage::disk('local')->putFileAs('images', $file, $newFilename); } } } تُرجع الدالة أيضاً مسار الملف. تُتيح لارافيل أيضاً دالتي store و storeAs لكن هاتين الدالتين لا تُستخدمان بإستعمال الfacade بل مُباشرة على الملف بهذا الشكل مثلاً: $path = $request->file('file')->store('images'); $path = $request->file('file')->storeAs( 'images', $newName );
×
×
  • أضف...