-
المساهمات
5196 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
52
إجابات الأسئلة
-
إجابة Adnane Kadri سؤال في التحديث التلقائي لمحتوى ال div كانت الإجابة المقبولة
لن يمكنك فعل ذلك بإستعمال التابع load , لأن هذا التابع يسمح بتحميل HTML أو محتوى نصي من الخادم ثم إضافته إلى عنصر DOM .
أما لتحقيق غرضك فلن نحتاج إلا لتحديد العنصر الحاوي للمحتوى ثم إضافته إلى العنصر div . سيمكن إستعمال التابع append لهذا .
رغم أن فكرة تحميل محتوى موجود داخل الـ div و إعادة تضمينه في نفس العنصر غير منطقية إلا أن الشيفرة ستكون مشابه للتالي :
<div id="load_posts"></div> <script> setInterval(function(){ var content = $('#load_posts').html(); // $('#load_posts').html(''); لحذف المحتوى و إعادة تحميله $('#load_posts').append(content); }, 1000); </script>
-
إجابة Adnane Kadri سؤال في التحريك التلقائي للشريط الجانبي فى الشات كانت الإجابة المقبولة
يمكنك تحريك الشريط الجانبي للأسفل تماما مباشرة بعد نجاح عملية تحميل أية رسائل جديدة و إضافتها إلى الوثيقة .
أي إلى الدالة appendMessage .
قد لا نحتاج الدالة getMessages في هاته العملية .
أي أننا لا يجب أن نرغم المستخدم أن يكون الشريط الجانبي في أسفله تماما و دوما , و إنما أن يتم عمل التحريك التلقائي للشريط الجانبي بعد كل تضمين لعنصر رسالة جديد , و ذلك لعرضها .
أي أن الشيفرة الخاصة بالعملية ستتبع المنطق التالي :
const messages = document.getElementById('div_show_message'); function appendMessage() { const message = document.getElementsByClassName('message')[0]; const newMessage = message.cloneNode(true); messages.appendChild(newMessage); scrollToBottom(); } function scrollToBottom() { messages.scrollTop = messages.scrollHeight; } scrollToBottom();
-
إجابة Adnane Kadri سؤال في تثبيت برنامج ما على لينكس كانت الإجابة المقبولة
قد يختلف الأمر قليلا خصوصا لو كنت قادم من نظام تشغيل ويندوز , فلن تجد واجهة تفاعلية تخبرك بما عليك فعله . و سيتم كل ذلك عن طريق التارمنل . عن طريق ما يعرف بمدراء الحزم .
و بالطبع فإن الأمر ليس دستورا ثابتا , فهو يختلف من توزيعة لينكس إلى أخرى , و من مدير حزم إلى مدير اخر .
و لنأخذ على سبيل المثال توزيعة ubuntu الغنية عن التعريف .
في ubuntu يمكننا تثبيت البرنامج بـ 3 طرق مختلفة :
عن طريق مركز برمجيات أوبونتو أو Ubuntu Software Center : وهو عبارة عن برنامج يوفر واجهة تفاعلية يسهل من عليها استعراض البرامج المتوفرة و تثبيتها عن طريق ضغطة زر . قد توفر توزيعات أخرى نفس الفكرة . عن طريق snap : وهو مدير حزم يقوم بتحميل الحزم و تحميلها من متجر snap , يتوفر snap في عديد من توزيعات لينكس من مثل فيدوار و لينكس مينت . و سنحتاج للتارمنل في التعامل معه لأن snap لا يوفر واجهة تفاعلية . يتم تثبيت البرامج عن طريقه بأوامر مشابهة :
sudo snap install <app-name> عن طريق مدير الحزم apt : sudo apt install <app-name>
و كوننا قد قمنا بثتبيت البرنامج لن يجعل من المنطقي ان نقوم بتثبيته كل مرة غرض تشغيله , و بالتالي فإنك لن تحتاج ذلك و يكفي تثبيته مرة واحدة . و لتشغيل البرنامج نقوم إما بطباعة اسمه في التارمنل أو بالتصفح إليه في قائمة البرامج .
كما يمكنك إنشاء أيقونة سطح المكتب للوصول السهل إليها .
-
إجابة Adnane Kadri سؤال في خطأ fatal: Not a git repository (or any of the parent directories): .git كانت الإجابة المقبولة
يحاول الخطأ إخبارك أن المشروع الذي تحاول تطبيق الأمر فيه ليس مستودع git , و لذلك سنحتاج تحويله لذلك قبل عمل أي أوامر git عليه . يمكنك ذلك عن طريق الأمر :
git init قد تحتاج أيضا ربط ملفات مشروعك مع مستودعك البعيد عن طريق الأمرين :
git remote add origin https://your_gitrepo/some_repo ثم :
git branch -M main بعد ذلك يمكنك تطبيق الأوامر :
git add -A git commit -m "init commit" git push -u origin main
-
إجابة Adnane Kadri سؤال في ما هي أفضل قاعدة بيانات كانت الإجابة المقبولة
ينغبي الفهم أولا أن قاعدة البيانات ، ليست هي إلا مجموعة بيانات أو معلومات يتم تنظيمها لتسهيل تخزينها , استرجاعها , تعديلها وحذفها بالتزامن مع عمليات معالجة البيانات المختلفة . عادة ما يتم ذلك عن طريق نظم إدارة قواعد البيانات , و يشار إلى النظام نفسه مع البيانات بقواعد البيانات . أي أن الهدف واحد و السبل تختلف .
عادةً ما يتم نمذجة هاته البيانات الموجودة ضمن الأنواع الأكثر شيوعًا من قواعد البيانات الشغالة اليوم في : صفوف وأعمدة في سلسلة من الجداول لجعل المعالجة والاستعلام عن البيانات فعالا و أبعد قليلا عن التجريد . بحيث يمكن بعد ذلك الوصول إلى البيانات وإدارتها وتعديلها وتحديثها والتحكم فيها وتنظيمها بسهولة .
تستخدم معظم قواعد البيانات لغة الاستعلام المهيكلة (SQL) لكتابة البيانات والاستعلام عنها أو إدارتها .
يوجد العديد من أنواع قواعد البيانات المختلفة التي يمكن لمؤسسة أو برنامج ما إتباعها نذكر منها :
قواعد بيانات علائقية Relational databases : يمكن اعتبارها الأكثر شيوعا الان . بحيث يتم تنظيم العناصر الموجودة في قاعدة البيانات العلائقية كمجموعة من الجداول ذات الأعمدة والصفوف التي يمكن لها أن تحمل علاقات فيما بينها . قواعد بيانات كائنية التوجه Object-oriented databases : بحيث يتم تنظيم البيانات بشكل كائنات يسهل التعامل معها بمنطق مشابه لمنطق البرمجة الكائنية . قواعد بيانات موزعة Distributed databases : يتم تنظيم البيانات بشكل ملفات تكون موزعة على مكانين أو أكثر . قواعد بيانات غير علائقية NoSql: تعتبر الأفضل من ناحية تخزين البيانات غير المهيكلة unstructured و شبه المنظمة semistructured . واحدة من الأكثر شيوعا الان .
طبعا ليست هاته الأنواع الوحيدة فقط بل يوجد الكثير غيرها .. كل منها ينفرد بمنطقه و طريقة معالجته للبيانات و تخزينها .
و مثلما تم الإشارة فإنه يتم إدارتها عن طريق نظم إدارة قواعد البيانات (database management system) اختصارا : DBMS .بحيث يعمل كواجهة بين قاعدة البيانات والمستخدمين النهائيين أو البرامج ، مما يسمح للمستخدمين باسترداد وتحديث وإدارة كيفية تنظيم المعلومات وتحسينها . و أيضا الإشراف والتحكم في قواعد البيانات ، يوفر هذا مجموعة متنوعة من العمليات الإدارية مثل مراقبة الأداء والضبط والنسخ الاحتياطي والاسترداد و غيرها . و لنأخذ MySql كمثال :
MySQL هو نظام إدارة قواعد بيانات علائقية مفتوح المصدر يعتمد على SQL . تم تصميمه وتحسينه لتطبيقات الويب . كانت وراء بعض أفضل مواقع الويب و تطبيقات الويب في العالم ، أمثلة : Airbnb و Uber , LinkedIn , Facebook , Twitter , YouTube . و رغم أنها بالفعل خسرت بعض شعبيتها في الأعوام الأخيرة إلا أنه لا بأس في تعلمها و التعرف عليها و العمل بها , خصوصا في سوقنا العربي فهي :
سهلة التعلم. ما تزال شائعة ومهيمنة نوعا ما . توثيقها السهل و وفرة المعلومات حولها . متوفرة بشكل افتراضي في أغلب الاستضافات . مجانية . يمكنك القراءة عن Mysql أكثر هنا .
يمكنك أيضا التعرف أكثر على قواعد البيانات على بعض من نظم إدارة قواعد البيانات هنا .
كما يمكنك الاستزادة بقراءة بعض من مقالات الأكاديمية بهذا الشأن :
الأنواع السبعة لروابط الجداول في SQL مقارنة بين أنظمة إدارة قواعد البيانات العلاقية: SQLite مع MySQL مع PostgreSQL شرح الفروقات بين قواعد بيانات SQL ونظيراتها NoSQL -
إجابة Adnane Kadri سؤال في جعل webpack يتعرف على جميع ملفات javaScript كانت الإجابة المقبولة
يبدوا أنك تقوم بإخراج الملفات إلى ملف واحد . بالطبع ستحتاج تعديل المخرج أيضا , سنحتاج إخراج الملفات منفصلة بحسب إسم الملف .
فعوضا عن مثل هذا :
output:{ path:path.join(__dirname,"/dist"), filename:"main.js" }, نحتاج إخراج الملفات على هذا النحو :
output:{ path:path.join(__dirname,"/dist"), filename:"[name].js" }, حتى لا يحدث خطأ التعارض الذي ظهر معك , ثم يمكنك بعد ذلك تشغيل أمر البناء بشكل طبيعي :
npm run build
-
إجابة Adnane Kadri سؤال في كيفية اضافة حقل في قواعد البيانات لارافل كانت الإجابة المقبولة
أظن أن من الخطأ إستعمال نفس قواعد البيانات للتحقق Testing و حل المشاكل Debugging , بهاته الطريقة ستكون البيانات الحقيقية عرضة للفقدان كليا .
الطريق الأقصر : و هي الإستعانة بالكثير من الحلول البديلة من مثل :
تحضير نسخ إحتياطية Backups لقواعد البيانات قبل تجربة التطبيق أو قبل تحديث التهجير لقواعد البيانات , ثم إعادة التهجير بعد التحقق . تحضير نسخة إحتياطية تجريبية للتطبيق , يمكن إستعمال حزم من مثل laravel-backup من مجموعة spatie لعمل ذلك و التجربة عليه . لكن الأفضل ,و الطريق الأطول, يكون بفصل عملية التحقق Testing بشكل كامل عن نفس إتصال قواعد البيانات الذي يستخدمه تطبيقك . و لارافيل تجعل ذلك سهلا مع phpunit .
فعلى سبيل المثال : إن كان تطبيقك يستخدم Mysql فعمليات التحقق يجب أن تستخدم ذاكرة مؤقتة و إتصال sqlite .
و إن لم يتم كتابة الاختبارات Tests بشكل إما مواز أو مسبق للأكواد فسيجب لتحقيق هذا كتابة الإختبارات اللازمة لكل أجزاء التطبيق حتى يتم تحقيق هذا الأخير و إختبار التطبيق نفسه , لا نسخة إحتياطية منه ,في بيئة التطوير أو الإنتاج و بدون أي فقد لأية بيانات .
-
إجابة Adnane Kadri سؤال في إنشاء نظام تنبيهات - لارافل كانت الإجابة المقبولة
يمكن ذلك عن طريق الإستعانة بمفهوم الويب سوكيت . بحيث نقوم :
في الواجهة الخلفية للتطبيق بإنشاء قناة أو قنوات بحدث أو أحداث معينة . في الواجهة الأمامية للتطبيق بالإشتراك في هاته القنوات و الإستماع لهاته الأحداث . مثال عن الإستعمال :
لما يضغط عمر زر الإعجاب بمنشور أحمد سيتم إرسال طلب HTTP إلى الخادم . سيقوم الخادم بمعالجة طلب عمر و تسجيل الإعجاب , و في نفس الوقت سيقوم بإثارة الحدث المرتبط بالعملية و ليكن NewLikeEvent ضمن القناة AhmedChannel . أحمد مشترك في القناة AhmedChannel و يستمع لأية إثارة لأحداثها , ففي حالة إثارة أية حدث سيقوم بالتقاط البيانات التي تم تمريرها عبره دون تحديث الصفحة . لما يتم إثارة الحدث NewLikeEvent ضمن القناة AhmedChannel ستقوم الواجهة الأمامية لأحمد بالتصرف بناء على البيانات التي تلتقطها عبر هاته القناة في هذا الحدث . كأن تقوم بإظهار إشعار أو تنبيه نصي . قد نحتاج إلى دريفر لمساعدتنا في تمرير البيانات و إنشاء القنوات من مثل Pusher.
و للتوضيح أكثر سنقوم بإستعمال Pusher كونه معدا مسبقا للعمل مع لارافل بشكل متسق , و هو ما سنقوم به في هذا المثال .. يمكن عمل الفكرة عن طريق المنطق التالي :
تثبيت حزمة خادم Pusher في تطبيق الللارافل : composer require pusher/pusher-php-server
إنشاء تطبيق Pusher : نحتاج في هاته الخطوة إلى التسجيل في pusher.com و تسجيل تطبيق جديد . بعد ذلك سنحتاج نسخ معلومات التوثيق و نقوم بوضعها في ملف الإعداد env. كما يلي : PUSHER_APP_ID=PUT_YOUR_PUSHER_ID_HERE PUSHER_APP_KEY=PUT_YOUR_PUSHER_KEY_HERE PUSHER_APP_SECRET=PUT_YOUR_PUSHER_SECRET_HERE PUSHER_APP_CLUSTER=PUT_YOUR_PUSHER_CLUSTER_HERE كما أنه يجب تغيير قيمة BROADCAST_DRIVER:
BROADCAST_DRIVER=pusher
نقوم بإنشاء حدث معين :
php artisan make:event Notify سنلاحظ إضافة ملف Notify.php داخل مجلد events , لنتأكد من أنه سيتم تعديله ليكون على هذا النحو :
<?php namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Queue\SerializesModels; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class Notify implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $data; /** * هنا يتم التقاط أية بيانات و تسجيلها ضمن هذا الكائن * * @return void */ public function __construct($passed_data) { $this->data = $passed_data; } /** * هنا يتم تعريف القنوات التي من المفترض أن ينتمي إليها هذا الحدث * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { return new Channel('notify-channel'); } }
إنشاء متحكم يختص بالعملية :
php artisan make:controller NotificationController ثم لنتأكد من وضع المحتوى التالي به :
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class NotificationController extends Controller { public function notify() { // تحضير مصفوفة بيانات لتمريرها $data['message'] = 'قم بتمرير هاته الرسالة'; // Notify إثارة الحدث event(new App\Events\Norify($data)); } }
سيكون علينا تعريف مسارين , مسار لإستهداف تابع المتحكم NotificationController و اخر لعرض الصفحة notification.blade.php :
//web.php Route::get('notify','NotificationController@notify'); Route::view('/notification', 'notification');
ثم بملف ما بالواجهة الأمامية سيكون علينا فقط : الإشتراك في هاته القناة + الإستماع لأحداث هاته القناة :
<!-- notification.blade.php --> <!DOCTYPE html> <head> <title>مثال عن إشعار</title> <script src="https://js.pusher.com/4.1/pusher.min.js"></script> <script> // الإشتراك ضمن نفس تطبيق البوشر var pusher = new Pusher('{{env("MIX_PUSHER_APP_KEY")}}', { cluster: '{{env("PUSHER_APP_CLUSTER")}}', encrypted: true }); // الاشتراك في نفس القناة var channel = pusher.subscribe('notify-channel'); // Notify الاستماع للحدث channel.bind('App\\Events\\Notify', function(data) { // إن تم اثارة الحدث قم بعرض البيانات alert(data.message); }); </script> </head> بدون تحديث الصفحة سيكون علينا التصفح إلى المسار notify/ و سنلاحظ ظهور التنبيه في مسار notifications/ . المسار الأول يمثل الطلب الذي أرسله عمر , و المسار الثاني يمثل صفحة عرض الاشعارات بالنسبة لأحمد . و بالطبع فإن هذا هو الشكل الأبسط للعملية , يمكن تطوير العملية كأن نقوم بتخصيص طريقة العرض في قائمة إشعارات منظمة و منسدلة مع ظهور إشعار جانبي في كل إثارة للحدث , كما يمكن تخصيص قنوات خاصة بكل مستخدم منفرد أو نقوم بتمرير بيانات أخرى و تطبيق العديد من الأفكار عليها .
-
إجابة Adnane Kadri سؤال في ثلاث حاجات عجزت في تعلمهن في البرمجة كانت الإجابة المقبولة
بداية يجب عليك معاملة أية مشاكل و صعوبات تظهر معك كأشياء طبيعية في المجال و من جانب اخر هي إمتحانات لك و لا يجب عليك التفكير في التوقف عن ما أقدمت عليه بسبب أشياء تواجهها لأنه , و بهاته الطريقة , سيكون لديك الكثير لتتوقف من أجله .
كما أنه يجب عليك الإستفادة من الإجابات التي طرحها عليك الزملاء في أسئلتك السابقة :
و بشكل عام فإنه يجب عليك فهم منطق هاته العمليات لا التوغل في مثال عن كود واحد و إعتباره كمعيار أو دستور للعملية . فمثلا :
التشفير و فك التشفير :
للتشفير : سيكون عليك تشفير سلسلة نصية معينة قبل إستعمالها , ولقراءته سنحتاج فك هذا التشفير .
مثال عن الإستعمال : تشفير كلمة المرور قبل إدخالها في قاعدة البيانات في عملية تسجيل المستخدم - أ - , ثم فك تشفيرها للتحقق من مطابقتها لكلمة مرور قام المستخدم - أ - بإدخالها في عملية تسجيل دخوله لاحقا.
أي : أننا نحتاج دالة تشفير و دالة فك تشفير . أو دالة و دالة معاكسة لها لعمل الفكرة , و قد تكتب خوارزميتك الخاصة للتشفير وفك التشفير أنت ذاتك فالعملية ليست حكرا على أحد لكن يقترح إستعمال المكتبات و الدوال المسبق تعريفها لأمان و سرعة أكثر .
و دوال التشفير كثيرة من PHP نذكر من بينها :
openssl_encrypt و الدالة المعاكسة لها : openssl_decrypt : توثيق . أمثلة :
<?php $example = '@123456'; # السلسلة النصية المراد تشفيرها $cipher_algo = 'AES-128-CTR'; # خوارزمية التشفير $encryption_key = 'HsoubAcademy'; # مفتاح التشفير $options = 0; # خيارات التشفير $encryption_iv = 1234567891011121; # يعبر عن بادئة التشفير $encrypted_example = openssl_encrypt($example , $cipher_algo , $encryption_key , $options , $encryption_iv); echo $encrypted_example; // النتيجة : nLTaaXcr1A== $decrypted_example = openssl_decrypt($encrypted_example , $cipher_algo , $encryption_key , $options , $encryption_iv); echo $decrypted_example; // النتيجة : @123456 base64_encode و الدالة المعاكسة لها : base64_decode . توثيق . أمثلة :
<?php $example = '@123456'; # السلسلة النصية المراد تشفيرها $encrypted_example = base64_encode($example); echo $encrypted_example; // النتيجة : QDEyMzQ1Ng== $decrypted_example = base64_decode($encrypted_example); echo $decrypted_example; // النتيجة : @123456
bin2hex و الدالة المعاكسة لها : hex2bin . توثيق و أمثلة .
و غيرها الكثير ..
كما يمكنك القراءة عن الموضوع أكثر هنا :
رفع الصور و الملفات عن طريق الأجاكس :
جافاسكربت تجعل ذلك بسيطا عن طريق إستعمال كائن يختص بنماذج البيانات و هو الكائن FormData , و لإرسال صورة أو ملف ما علينا إلا : إرسال نموذج من الكائن FormData يحمل الملف.
لاحظ جيدا منطق الخطوات بالمثال التالي :
$(document).ready(function(){ // 1 - إضافة حدث عن تقديم الاستمارة و رفع الملف $("#submit_file_form").click(function(){ // 2 - FormData تحضير نموذج عن الكائن var fd = new FormData(); // 3 - تحديد الملف var files = $('#my_file')[0].files; // 4 - التحقق من تحميل ملف if(files.length > 0 ){ // 5 - إضافة الملف إلى نموذج الكائن fd.append('file',files[0]); // 6 - تحضير طلب الاجاكس و إرسال نموذج الكائن $.ajax({ url: 'path/to/endpoint', type: 'POST', data: fd, contentType: false, processData: false, success: function(response){ if(response){ alert('تم رفع الملف'); }else{ alert('لم يتم رفع الملف'); } }, }); }else{ alert("قم بتحديد ملف لرفعه."); } }); });
معيارية MVC :
و هي إختصار لـ Model , View , Controller و ببساطة شديدة هو نموذج معيارية Design Pattern يقضي بعزل منطق العمل عن واجهة المستخدم بهدف تحقيق إستقلالية كل منهما و تسهيل التعامل معهما في التطوير , الفحص و الصيانة . و يحقق بذلك أحد مبادئ التصميم المشهورة في علوم الحاسب : مبدأ فصل الإهتمامات separation of concerns (SoC).
تقوم معيارية MVC بتقسيم التطبيق إلى ثلاث أجزاء :
النموذج Model : يعبر عن المكون المركزي و الرئيسي للنمط Pattern . و يمثل بنية البيانات الخاصة بالتطبيق ، فعن طريقه تتم مباشرة إدارة بيانات وقواعد التطبيق . العرض View : و هي أي تمثيل للمعلومات مثل صفحة ويب , جداول أو نصوص . و تمثل ها هنا واجهة المستخدم . المتحكم Controller : و يقوم بإستقبال المدخلات و التحكم فيها و التحقق من إمكانية تمريرها للنموذج Model حتى يتصرف بناء عليها . هذا الفصل بين المكونات الثلاث هاته يجعلها تتفاعل فيما بينها بهاته الطريقة :
النموذج Model مسؤول عن إدارة بيانات التطبيق . بحيث يتلقى مدخلات المستخدم من وحدة التحكم Controller .
تستجيب وحدة التحكم Controller لإدخال المستخدم , وتتحقق من سلامتها ثم تقوم بتمرير مدخل المستخدم إلى النموذج Model , أو تقوم إستجابة لمدخل المستخدم بعرض View بتنسيق معين .
و بشكل عام فإن أي فصل لهاته الثلاث مكونات , اهتمامات و وظائف هي معيارية تصميم MVC مثلها مثل أي معيارية أخرى , يتطلب التعمق فيها فهما أوسع و أعمق لأنماط ومعياريات التصميم Design Patterns . إن لم يكن لك إطلاع مسبق عنها فيمكنك أخذ فكرة عن الموضوع هنا و أيضا هنا .
كما يمكنك الإطلاع عن الكود المصدري لهاته النماذج المصغرة لمعيارية MVC هنا و هنا . و بالطبع فإنه يمكنك التدرب على فصل هاته المكونات الثلاث لتطبيق الفكرة عمليا .
-
إجابة Adnane Kadri سؤال في مشكلة في استعلام mysql كانت الإجابة المقبولة
يظهر الخطأ في القراءة من الإستعلام في عناصر التوريد و بالضبط في هذا السطر :
<input type="text" class="form-control contact-name" placeholder="الاسم" value="<?php echo $item['supplying_items.name']; ?>" disabled > وهذا لأن طريقة القراءة في كود PHP تختلف عن طريقة القراءة في إستعلام SQL . في PHP لا يوجد أي عنصر بالفهرس supplying_items.name من الناتج و لكن يوجد مصفوفة بإسم supplying_items تحوي عنصر بالفهرس name .
أي أن القراءة تكون على هذا النحو :
<input type="text" class="form-control contact-name" placeholder="الاسم" value="<?php echo $item['supplying_items']['name']; ?>" disabled > أو :
<input type="text" class="form-control contact-name" placeholder="الاسم" value="<?php echo $item['name']; ?>" disabled > إن كنت تقوم بالتكرار حول عناصر التوريد supplying_items لأن الدور الخاص بك غير واضح .
إن لم يقم هذا بحل مشكلتك يرجى إرفاق كامل الكود .
-
إجابة Adnane Kadri سؤال في PHP : كيف يمكنني أن أكتب سكريبت يصنع Tables في قاعدة البينات من تلقاء نفسه كانت الإجابة المقبولة
بالطبع فإنه يمكنك معاملة إستعلام إدراج و إنشاء الجداول كأي إستعلام CRUD اخر مثلا.
مثال عملي :
<?php /* mysqli تحضير كائن جديد*/ $mysqli = new mysqli("localhost", "root", "", "demo"); // التحقق من الاتصال if($mysqli === false){ die("حدث خطأ في الاتصال " . $mysqli->connect_error); } // جلب مجموعة الاستعلامات من ملف قواعد البيانات $sql = file_get_contents('data.sql'); if($mysqli->query($sql) === true){ echo "تم إنشاء الجداول بقواعد البيانات بنجاح"; } else{ echo "حدث خطأ" . $mysqli->error; } // إغلاق الاتصال $mysqli->close(); ?> قد تحتاج أيضا إضافة شرط الوجود في استعلام الـ sql على هذا النحو :
CREATE TABLE IF NOT EXISTS `users` ( `user_id` INT(8) NOT NULL AUTO_INCREMENT, `user_name` VARCHAR (30) NOT NULL, `user_pass` VARCHAR (255) NOT NULL, `user_email` VARCHAR (255) NOT NULL, `user_date` DATETIME NOT NULL, `user_level` INT(8) NOT NULL, UNIQUE INDEX `user_name_unique` (`user_name`), PRIMARY KEY (`user_id`) ) Engine=InnoDB;
-
إجابة Adnane Kadri سؤال في التخزين المؤقت في لارافيل (Cache) كانت الإجابة المقبولة
طبعا فإن لارافل توفر الكثير من دريفرات التخزين المؤقت و كل منها جيد و ممتاز في أداء مهمته في بيئة ما أو حسب شروط ما.
فمثلا :
لحل المشاكل و الـ Debuging ستكون الـ array أفضل خيار لك . لتوفير تخزين بشكل دائم سيكون الـ file أفضل خيار . لتجربة التطبيق و الـ Testing لن يكون هناك أفضل من قاعدة البيانات (MySql , SQLite) . لكن إذا كان لديك خادم مخصص و تريد إختيار درايفر تخزين مؤقت لتطبيق اللارافل لديك على بيئة الإنتاج ، عليك بالتأكيد اختيار memcached أو redis . فكل منها يمتلك نظام تخزين مؤقت مجاني ومفتوح المصدر و عالي الأداء و لن يكون عليك القلق بشأن ضغط الملفات على الخادم أو إنهيار الخادم .
يمكنك القراءة عن الكثير من المقارنات بينهما من حيث نمط و حجم البيانات , الثبات , الأداء , توثيق النظام و غيرها من العوامل . لكن يبقى كل منهما يحقق الغرض بأداء و جودة عاليتين و لو وجد تفاوت بينهما فسيكون تفاوتا طفيفا لن يؤثر عليك.
عن نفسي أفضل استخدام redis نظرًا لقدرته على الاحتفاظ بحجم كبير من البيانات ، لكن يبقى إستعمال أي من أحدهما حلاً جيدًا جدا .
أما عن فكرة تخزين الملفات المؤقتة في ذاكرة المستخدم أو حاسب المتصفح فالمتصفحات تكفيك تخزين بعض ملفات الواجهة الأمامية و لا أظن أنه توجد طريقة أصلا لإعتمادها كدريفر تخزين.
-
إجابة Adnane Kadri سؤال في مشكلة في القراءة من جدولين عن طريق الإستعلام JOIN كانت الإجابة المقبولة
ليكن في العلم أنه بعد ضم الجدولين عن طريق JOIN فأنت تقوم بضم كل سطر من الجدول 1 إلى السطر المرافق من الجدول 2 , بحيث أنه سيتم تحديد الترافق هذا عن طريق تساوي المفاتيح من الجدولين .
الان و بعد عمل الضم على هذا النحو :
SELECT common_cloth_composition.id AS CID, common_cloth_composition.ready AS readyId, commercial_description.id AS commID, commercial_description.name AS commName FROM common_cloth_composition INNER JOIN commercial_description ON common_cloth_composition.ready = commercial_description.id لاحظ أن هذا الإستعلام سيقوم بجلب كل الأسطر من الجدولين التي تتساوى فيها المفاتيح , يمكنك الان تصفية النتائج و إضافة شرط التساوي عن طريق WHERE :
SELECT common_cloth_composition.id AS CID, common_cloth_composition.ready AS readyId, commercial_description.id AS commID, commercial_description.name AS commName FROM common_cloth_composition INNER JOIN commercial_description ON common_cloth_composition.ready = commercial_description.id WHERE common_cloth_composition.ready='127'
-
إجابة Adnane Kadri سؤال في عند رفع الصورة في الصفحة الشخصية في تطبيق jetstream لا تحفظ التغيرات كانت الإجابة المقبولة
كل الملفات سليمة .
المشكلة في إستدعاء التابع factory في هذا السطر :
Post::factory() ليكن في العلم أن هاته الدالة يتم توفيرها من قبل السمة HasFactory .
تأكد فقط أن تضيفها إلى مودل المنشور Post على هذا النحو :
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; class Post extends Model { use HasFactory; // some code }
-
إجابة Adnane Kadri سؤال في سؤال في bootstrap modal كانت الإجابة المقبولة
الظاهر أن خلفية المودل modal-backdrop تظهر فوق المودل modal نفسه .
يحدث هذا السلوك عادة بسبب إمتلاك الحاوي لعنصر المودل الوضعية الثابتة fixed أو النسبية relative لذلك ينصح دوما بوضع المودل قبل وسم إغلاق الـ body مباشرة لتجنب هاته المشكلة أو التأكد من إمتلاك كل الحاويات لعنصر المودل الوضعية الإفتراضية . لكن في هاته الحالة ألحظ أنه يوجد بعض الوسوم المفتوحة التي لم يتم إغلاقها . في هاته الحالة تم إعتبارها كحاويات لما بعدها من عناصر مفتوحة أو مغلقة متضمنة المودل نفسه . لاحظ :
<div class="app-container app-theme-white body-tabs-shadow fixed-sidebar fixed-header"> <div class="app-main"> <div class="app-main__outer"> <div class="app-main__inner"> <div class="app-page-title"> </div> # < < < من المفروض وجود وسم إغلاق # < < < من المفروض وجود وسم إغلاق # < < < من المفروض وجود وسم إغلاق # < < < من المفروض وجود وسم إغلاق <table class="table table-primary table-bordered" dir="rtl"> ... </table> لاحظ أيضا أن الحاوي الأول (عدم إغلاقه سيجعله حاويا لكل الوسوم المغلقة أو المفتوحة بعده) يملك الوضعية الثابتة بسبب الصفوف fixed-header و fixed-sidebar و هذا غالبا ما أدى إلى ظهور المشكلة .
فحل المشكلة ببساطة هو في إغلاق الوسوم المفتوحة .
إذ لم يكن هذا كفيلا بحل المشكلة يمكنك إعادة ترتيب العناصر على المحور Z عن طريق الخاصية z-index . فعندما تتداخل العناصر يمكن عن طريق تحديد قيمة هذه الخاصية تحديد ما هو العنصر الذي سيظهر أعلى بقية العناصر .
يمكنك إعطاء العنصر بالصف modal-backdrop قيمة أقل :
.modal-backdrop { z-index: -1; }
-
إجابة Adnane Kadri سؤال في سؤال حول تحديث البيانات في الداتابيز php mysql كانت الإجابة المقبولة
و هذا لأن الطلب POST فارغ و لا توجد به أي متغيرات بالمسميات id و index في الحالة الإفتراضية .
لحل المشكلة يمكنك إعطاءها أي قيم إفتراضية على هذا النحو :
<?php $id = $_POST['id'] ?? null; $type = $_POST['type'] ?? null; أو تمريرها داخل الشرط مثل ما اقترح @بلال زيادة فتكون معرفة في حالة طلبات الـ POST فقط .
كما أنه يمكن إختصار الكثير من الأكواد المكررة المطولة لديك .
أمثلة عن ذلك :
تعريف المتغيرات من text1 حتى text19 و المتغيرات من check1 حتى check7:
var texts = []; var checks = []; for (var i = 1; i < 20; ++i) { texts[i] = $(".text-"+i).val(); if(i < 8) { checks[i] = $(".check-" + i).prop("checked"); } } ملفات تعريف الارتباط :
// حذف ملفات تعريف الارتباط بعد نجاح الطلب success: function(data) { if (data == "done") { for(var i = 1 ;i < 20; i++) { deleteCookie("text" + i); if(i < 8) { deleteCookie("check" + i); } } } } // تعريف ملفات الارتباط for(var i = 1 ;i < 20; i++) { document.cookie = "text"+ i +"=" + texts[i + 1] + ";expires=Thu, 18 Dec 2023 12:00:00 UTC;"; if(i < 8) { document.cookie = "check"+ i +"=" + checks[i + 1] + ";expires=Thu, 18 Dec 2023 12:00:00 UTC;"; } } ثم إرسال المصفوفتين texts و checks عبر الطلب عوضا عن كل المتغيرات فتتم المعالجة على هذا النحو :
<?php if ($type == "supp") { for($i = 1;$i < 20 ;$i++) { ${"text".$i} = $_POST['texts'][$i]; if($i < 8) { ${"check".$i} = $_POST['checks'][$i]; } } } سيجعل الكود أقصر , أنظف و أسهل قراءة .
-
إجابة Adnane Kadri سؤال في هل بإمكاني التعديل على البيانات القادمة من الداتا بيز قبل إرسالها إلى الAPI? كانت الإجابة المقبولة
نعم يمكنك ذلك عن طريق الإستعانة بمفهوم المسترجعات والمعدلات (Accessors & Mutators) في لارافال .
مثال عملي عن ذلك :
نقوم بتعريف معدل جديد بملف مودل المستخدمين على هذا النحو :
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * Get the user's type. * * @param string $value * @return void */ public function getTypeAttribute($value) { if($value == 0 ) return 'admin'; return 'user'; } } لاحظ كيفية تعريف المعدل :
get | {attr} | Attribute attr => capitialized يمكنك القراءة أكثر عن الموضوع من هنا .
-
إجابة Adnane Kadri سؤال في بوابة استلام مدفوعات في Flutter لا تحتاج إلى سجل تجاري و بطاقة ضربية كانت الإجابة المقبولة
هذا الأمر لا يقتصر على فلاتر أو غيره , فكل بوابات الدفع تقدم إما واجهة تطبيق برمجية جاهزة API أو مكتبة SDK يسهل ربطها , دمجها و التعامل معها بأي إطار عمل أو منصة أو أي لغة كانت .
و إختيار بوابة الدفع عموما يكون إنطلاقا من إحتياجات أو إختيار عميلك بالدرجة الأولى , ولأسباب أخرى بدرجة ثانية (من مثل المنطقة و الدول المدعومة و العمولات المخصومة على كل تحويل و العروض المتوفرة .. إلخ ) .
أما عن بوابات الدفع التي تقبل إشتراك فردي (أشخاص و شركات) لا تشترط و لا تطلب أي سجل تجاري , رقم ضريبي أو بطاقة ضريبية فنذكر من بين أفضلها :
بوابة دفع بيبال Paypal, بحيث توفر SDK سهل الإستخدام و الربط و خصوصا مع لغات و منصات الواجهة الأمامية من مثل فلاتر .أؤمن أنها الأفضل في كثير في الحالات , كما توفر أيضا حساب تجريبي (sandbox account) لتجربة التطبيق على مستوى التطوير . باي فورت PayFort, وهي أحد أحد أبرز بوابات الدفع الإلكتروني الرائدة في الشرق الأوسط تم إنشاءها بالإمارات و استحوذت عليها شركة أمازون الان و قد تم تغيير إسمها إلى Amazon Payment Services, تقوم بتوفير API سهل الربط مع تطبيقك . سكريل Skrill, و هي بوابة غنية عن التعريف توفر أيضا واجهة برمجية سهلة الربط . بوابة تتو تشيك أوت 2checkout , و هي واحدة من أكثر البوابات شيوعا , توفر أيضا API سهل الإستخدام بتوثيق مفصل , (قد كنت اخترتها للعديد من العملاء ممن سبق لي التعامل معهم) . للربط مع فلاتر قد تحتاج القراءة أكثر عن قنوات المنصة .
-
إجابة Adnane Kadri سؤال في مساعدة في دمج اكواد جافا اسكربت كانت الإجابة المقبولة
أظن أن قصدك "وضع الكود الثاني و الثالث بداخل الأول" (و هذا تحقيقا للغرض المطلوب).
لا حاجة لذلك , يمكنك فصل كل الدوال بحسب المهمة و من ثم إستدعاءهم في دالة واحدة . بداية يمكنك تبسيط العملية أكثر عن طريق التالي :
قم بوضع كل الأكواد الأول و الثاني و الثالث بداخل دوال على هذا النحو (وهذا بحسب مبدأ فصل الإهتمامات) :
function openVideoFile() { if(!$('#iframe').length) { $('#iframeHolder').html('<iframe id="iframe" src="//player.vimeo.com/video/90429499" width="700" height="450"></iframe>'); } } و :
function putVideoInPage() { setTimeout(function(){$(".video-youtube").each(function(){$(this).replaceWith('<iframe class="video-youtube loader" src="'+$(this).data("src")+'" allowfullscreen="allowfullscreen" height="281" width="500"></iframe>')})},5e3); } و :
function GoInFullscreen(element) { if(element.requestFullscreen) element.requestFullscreen(); else if(element.mozRequestFullScreen) element.mozRequestFullScreen(); else if(element.webkitRequestFullscreen) element.webkitRequestFullscreen(); else if(element.msRequestFullscreen) element.msRequestFullscreen(); } function GoOutFullscreen() { if(document.exitFullscreen) document.exitFullscreen(); else if(document.mozCancelFullScreen) document.mozCancelFullScreen(); else if(document.webkitExitFullscreen) document.webkitExitFullscreen(); else if(document.msExitFullscreen) document.msExitFullscreen(); } function IsFullScreenCurrently() { var full_screen_element = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement || null; if(full_screen_element === null) return false; else return true; } و :
function setEventForGoButton() { $("#go-button").on('click', function() { if(IsFullScreenCurrently()) GoOutFullscreen(); else GoInFullscreen($("#demo-element").get(0)); }); } و :
function handleFullScreen() { $(document).on('fullscreenchange webkitfullscreenchange mozfullscreenchange MSFullscreenChange', function() { if(IsFullScreenCurrently()) { $("#demo-element span").text('opn'); $("#go-button").text('bak'); } else { $("#demo-element span").text('bak'); $("#go-button").text('opn'); } }); } ثم يمكنك دمج و إستدعاء كل الدوال بعد الضغط على زر تشغيل الفيديو على هذا النحو :
$(function(){ $('#button').click(function(){ // تضمين الفيديو في الصفحة openVideoFile(); // وضع رابط فيديو بصفحة النشر بدون وضع اكواد فريم putVideoInPage(); // إضافة التفاعلية لزر ملئ الشاشة setEventForGoButton(); // تغيير النصوص بحسب وضع ملئ الشاشة // #demo-element span النصوص المعرفة بـ handleFullScreen(); }); }); ملاحظات :
الكثير من الأكواد غير واضحة المهمة في الأكواد التي أرفقتها و لا يظهر بالنسبة لي أي ترابط بين الكود الثاني و الأكواد الأخرى , و رغم ذلك قد قمت بتضيمنها في الأكواد التي وصفتها لك (يمكن لأن ذلك راجع إلى غياب باقي عناصر الصفحة ) .
يمكنك تتبع نفس المنطق لكتابة دالة تجمع عمل كل الدوال المعرفة (ألف دالة تقوم بألف مهمة أفضل من دالة تقوم بألف مهمة) , سيكون الكود أفضل قراءة و أكثر وضوحا.
-
إجابة Adnane Kadri سؤال في كيفيه ادخال بيانات لجدولين php باستخدام phpmyadmin كانت الإجابة المقبولة
بإستخدام phpmyadmin يمكنك ذلك عن طريق :
التصفح إلى http://localhost/phpmyadmin الدخول إلى قاعدة البيانات المقصودة بالقائمة الجانبية . الضغط على زر SQL في قائمة التصفح أعلى الصفحة . طباعة إستعلام الإدراج و الضغط على GO , يكون كود الإستعلام على هذا النحو : INSERT INTO blood_groups (blood_group_name) VALUES ('O+'); INSERT INTO benefactor (fk) VALUES (/* من جدول الفصائلid قم بطباعة اخر */); ملاحظات :
يجب مراعاة القيم الإفتراضية للأعمدة بالجداول السابقة و التأكد من أن لها قيم إفتراضية بالفعل .
لا ينصح بإدخال البيانات يدويا إلا في حالات إستثنائية , عوضا عن ذلك يمكنك فعل ذلك بالـ php .
-
إجابة Adnane Kadri سؤال في اظهار نتائج بشكل متكرر mysql كانت الإجابة المقبولة
لو أحببت أن تترك الأمر لجانب الباك اند فقط فيمكنك تطبيق العملية وفق المنطق التالي :
جلب كل العناصر الغير مميزة . جلب العناصر المميزة . تكرار العناصر المميزة كذا مرة . دمج العناصر المميزة مع غير المميزة وفق ترتيب معين . مثال عملي :
يمكنك جلب كل العناصر التي لا تحتوي على 1 في حقل المنتج المميز على هذا النحو :
$sql = "SELECT * FROM Prodect WHERE is_special = 0 ORDER BY RAND()"; ثم جلب العناصر المميزة و تكرارها :
<?php // تحضير الاستعلام $sql2 = "SELECT * FROM Prodect WHERE is_special=1 ORDER BY RAND()"; function getRepeated($query) { $repeat_times = 10; $counter = 0; $rows = []; $result = mysql_query($query); // تحضير كل الحقول while($row == mysql_fetch_row($result)) { $rows[] = $row; } // تحضير مصفوفة تحمل عناصر مميزة ومكررة $repeated = []; for($index = 0; $counter < $repeat_times; $counter++) { $repeated[] = $rows[$i]; $index++; // إعادة الدور إلى الصفر لملئ المصفوفة بعناصر مكررة if($index == count($rows)) { $index = 0; } } return $repeated; } $special = getRepeated($sql2); المزج وفق الترتيب و التكرار :
<?php $non_special = [...]; // ناتج الاستعلام الاول $special = [...]; // ناتج الاستعلام الثاني مكرر $total = []; $offset = 0; for($i = 0; $i < count($non_special); $i++) { if(is_float($i / 10)) { array_push($total ,$non_special); } else { // قطعة من مصفوفة المنتجات المميزة لدمجها $pieceOfSpecial = array_slice($special,$offset,5); $offset += 5; array_merge($total ,$pieceOfSpecial); } } // =======> return $total الان ستسهل عملية عرضها مباشرة
تحديث :
يمكن أن لا تكون هناك أي حاجة من تكرار العناصر المميزة كذا مرة لدمجها مع الغير مميزة و يمكن تحقيق نفس الغرض في حالة جلب عدد معين من العناصر المميزة . فتكون عوض الخطوة كاملة و عوضا عن اقتطاع المصفوفة كل مرة في المرحلة الأخيرة يمكنك فقط دمج المصفوفة كلها (قد يكون هذا البديل مفيد في حالة وجود عدد محدود جدا من العناصر المميزة بقاعدة البيانات) .
-
إجابة Adnane Kadri سؤال في عرض عملات مختلفه في فلاتر كانت الإجابة المقبولة
أسعار العملات بالنسبة لعملة رئيسية و معدلات التحويل الخاصة بها متغيرة في الغالب و تحتاج ديناميكية لوضع الأسعار . تستطيع إما تخزين السعر بالدولار كـ base currency و من ثم جعل عملية التحويل ديناميكية عن طريق معدل تحويل . لا أظن أنه توجد حزمة جاهزة لتقوم بالعملية . لكن يمكنك إستعمال أحد هاته الـ APIS : هذا أو هذا لجلب معدلات التحويل من الدولار أو من أي base currency تستعملها . كما يمكنك مباشرة إرسال طلبات GET إلى نقطة الوصول هاته فقط و قراءة الخاصية geoplugin_currencyConverter لجلب معدل التحويل الذي يخص بالمستخدم نفسه (الذي تم إرسال الطلب عن طريقه) من الدولار من الرد مباشرة أيضا (مثلا لإظهار العملة بحسب بلد المستخدم حسب تحليل الـ IP) .
أيا كانت طريقتك في جلب معدل التحويل يمكن حساب السعر الجديد بسهولة عن طريق :
var new_price = base_price * exchange_rate_base_to_target /*من الرسبونس*/; و كإقتراح لتحسين تجربة المستخدم و جعل عملية تثبيت العملة المحول إليها سهلة , قم بتخزين العملة و معدل التحويل في الجلسة أو الكوكي أو التخزين المحلي بدل إرسال طلب مع كل مرة .
ملاحظات :
يمكنك أيضا الإستغناء عن هاته العملية ككل و إدخال أسعار لمختلف العملات في حالة كان عدد العملات محدود جدا و تريد تحكم أكبر في الأسعار بحسب البلد أو العملة (خذ إحتمال أسعار السوق السوداء مثلا , فهي لا ترسل في الردود من أي API و قد تحتاجها لوضع تسعيرة معقولة في حال كان هنالك تباعد كبير بين سعر الصرف و سعر السوق السوداء) . و بنفس منطق واجهات التطبيق البرمجية المشار إليها يمكنك تخصيص نقطة وصول لجلب معدلات التحويل بتطبيقك نفسه و ليكن من جدول تنشأه : معدلات التحويل exchange_rates , و من ثم التحكم في هاته المعدلات على نطاق أوسع و التعديل بما يلائم سعر الصرف الحالي أو السعر الذي يناسب فرع المتجر بالعملة الفلانية .
-
إجابة Adnane Kadri سؤال في التحقق من رسالة كود التفعيل باستخدام فلاتر كانت الإجابة المقبولة
في العادة إرسال رسائل sms قد تحتاج تكلفة و إشتراك لتطبيق العملية و الإستعانة بها. و يمكنك تطبيق العملية كلها وحدك مثل ما أشار الأخ @بلال زيادة. وقد تحتاج الإستعانة بأحد هاته الواجهات Twilio أو Plivo .
مثال عن إرسال رسالة بإستعمال Twilio :
<?php use Twilio\Rest\Client; # إرسال رسالة ... $client = new Client($account_sid, $auth_token); # تعطى مع حساب تويليو $client->messages->create($receiverNumber, [ 'from' => $twilio_number, # يعطى مع حساب تويليو 'body' => $activation_code ]); # قم تخزين الكود ... $currentUser->update([ 'activation_code' => $activation_code , ]); ثم براوت اخر يمكنك عمل المصادقة بشكل مشابه :
<?php ... if($user_input == $activation_code){ $current_user->update([ 'phone_is_activated' => true, ]); return 'أنت مفعل'; } return 'كود التفعيل خاطئ'; و بالطبع فإن هذا هو الشكل الأبسط للعملية , يمكنك إضافة العديد من الأشياء كإنتهاء صلاحية الكود أو ربط كود التفعيل بمودل اخر غير مودل المستخدم و غيرها .
كما يمكنك إستعمال حزم جاهزة مثل هاته الحزمة بحيث توفر عليك الكثير من الأشياء من مثل الError Reporting و كل الBack end Logic بحيث تقوم بإرسال بيانات إلى نقاط وصول معينة و القراءة من الرد . و مثل ما تقدم هذا في نفس الوقت هي تزيل عنك حرية التصرف و التطوير بما يلائم مشروعك .
-
إجابة Adnane Kadri سؤال في كيفية تخزين صورة في قاعدة البيانات MySQL كانت الإجابة المقبولة
بداية , لا يمكنك تخزين أي ملفات بقاعدة البيانات Sql , عوضا عن ذلك يمكنك إستخدام الfile systems لتخزين الصورة أو الملف و تخزين باث الصورة أو الملف في قاعدة البيانات .
يتم إستقبال الطلب من قبل اللارافل و معالجته على هذا النحو :
<?php public function uploadImg(Request $request) { // التحقق إن كان الطلب يحمل ملف باسم image if($request->hasFile('image')) { // انشاء اسم بلاحقة للملف $name = time()."_".$request->file('image')->getClientOriginalName(); // تخزين الملف بالpublic path $request->file('image')->move(public_path('images'), $name); } // return response()->json([ asset("images/$name"), // باث الصورة 201, // كود الحالة 'message' => asset("images/$name") ? 'تم حفظ الصورة' : 'failed' ]); } -
إجابة Adnane Kadri سؤال في اضافة أكثر من صفحة sass في مشروع webpack كانت الإجابة المقبولة
يمكنك عمل ذلك عن طريق تمرير عدة نقاط وصول لملفات scss الخاصة بك عن طريق :
module.exports = { entry: { 'about': ['./src/css/about.scss'], 'contact': ['./src/css/contact.scss'], 'index': ['./src/css/index.scss'] }, plugins: [ new MiniCssExtractPlugin( { filename: "./css/[name].css" } ), ] } الwebpack ستقوم بقراءة مفاتيح المدخلات و تقوم بإستبدالها بالوسم name داخل الfilename فتكون المخرجات على هذا النحو :
dist css about.min.css contact.min.css index.min.css ثم بملفات الHTML يمكنك تضمين كل ملف css داخل dist/css حسب الحاجة أو حسب صفحة الHTML الحالية.
ملاحظة :
تأكد أن تقوم بتضمين الminifier على نحو صحيح :
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); و في حالة ظهور أي أخطاء على هاته الشاكلة :
could not resolve module mini-css-extract-plugin تأكد أن تقوم بتثبيت الـ Plugin :
npm install --save-dev mini-css-extract-plugin