-
المساهمات
5196 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
52
نوع المحتوى
ريادة الأعمال
البرمجة
التصميم
DevOps
التسويق والمبيعات
العمل الحر
البرامج والتطبيقات
آخر التحديثات
قصص نجاح
أسئلة وأجوبة
كتب
دورات
كل منشورات العضو Adnane Kadri
-
هذا ليس خطأ و إنما رسالة تحذير بسيطة يتم إخبارك فيها أنه لا يمكنك محو مجلد , و يحدث هذا لأن بعض عناصر المصفوفتين تحوي سلاسل نصية كالتالي : " " , أي فراغ . يمكنك تجاهلها بكل حال من الأحوال كون الشيفرة قابلة للتنفيذ مرة واحدة . لا تنسى ضبط السطر التالي : $targetImages = array_diff($stored_imgs,$db_imgs); و ذلك وفق ما هو موضح سابقا :
- 12 اجابة
-
- 1
-
لاحظ عدم تماثل مخروجي المصفوفتين . فإما هذا : أو العكس : أن يكون مخروج مصفوفة المخزن تحوي اسم المجلد . فنتائج المصفوفة الأولى ممثلة للصور المخزنة stored_imgs لا تماثل نتائج المصفوفة الثانية db_imgs. و لحل المشكلة سنقوم بإضافة السابقة uploads/profile/ إلى كل عناصر مصفوفة عناوين الصور في قواعد البيانات . يمكن ذلك عن طريق الوظيفة preg_filter كالتالي : $prefixedArray = preg_filter('/^/', 'prefix', $targetArray); كما أننا سنحتاج فلترة نتائج كل من المصفوفتين للتخلص من وجود العناصر الفارغة لتجنب التحذيرات و الأخطاء التي تظهر , يمكن ذلك عن طريق الوظيفة array_filter كالتالي : $filteredArray = array_filter($nonFilteredArray); لتصبح الشيفرة كاملة : // تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . $res = mysql_query('SELECT img_profile_path from users'); $db_imgs = []; while($row = mysql_fetch_array($res)) { $db_imgs[] = $row['img_profile_path']; } // إضافة سابقة $db_imgs = preg_filter('/^/', 'uploads/profile/', $db_imgs); // تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . $stored_imgs = glob($targetDirectory . "*.jpg"); // تحديد العناصر الغير متوفرة في كلتا المصفوفتين . $targetImages = array_merge(array_diff($db_imgs, $stored_imgs), array_diff($stored_imgs, $db_imgs)); // فلترة العناصر الفارغة $targetImages = array_filter($targetImages); // حذفها هاته العناصر foreach($targetImages as $image) { unlink($image); } يفترض أن يقوم هذا بحل المشكل . يمكنك دوما تتبع مخروج المصفوفتين عن طريق طباعة كل منهما كل مرة . توثيق الوظيفتين : array_filter preg_filter
- 12 اجابة
-
- 1
-
هلا قمت بتنفيذ الشيفرة التالية و إرفاق النتيجة ؟ // تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . $res = mysql_query('SELECT img_profile_path from users'); $db_imgs = []; while($row = mysql_fetch_array($res)) { $db_imgs[] = $row['img_profile_path']; } // تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . $stored_imgs = glob($targetDirectory . "*.jpg"); // تحديد العناصر الغير متوفرة في كلتا المصفوفتين . $targetImages = array_diff($stored_imgs, $db_imgs); echo '<pre>'; print_r($targetImages); echo '</pre>'; echo '<br><br><br><pre>'; print_r($db_imgs); echo '</pre>'; die(); // حذفها هاته العناصر foreach($targetImages as $image) { unlink($image); } سيمكن بهذا تتبع مخروج كل من المصفوفتين قبل تطبيق أية عمليات عليها .
- 12 اجابة
-
- 1
-
يعني هذا عدم تماثل بعض النتائج من قاعدة البيانات و الملفات , يحتمل أنك تقوم بتخزين اسم المجلد في قواعد البيانات أيضا . هلا تأكدت من أن الصور تظهر كالتالي في قاعدة البيانات : img1.jpg img2.jpg و ليس كـ : images/profile/img1.jpg images/profile/img2.jpg
- 12 اجابة
-
- 1
-
تقوم الشيفرة الموصوفة بحذف كل من : الصور المخزن مساراتها في قواعد البيانات و التي لا تتوفر على مسار فعلي في نظام الملفات. الصور المتوفرة في نظام الملفات و ليس لها توفر في قواعد البيانات . يمكنك استثناء الإحتمال الأول بالتخلص تماما من فكرة مزج مصفوفتي : ناتج فرق المصفوفة الاولى و الثانية . ناتج فرق المصفوفة الثانية و الأولى . وذلك عن طريق السطر المعني ليصبح كالتالي : $targetImages = array_diff($stored_imgs, $db_imgs);
- 12 اجابة
-
- 1
-
في الحقيقة نحن عادة لا نقوم بتخزين " الصور " ذاتها في قواعد البيانات بل نقوم بتخزين مسارات هاته الصور , و عوضا عن تخزينها في قواعد البيانات نحن نستخدم نظم التخزين و الملفات لذلك . كما أنه لا ينصح بتخزين الصور في جدول قاعدة البيانات. فهناك عيوب كثيرة جدا لهذا النهج. بحيث يتطلب تخزين بيانات الصورة في الجدول أن يقوم خادم قاعدة البيانات بمعالجة ونقل كميات هائلة من البيانات التي يمكن إنفاقها بشكل أفضل على المعالجة الأنسب لها . و من جانب اخر يمكن لخادم الملفات معالجة ملفات الصور هذه بشكل أفضل . بحيث يؤدي تخزين بيانات الصورة داخل حقل ثنائي إلى ترك هذه البيانات متاحة فقط للتطبيق الذي يقوم بدفق بيانات الصورة الأولية من وإلى هذا الحقل , و الميزة الوحيدة لهذا الأسلوب هي أنه يمكنك تأمين صورك بشكل أفضل لأنه يمكنك استخدام ميزات أمان قاعدة البيانات . طريقة بديلة وأفضل هي تخزين الصور خارج قاعدة البيانات و تخزين رابط فقط إلى ملف الصورة و ليكن تحت حقل اسمه img_path مثلا . بحيث سنحتاج فقط إلى حقل نص في جدول قاعدة البيانات لتخزين هذه المعلومات , كما أننا ستحتاج مزامنة البيانات في حقل الارتباط مع نظام الملفات الخاص بك لكي نتجنب مشاكل مثل التالي : و من السهل جدًا أيضًا استخدام هذه الطريقة لتخزين الصور مع مختلف لغات البرمجة , لأن معظمها تدعم وظائف القراءة من نظمم الملفات و إدارتها .
-
يمكنك جعل العملية ديناميكية و منطقية أكثر كالتالي : يتم حذف الصورة القديمة لكل مستخدم قبل تغيير صورته في حالة ارساله لطلب . فلو كانت شيفرة تحديث صورة مستخدم ما كالتالي : $target_dir = "uploads/profile"; $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]); $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION); if(isset($_POST["change_pic"])) { move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file); $sql = "UPDATE users SET image_profile_path = '".$_FILES['fileToUpload']['name']."' WHERE id = '" .$targetUser. "'"; $check = $conn->query($sql); } سيجب إضافة شيفرة الحذف كالتالي : $target_dir = "uploads/profile"; $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]); $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION); $oldImgPath = "SELECT image_profile_path from users WHERE id = '".$targetUser."'"; if(isset($_POST["change_pic"])) { move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file); $sql = "UPDATE users SET image_profile_path = '".$_FILES['fileToUpload']['name']."' WHERE id = '" .$targetUser. "'"; $check = $conn->query($sql); if($check){ unlink($oldImgPath); } } و بالطبع يمكنك تخصيص الشيفرة أكثر , سيحل هذا مشكلة الإحتفاظ بالصور في حالة تعديلها . لكن سيبقى مشكل توفر صور لا فائدة منها . و لتفادي هذا المشكل يمكننا إنشاء شيفرة تنفذ مرة واحدة و تحذف بعد ذلك ( one-time excutable code ) , ستتبع الشيفرة المنطق التالي : تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . تحديد العناصر الغير متوفرة في كلتا المصفوفتين . حذفها هاته العناصر . يترجم إلى : // تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . $res = mysql_query('SELECT img_profile_path from users'); $db_imgs = []; while($row = mysql_fetch_array($res)) { $db_imgs[] = $row['img_profile_path']; } // تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . $stored_imgs = glob($targetDirectory . "*.jpg"); // تحديد العناصر الغير متوفرة في كلتا المصفوفتين . $targetImages = array_merge(array_diff($db_imgs, $stored_imgs), array_diff($stored_imgs, $db_imgs)); // حذفها هاته العناصر foreach($targetImages as $image) { unlink($image); } يجب التأكد من تمليك الملف الحاوي لهاته الشيفرة الأذونات اللازمة لذلك , كما أنه يجب حذفها نهائيا بعد تنفيذها .
- 12 اجابة
-
- 1
-
يحتمل أن يكون ذلك بسبب عدم تحديث ملفات التطبيق المؤقتة , و ذلك في حالة توفر ملف بإسم home.blade.php في مجلد resources/views . و لذلك يرجى التأكد من توفر الملف المستهدف و إلا فستحتاجين إنشاءه , ثم سيمكنك محوها عن طريق تنفيذ الأمر التالي : php artisan config:clear php artisan cache:clear فمسارات التطبيق المحددة و المخزنة مؤقتا في : storage/framework/config.php قد لا تزال مضبوطة على المسار الموجود على الجهاز القديم .
-
الأمر بالطبع ليس بالبساطة التي يظهر عليها , فلتحقيق ذلك تحتاج التكامل بين الواجهتين الأمامية و الخلفية و القراءة من قواعد البيانات بإستعلامات خاصة . و لكن عموما يمكن تحقيق فكرتك بإتباع التالي : تضمين الهاتشتاغ في رابط تشعبي خاص بصفحة عرض و فلترة الهاتشتاغات في هيكلية صفحة الـ HTML . فلترة نصوص الحقل المستهدف في الجدول المستهدف بحسب الهاتشتاغ الممرر في الرابط التشعبي . عرض النتائج الحاوية لحقول حاملة لذات الهاتشتاغ . مثال عملي في لغة الـ PHP : لنقل أننا نحتاج فلترة التدوينات التي تحتوي الهاشتاغ someHashtag اخرها . تكون الهيكلية لصفحة ما مثلا : <div class="article"> <p>some dummy text some dummy text some dummy text</p> <p>some dummy text some dummy text some dummy text</p> <a href="http://my_domain.dm/path/to/filter_tags?tag=someHashtag"> #someHashtag </a> </div> في صفحة العرض المقدمة من الرابط المعرف في الخاصية href للعنصر a في الهكلية السابقة نحتاج عمل التالي : استخراج الهاشتاغ من الرابط بناء إستعلام قراءة من قواعد البيانات إنطلاقا من المستخرج عرض النتائج يترجم ذلك الشيفرة التالية : if(isset($_GET['tag']) && $_GET['hashtag'] != '') { $tag = trim($_GET['tag']); $result = mysql_query("SELECT * FROM `articles` WHERE article LIKE '%$tag%' ORDER BY `id` DESC"); while($row = mysql_fetch_array($result)) { ?> <div> <?php echo $row['article']; ?> </div> <?php } } ?> كما يمكنك تخصيص العملية و إضافة تفاصيل أخرى .
-
يستعمل الـ CROSS JOIN عادة لإنشاء ,إنطلاقا من جدولين, توليفة مزدوجة من كل صف من الجدول الأول مع كل صف من الجدول الثاني . أي إن كان الجدول الأول يحوي المعلومات : +++++++++++ |STUDENTS | |---------| |AHMED | |OMAR | |YOUNESS | +++++++++++ و الجدول الثاني المعلومات : +++++++++++ |CARS | |---------| |BMW | |MERCEDES | |HONDA | +++++++++++ فإن إستعمال الـ CROSS JOIN الذي سيقوم بتشكيل : سطر لأحمد بمحاذاة سطر BMW . // // // // MERCEDES . // // // // HONDA . و أيضا : سطر لعمر بمحاذاة سطر BMW . // // // // MERCEDES . // // // // HONDA . و أيضا : سطر ليونس بمحاذاة سطر BMW . // // // // MERCEDES . // // // // HONDA . بمعنى أنه سيتبع منطقا كالتالي : / BMW / |OMAR ---- MERCEDES \ \ HONDA / BMW / |AHMED --- MERCEDES \ \ HONDA / BMW / |YOUNESS --- MERCEDES \ \ HONDA لينتج لنا مجموعة النتائج التالية : ++++++++++++++++++++++ |STUDENTS | CARS | |---------|----------| |AHMED |BMW | |AHMED |MERCEDES | |AHMED |HONDA | | | | |OMAR |BMW | |OMAR |MERCEDES | |OMAR |HONDA | | | | |YOUNESS |BMW | |YOUNESS |MERCEDES | |YOUNESS |HONDA | ++++++++++++++++++++++ يشبه هذا جداء مجموع في الجبر , إذ يتم إستعمال النشر المزدوج كطريقة لتحليل عبارة جبرية تتضمن جداء مجموع , مثال : (a + c )( b + d ) = ab + ad + cb + cd سوى أن النتائج في الـ CROSS JOIN يتم نشرها كصفوف بنتيجة الإستعلام . السياق العام لها هو ما كالتالي : SELECT ColumnName_1, ColumnName_2, ColumnName_N FROM [Table_1] CROSS JOIN [Table_2] أو يكفي : SELECT ColumnName_1, ColumnName_2, ColumnName_N FROM [Table_1],[Table_2] و يتم استخدامه بغرض إنشاء مجموعة من كافة مجموعات العناصر بجدول ما بقاعدة البيانات ، مثل تشكيل مجموعات منازل ذات ألوان و أحجام معينة , هذا مع إمكانية التحكم في عناصر هاته المجموعات لونا أو حجما : select size, color from sizes CROSS JOIN colors ++++++++++++++++++++++ |SIZE | COLOR | |---------|----------| |XS |RED | |XS |BLUE | |XS |GREY | | | | |XM |RED | |XM |BLUE | |XM |GREY | | | | |XL |RED | |XL |GREY | |XL |BLUE | ++++++++++++++++++++++ فلو أردنا مثلا إستثناء المنازل الحمراء , فسنتثني اللون الأحمر فقط ليتم إستثناء كل التوليفات المشكلة من حجم X و لون أحمر .. : و هكذا . أو ربما تريد جدولاً يحتوي على صف لكل دقيقة في اليوم ، وتريد استخدامه للتحقق من تنفيذ إجراء ما كل دقيقة ، لذلك يمكنك تجاوز ثلاثة جداول : select hour, minute from hours CROSS JOIN minutes ++++++++++++++++++++++ |HOUR | MINUTE | |---------|----------| |13:00 |00 | |13:00 |01 | |13:00 |02 | |13:00 |03 | . . . . . . |21:00 |55 | |21:00 |56 | |21:00 |57 | |21:00 |58 | . . . . . . ++++++++++++++++++++++ فهو يخلق مجموعة إحتمالات غير مكررة ,بإعتبار أن الأعمدة تحمل قيما فريدة, إبتداءا من مجموعات محدودة من العناصر . يمكن أن يكون هذا عمليا جدا في عمليات مثل إختبار التطبيق أو بذر قواعد البيانات ببيانات تجريبية .
- 1 جواب
-
- 3
-
شائع عادة إستعمال مدير قواعد البيانات phpMyadmin لذلك . سواء في المستضيف المحلي أو على الإستضافة المشتركة . لنقم بتلخيص الأمر وفق الخطوات التالية : تصدير قواعد البيانات من المستضيف المحلي بصيغة SQL . يمكنك ذلك عن طريق الدخول إلى phpmyadmin من localhost و التوجه إلى export من قائمة التصفح العلوية التي تظهر بعد الضغط على اسم قواعد البيانات الخاصة بك , ثم اختيار صيغة التصدير و التصدير . (يمكنك تجاهل هاته الخطوة ان كنت تمتلك بالفعل ملف بلاحقة sql خاص بقاعدة البيانات التي لديك ) . الدخول إلى لوحة التحكم الخاصة بإستضافتك . الذهاب إلى phpMyadmin في الجزء الخاص بقواعد البيانات . (المثال من لوحة cPanel) قد تحتاج في بعض لوحات التحكم التي تعطي وصولا محدودا في phpMyadmin إلى إنشاء قاعدة بيانات ومستخدم كامل الصلاحيات . بعد الدخول إلى phpMyadmin تأكد أن تقوم بتحديد قاعدة البيانات المنشأة حديثا , أو أن تقوم بإنشاء واحدة جديدة , ان توفرت صلاحية ذلك , عن طريق الضغط على New أعلى القائمة الجانبية أسفل شعار phpmyAdmin . من قائمة التصفح العلوية نقوم بإختيار تضمين أو Import . قم بالتصفح إلى ملف الـ sql. الذي قمت بتصديره و قم بتحديده و تضمينه بعد الضغط على browse files . ربط موقعك بقواعد البيانات المضافة . يكون هذا عادة بملف إعداد للموقع على شاكلة env. أو init.php_ أو غيرها . قد تحتاج كخطوة إضافية في بعض الأحيان محو الملفات المؤقتة الخاصة بإعداد موقعك , و هذا في حالة إستعماله للملفات المؤقتة بالطبع (مثال : تطبيقات اللارافيل تستعمل ذلك) .
- 2 اجابة
-
- 2
-
الـ views أو العروض في SQL هي نوع من الجداول الافتراضية . تحتوي على صفوف وأعمدة مثلها مثل الجداول الحقيقية في SQL . بحيث يمكننا إنشاء العروض عن طريق تحديد حقول معينة من جدول واحد أو أكثر موجود في قاعدة البيانات الخاصة بنا . و لفهمها أكثر لنقم بفهم المثال التالي : ليكن لدينا جدول تفاصيل الطلاب students_details التالي : و ليكن لدينا جدول علامات الطلاب students_marks كالتالي : و لنقل أننا نريد إنشاء طريقة نقوم من خلالها بقراءة علامات الطلبة Mark و عناوينهم Address . واحدة من السبل لذلك هي في إنشاء العروض أو الـ Views .بحيث توفر تلخيصا لذلك في جدول افتراضي و لنقل أنه جدول بإسم students_extra_details . يمكننا إنشاء عرض ما باستخدام التعليمة CREATE VIEW مباشرة .بحيث يمكن إنشاء طريقة عرض إما من جدول واحد أو من عدة جداول بسياق عام كالتالي : CREATE VIEW view_name AS SELECT column1, column2..... FROM table1_name,table2_name , table3_name.... WHERE condition; أي : CREATE VIEW students_extra_details AS SELECT student_details.NAME, student_details.ADDRESS, student_marks.MARKS FROM student_details, student_marks WHERE student_details.NAME = student_marks.NAME; في ذاكرة الـ SQL قد تم إنشاء هاته الـ view كجدول افتراضي , يمكن معاملته كأي جدول SQL اخر . بشكل يبدوا كالتالي : الان لن نحتاج إلا لمعاملتها كجدول عادي تماما , فإستعلام القراءة SELECT مثلا يكون كالتالي : SELECT * FROM students_extra_details; و هكذا .. وراء ما يخفيه هذا الإستعمال المميزات و الفوائد التالية : الأمان و التغليف : بحيث يمكن إتاحة العروض للمستخدمين بينما لا يمكن الوصول إلى الجداول الأساسية بشكل مباشر . مما يعطي المستخدمين البيانات التي يحتاجون إليها فقط ، مع حماية البيانات الأخرى في نفس الجدول , لإستعمالها كشروط أو أغراض أخرى . كما أنها تعتبر طبقة تجريدية أو abstraction layer ، وهي تفعل ما تفعله أي طبقة تجريد جيدة ، بما في ذلك تغليف مخطط قاعدة البيانات وحمايتك من أية عواقب تنتج عن كون هيكلية قواعد البيانات مكشوفة . البساطة و الدلالية: يمكن استخدام العروض لإخفاء الاستعلامات المعقدة مثل إستعلامات الـ JOIN , فما الذي يبدوا أبسط برأيك , إنشاء طريقة عرض شاملة لكامل إستعمالاتك في التطبيق أم كتابة إستعلام JOIN كل مرة تحتاج القراءة من جدولين وفق شرط ما ؟ .. كما يمكن استخدامها لتوفير أسماء مستعارة بسيطة لأسماء الأعمدة لجعلها أكثر قابلية للتذكر أو دلالية ذات مغزى . مساحة تخزين بسيطة : بحيث تأخذ مساحة صغيرة جدًا للتخزين , فقاعدة البيانات تحتوي على تعريف العرض فقط ، وليس نسخة من جميع البيانات التي تقدمها و هذا شيء يقوم بإختصار الكثير . يمكنك القراءة أكثر عن العروض في سلسلة sql للمحترفين - مواضيع متفرقة في SQL .
- 3 اجابة
-
- 2
-
أقوم عادة بإستعمال واحد من هاته المواقع : موقع 365psd : بوصول وطريقة تحميل سهلة سريعة . موقع dribbble : القوالب التي يحتويها أحسن جودة ,و تحتاج فيه فتح حساب , و نادرا ما تجد المجاني منها . فأغلب القوالب المتوفرة مدفوعة . موقع freepik : يقوم بدمج الاثنين السابقين معا , إذ أن الوصول و التحميل سهل و سريع , يتوفر على المجاني و المدفوع بنظام فلترة . بجانب : موقعي pngtree و unsplash الغنيين عن التعريف . موقع freepsdfiles .
- 1 جواب
-
- 1
-
تعتبر أداة FFmpeg حل متعدد المنصات لتسجيل وتحويل وبث الصوت والفيديو و تعديله , و لذلك قد تتغير طريقة الإستعمال أو سياقها بتغير تفاصيل الواجهة الخلفية لموقعك مثلا . فكثير من الإضافات و الملحقات توفر واجهات سهلة للإستعانة بخدمات المكتبة و أدواتها في كثير من اللغات . فعلى سبيل المثال في php , و بإستعمال مكتبة PHP-FFMpeg/PHP-FFMpeg يتم تعديل حجم فيديو كالتالي : $video->filters()->resize($dimension, $mode, $useStandards); // example : $video->filters()->resize(new FFMpeg\Coordinate\Dimension(320, 240)) كما يمكن إضافة علامة مائية كالتالي : $video ->filters() ->watermark($watermarkPath, [ 'position' => 'relative', 'bottom' => 50, 'right' => 50, ]); يمكنك القراءة أكثر عن توثيق المكتبة هنا . كما تتوفر على أداة command Line كاملة , يمكنك الإطلاع على توثيقها مفصلا هنا .
- 2 اجابة
-
- 1
-
لنقم أولا بفهم كل منهما كالتالي : NoSQL هو نظام قواعد بيانات غير علائقي يقوم بتوفير آلية لتخزين واسترجاع البيانات التي تم تصميمها بتقنيات أو طرق غير العلاقات المجدولة المستخدمة في قواعد البيانات العلائقية مثل الشائع استعمالها في SQL . SQL , ترجمة عن Structured Query Language , لغة الاستعلامات البنائية (أو البنيوية) . هي لغة برمجة غير اجرائية تستخدم في مضمونها مفاهيم مثل العلاقات و الفهرسة . فكلاهما لغتان برمجيتان غير إجرائيتين ، أي أنهما يختلفان عن لغات البرمجة المعتادة مثل C ، فهي لغات متخصصة للتعامل والتحكم مع قواعد البيانات المترابطة من خلال التعامل مع تراكيب البيانات وإجراء عمليات إدخال البيانات والحذف والفرز والبحث والتصفية والتعديل و غيره . و نلقم بتلخيص الفروقات التالية بينهما كالتالي : من حيث نموذج تخزين البيانات Data storage model : فـ SQL تعتمد جداول بأعمدة و صفوف ثابتة و مرنة , على عكس NoSql التي تستعمل مفاهيم أخرى مثل مفتاح - قيمة (Key - Value NoSQL Database) , الجدول الكبير (Big table) و غيرها .. من حيث الهدف من إنشاء كل منهما . فـ SQL أنشئت للغرض العام , في حين أن NoSql تستوعب كميات كبيرة من البيانات مع استعلامات بحث بسيطة ،أو مع أنماط استعلام يمكن التنبؤ بها . من حيث السهولة و السرعة : تعتبر NoSql أسهل منطقا و تجريدا و تعاملا و أسرع مقارنة بـ SQL . من حيث التوسع : تتطلب منك معظم قواعد بيانات SQL التوسع عموديًا ( مثل الإضطرار إلى الانتقال إلى خادم أكبر وأكثر تكلفة) عندما تتجاوز متطلبات السعة لخادمك الحالي . على العكس من ذلك ، تسمح لك معظم قواعد بيانات NoSQL بالتوسع أفقيًا ، مما يعني أنه يمكنك إضافة خوادم سلعة أرخص كلما احتجت إلى ذلك . من حيث الإستعمال : تعتبر SQL أفضل بكثير في جانب تنظيم البيانات ,فلو كانت بياناتك منظمة للغاية ، ولا تتغير بنية أو تركيبا بشكل متكرر فـ SQL أفضل بكثير . على عكس NoSql التي يكون استعمالها شائع من حيث التعامل مع البيانات غير المهيكلة أو شبه المنظمة التي لا تتناسب مع النموذج العلائقي الذي تستعمله SQL . من ناحية الأمان : يعتبر الكثير SQL أكثر أمانا , و أفضل حلا عندما يتطلب الأمر درجة عالية من سلامة البيانات وأمانها . يمكنك القراءة أكثر عن شرح الفروقات بين قواعد بيانات SQL ونظيراتها NoSQL . كما قد تحتاج الإطلاع أكثر عن NoSQL مقابل SQL و حالات إستخدام كل واحد منهما .
- 2 اجابة
-
- 1
-
و عليكم السلام و رحمة الله . يحتمل أن يكون ذلك بسبب نسخة الـ MySql التي تستخدمها . فالسياق قد يكون غير مدعوم بعد في نسخ متأخرة من MySql أقل من النسخة الثامنة (الحالية) . يمكنك على كل حال إستبدال الإستعلام الذي لديك بالتالي : ALTER TABLE tableName CHANGE oldcolname newcolname datatype(length); أو مفصلا : ALTER TABLE `dbName`.`tableName` CHANGE COLUMN `old_columnName` `new_columnName` VARCHAR(45) NULL DEFAULT NULL;
- 8 اجابة
-
- 1
-
معروف أن العناصر و الوسوم <meta> ,تعرف أيضا بـ meta level tags, تمثل بيانات وصفية لا يمكن تمثيلها باستخدام عناصر HTML المتعلقة بالبيانات الوصفية من مثل <link> أو <title> . و تعتبر http-equiv أحد الخواص التي من الممكن أن تتخذها وسوم الـ meta هاته , هاته الخاصية تعطى قيمة ما يمكنها تعديل سلوك الخادوم أو المتصفح . وتكون قيمة هذه الخاصية موجودة ضمن الخاصية content . و من بين القيم التي من الممكن أن تأخذها الخاصية هي القيمة X-UA-Compatible , تخص هاته القيمة متصفحات IE . فإبتداءا من Internet Explorer 8 ، أصبح يمكنك إجبار مستعرض Internet Explorer على استخدام محرك Internet Explorer آخر أقدم لتفسير صفحة Html الخاصة بك . يمكن أن تأخذ الخاصية content الموافقة لهاته الخاصية القيم التالية : <meta http-equiv="X-UA-Compatible" content="IE=5" /> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> <meta http-equiv="X-UA-Compatible" content="IE=7.5" /> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" /> <meta http-equiv="X-UA-Compatible" content="IE=8" /> <meta http-equiv="X-UA-Compatible" content="IE=100" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=5" > كل قيمة تشير إلى نسخة مستهدفة من نسخ انترنت اكسبلورر . و بالطبع , لا يعد استخدام X-UA-Compatible حلاً نهائيًا لأنه ليس مدعوما و متوافقا مع جميع متصفحات Internet Explorer , فمثلما تم الإشارة الخاصية ليست مدعومة إلا بعد النسخة 8 . توثيق العنصر meta هنا .
- 2 اجابة
-
- 3
-
يمكن تعريف الـ API , اختصارا لـ Application Programming Interface ترجمة عن واجهة تطبيقات برمجية أو الواجهة البرمجة للتطبيق , كـمجموع القواعد التي تحدد كيفية اتصال تطبيقات أو واجهات , أو حتى الأجهزة ببعضها البعض . شائع بناءها في تطبيقات الويب لفصل الواجهة الخلفية تماما عن شيفرات الواجهة الأمامية يتوفير نقاط وصول أو end points للوصول إلى مصادر معينة أو تطبيق أفعال CRUD بسهولة (Create, Read ,Update , Delete ) . و يتم ذلك عن طريق إخفاء تعقيد منطق عمل وظيفة أو دالة أو تابع و تصدير طريقة بسيطة للوصول إليه و التعامل معه , يعطي هذا مرونة أكبر و قابلية أكثر للتحكم في التطبيق بواجهتيه : الأمامية و الخلفية . أما عن REST API فهي واجهة برمجة تطبيقات تتوافق مع مبادئ تصميم REST ، أو كما يعرف بالـ representational state transfer architectural style . و لهذا السبب ، يُشار أحيانًا إلى واجهات برمجة تطبيقات REST إلى واجهات برمجة تطبيقات RESTful كصفة عن REST . تتواصل هاته الـ REST APIs عبر طلبات HTTP لأداء وظائف قاعدة البيانات القياسية مثل إنشاء وقراءة وتحديث وحذف السجلات (المعروفة أيضًا باسم CRUD) داخل مورد ما . على سبيل المثال : قد تستخدم واجهة برمجة تطبيقات REST كلا من التالي : طلب GET لاسترداد الموظفين في قاعدة بياناتنا . طلب POST لإنشاء موظف جديد . طلب PUT أو PATCH لتحديث بيانات موظف . طلب DELETE لحذف بيانات موظف . و يعبر عن ذلك بـ : GET https://your_domain.dm/api/v.x/teachers POST https://your_domain.dm/api/v.x/teachers PATCH https://your_domain.dm/api/v.x/teachers/{teacher_id DELETE https::/your_domain.dm/api/v.x/teachers/{teacher_id} يتم وراء هاته الروابط أو النقاط سهلة الوصول إخفاء كل تعقيد , من الإتصال بقواعد البيانات و التحقق من الطلبية و معالجتها و إعادة الرد عليها . يمكن تلخيص مجموعة مبادئ REST التي تعطي صفة الـ RESTful لكل واجهة برمجية تلتزم بها كالتالي : الواجهة الموحدة (uniform interface) : يجب أن تبدو جميع طلبيات واجهة برمجية ما للمورد نفسه بنفس الشكل متبعة نفس النسق , أي أن كل من الطلبات و الشكل العام لنقاط الوصول و الردود و غيرها يجب أن تتبع نسقا موحدا . فصل واجهة العميل عن واجهة الخادم (Server - Client أو Client-server decoupling) : يفرض نمط تصميم عميل - خادم مبدأ فصل الاهتمامات التي تساعد مكونات العميل والخادم على التطور بشكل مستقل . و ذلك من خلال فصل اهتمامات واجهة المستخدم (العميل) عن اهتمامات تخزين و معالجة البيانات (الخادم) . عدمية الحالة (Stateless أو Statelessness) : يجب أن تكون واجهات برمجة تطبيقات REST عديمة الحالة ، مما يعني أن كل طلب يحتاج إلى تضمين جميع المعلومات اللازمة لمعالجته. بمعنى آخر ، لا تتطلب واجهات برمجة تطبيقات REST أي جلسات من جانب الخادم. لا يُسمح لتطبيقات الخادم بتخزين أي بيانات متعلقة بطلب العميل . قابلية التخزين بشكل مؤقت (Cacheability أو Cacheable) : بحيث يتطلب أن يتم تصنيف البيانات الموجودة في الاستجابة بشكل ضمني أو صريح على أنها قابلة للتخزين المؤقت أو غير قابلة للتخزين المؤقت . إذا كانت الاستجابة قابلة للتخزين المؤقت ، فسيتم منح تطبيق العميل الحق في إعادة استخدام بيانات الاستجابة لاحقًا ، للطلبات المكافئة ولفترة زمنية محددة . مثل : طلبات سجل الموظفين يتم تخزينها في الذاكرة المؤقتة و لا حاجة لإعادة تنفيذ الإستعلام إلا كل ساعة مثلا . في حين أن جلب معلومات سجل التعاملات أو المدفوعات غير قابل للتخزين بشكل مؤقت . نظم الوسطاء (Layered system) : ففي REST APIs ، تمر كل من المكالمات والاستجابات عبر طبقات مختلفة. و كقاعدة عامة ، لا يفترض من تطبيقات العميل والخادم أن تتصل ببعضها البعض مباشرة. قد يكون هناك عدد من الوسطاء المختلفين في حلقة الاتصال. فيجب تصميم واجهات برمجة تطبيقات REST بحيث لا يمكن للعميل أو الخادم معرفة ما إذا كان يتواصل مع التطبيق النهائي أو الوسيط . مفاهيم مثل الطبقات الوسيطة أو الـ middlewares شائعة جدا بهذا الخصوص . يمكنك الإطلاع على هذا السؤال بشأن المبدأين Stateless و Cacheable هنا . كما يمكنك التعرف أكثر على أسباب التوجه إلى تطوير الخدمات في الواجهات الخلفية كـ API هنا .
- 2 اجابة
-
- 2
-
لنقم بتفكيك الإستعلام لفهمه أولا : نحتاج تحديد معرف الشركة التي لها أكبر عدد موظفين سابق , و ذلك عن طريق قراءة أكثر قيمة معروفة أو مكررة في جدول الموظفين people . يترجم إلى : SELECT PREV_COMPANY_ID FROM people GROUP BY PREV_COMPANY_ID ORDER BY COUNT(PREV_COMPANY_ID) DESC LIMIT 1; بناء على نتيجة الإستعلام السابق , نحتاج تحديد وجلب معلومات هاته الشركة , و يكون ذلك عن طريق القراءة من جدول الشركات companies : SELECT * FROM companies WHERE id = TARGET_RESULTED_ID حيث أن القيمة TARGET_RESULTED_ID هي القيمة الناتجة عن الإستعلام السابق . ثم بمساعدة الإستعلام الفرعي أو الـ sub Query لنقم بدمجهما معا ليكونا على النحو التالي : SELECT * FROM companies WHERE id = ( SELECT company_id FROM people GROUP BY company_id ORDER BY COUNT(company_id) DESC LIMIT 1 ) و ما سيقوم به هذا الإستعلام هو ببساطة كالتالي : جلب معلومات الشركة التي معرفها يساوي ( أكثر معرف شركة مكرر في جدول الموظفين ) . و بعبارة أخرى :
- 1 جواب
-
- 1
-
كحل نهائي لجميع المشاكل يقترح إستعمال باني إستعلامات عوضا عن إستعلامات SQL جاهزة من الواجهة DB , و ذلك لأن العديد من الإستعلامات التي نكتبها قد لا تعمل مع نظم إدارة قواعد بيانات أخرى تختلف عن تلك التي اختبرنا عليها إستعلاماتنا الأولى . و إلا فإننا سنحتاج تنقيح كل إستعلاماتنا لتلائم بيئة إنتاجنا . إستعمال Eloquent سيحد من هذا المشكل . فمثال مثل الذي لديك : DB::select( 'SELECT id FROM teachers WHERE (subject_id = ? AND levels = ?) OR EXISTS (SELECT id FROM users WHERE name = ? AND phone = ?)', [$request->subject, json_encode($request->levels), $request->name, $request->mobile] ); يصبح : DB::table('teachers') ->where('subject_id', $subject) ->where('levels',json_decode($request->levels)) ->orWhereExists(function($query) { DB::table('users') ->where('name',$request->name) ->where('phone',$request->mobile) ->select('id'); }) ->select('id') ->get(); و هكذا .. يعطي هذا مرونة أكبر و قابلية أكثر للتلائم مع كامل النظم . تعرف على المبادئ الأساسيّة لإطار العمل Eloquent ORM .
-
لاحظ أن عنصر الفقرة التالية : <p>Unlimited Possibilities</p> يمتد على عرض أكثر من عرض الحاوي له , و ذلك حتى يحافظ على التخطيط الشبكي grid layout للعنصر الحاوي له بالصنف التالي : intro__container . يسبب تمدده على عرض أكبر من عرض الصفحة امتلاكه للخاصية التالية : .intro p:last-of-type { font-size: 3.8rem; } فلو تقم بتقليل حجم الخط الذي يمتلكه ستلاحظ عودة الصفحة لحجمها الطبيعي , و ذلك لعدم إمتداد الحاوي الشبكي على عرض أكبر من عرض الصفحة . و ليكن مثلا حجم الخط 2.1rem . جعل أحجام الخطوط تجاوبية يجب أخذه بالإعتبار أيضا , و لذلك أفضل تقليل حجم النص لعنصر الفقرة عوضا عن إعطاء العنصر body القيمة fit-content للخاصية min-width . فهاته القيمة ليست مدعومة بعد من قبل كامل متصفحات الويب .
- 9 اجابة
-
- 1
-
يبدوا أن العنصر body لا يأخذ كامل عرض الصفحة في الشاشات الأقل من 343 بكسل . إعطاء العنصر body القيمة fit-content في خاصية العرض الأدنى للعنصر min-width قام بحل المشكل لدي: body{ min-width: fit-content; } توثيق الخاصية : هنا .
-
يمكنك أيضا ذلك عن طريق إستعمال التابع replace لإستبدال كل الفواصل الناتجة عن تحويل المصفوفة إلى سلسلة نصية بإستعمال toString كالتالي : var arr = ['hsoub' ,'academy' ,'is' ,'cool']; console.log( arr.toString().replace(/,/g ,' ') ); // hsoub academy is cool كما يمكنك إستعمال الباني الخاص بـالصنف String كالتالي : var arr = ['hsoub' ,'academy' ,'is' ,'cool']; console.log( String(arr).replace(/,/g,' ') ); // hsoub academy is cool و لكن عيب هاتين الطريقتين هو في إحتمالية إحتواء أحد عناصر المصفوفة فاصلة مثل "h,soub" . لن يتم إعتبارها و سيتم إستبدالها بفراغ بكل حال من الأحوال . و كحل لهاته المشكلة يمكنك إستعمال بدلا من ذلك الطريقة التالية : تقليل المصفوفة إلى قيمة واحدة عن طريق التابع reduce بإستعمال فاصل مخصص كالتالي : var arr = ['hsoub' ,'academy' ,'is' ,'cool,' ,'awesome' ,'and great!']; arr.reduce((str, a) => { return str +' '+ a }); // hsoub academy is cool, awesome and great! يمكنك الإطلاع على كل من : توثيق التابع replace . توثيق الكائن String . توثيق التابع reduce .
-
نعم بالضبط . و أضيف على ذلك , التوابع أيضا . فمن الممكن تغليف التوابع و جعلها غير قابلة للوصول إلا من خلال الصنف نفسه أيضا . كما أظن أن الحاجة لذلك في مسارك و أثناء تطبيقك العملي ستقوم بتوضيح ذلك أكثر لك . تعرف الكلمات public , private و protected في الوسط البرمجي كمحددات وصول ترجمة عن Access Modifiers بحيث تحدد هاته الكلمات الخواص و التوابع التي يمكن الوصول إليها . بحيث أن : public : تعني أن الوصول إليها قابل في كل مكان . protected : تعني أن الوصول محمي فقط داخل الصنف نفسه , و من داخل أي أصناف ترث هذا الصنف أيضا . private : تعني أن الوصول لا يتم إلا من خلال الصنف الذي يحدد هاته الخاصية أو أحد توابعه العامة . .
- 4 اجابة
-
- 1
-
و عليكم السلام و رحمة الله تعالى و بركاته . لنقم بفهم التغليف كالتالي : التغليف ترجمة عن encapsulation هو ميكانيزمة و طريقة لحماية الخواص و التوابع التابعة لصنف ما من التعديل المباشر عليها مع إمكانية إستعمال تابع معين للصنف لتعديل ذلك . و لكن ما الذي يعنيه ذلك ؟ لنأخذ التالي لفهم الحاجة من التغليف أساسا : تقوم شركات صنع سيارات بتوفير مقود في سياراتها كآلة للتحكم في إتجاهات سير السيارة , و من جانب اخر تقوم بإخفاء التعقيد وراء هاته العملية . أي أنها تقوم بتغليف و تغطية كل ما يتعلق بكيفية سيرها و توفير طريقة بسيطة لتغيير خاصية الإتجاه في السيارة . فهل يبدوا من المنطقي أن نقوم بتوصيل سلك بسلك أو تطبيق قوة ميكانيكية كل مرة نريد فيها تغيير اتجاه سيارة ؟ نفس الشيء ينطبق على التغليف في البرمجة الشيئية , فتغيير الخاصية مباشرة لا يكون سليما أحيانا , و قد يتعلق بمنطق عمل توابع أخرى تتأثر بتغير قيمة هاته الخاصية . و لكن تغييرها عن طريق توفير تابع يقوم بتحمل و اعتبار تبعات هذا التعديل حل نهائي للمشكلة . مثال عملي : ليكن الصنف DBInteract , المسؤول عن التفاعل مع قاعدة البيانات عن طريق عمليات CRUD العادية كالتالي : class DBInteract{ public $db_password = '68426123'; public $db_username = 'root'; public $db_name = 'my-db'; public function insert(string $table ,array $data) { } public function update(string $table ,array $data) { } public function delete(string $table) { } public function select(string $table ,array $rows) { } } و لنفرض أن كل من التوابع المعرفة تحمل شيفرات يمكن فهم وظيفتها عن طريق اسماءها الدلالية . و لنقل أننا نحتاج إدراج مهمة جديدة بجدول tasks في قاعدة البيانات بإسم my-db . أي أن العملية ستكون كالتالي : $db_class = new DBInteract(); $db_class->insert('tasks' ,$data); و منطقي هو أن التابع insert المسؤول عن عملية الإنشاء سيقوم بإستعمال الخواص التالية لمصادقة إتصاله مع قواعد البيانات : public $db_password = '68426123'; public $db_username = 'root'; public $db_name = 'my-db'; المشكلة هنا , هي أن هاته الخواص قابلة للوصول بشكل عادي عن طريق إستدعاء مباشر من أي كائن عن الصنف DBInteract . فلو أن مستخدما ما لصنفنا الجاهز DBInteract قام بتغيير الخاصية db_name بعد عشرات من إستعلامات الإنشاء و القراءة و الحذف و التعديل بمجرد سطر واحد : $db_class->db_name = 'new-db-name'; و لنقل أن بيانات المصادقة تحتاج فحصا قبل إعادة التعيين مثل أن يكون اسم قاعدة بياناتنا سلسلة نصية , و اسم مستخدمنا ليس قيمة فارغة , و كلمة سرنا تشكيلة أرقام . في حالة تعطل ذلك سيخل هذا بعمل كل من التوابع insert , update , delete , select . و هو ما لا نريده طبعا . و لحل المشكل لن نقوم إلا بتغليف هاته الخواص بإستعمال الكلمة المفتاحية private و إنشاء تابع جديد يمكننا من تغيير بيانات المصادقة هاته بطريقة سليمة لا تؤثر على عمل باقي التوابع . و ليكن مثلا : class DBInteract{ private $db_password = '68426123'; private $db_username = 'root'; private $db_name = 'my-db'; public function changeCreds($pass , $un , $db) { if(is_string($db) && is_numeric($pass) && !is_null($un)){ $this->db_password = $pass; $this->db_username = $un; $this->db_name = $db; } } public function insert(string $table ,array $data) { } public function update(string $table ,array $data) { } public function delete(string $table) { } public function select(string $table ,array $rows) { } } الان لو حاول شخص ما تغيير أحد بيانات المصادقة عن طريق مباشرة فهو لن يستطيع , و ستظهر له رسالة تخبره بذلك : cannot access private property و قس على ذلك العديد من الأمثلة و الوضعيات الأخرى التي تكون فكرة التغليف حلا فيها .
- 4 اجابة
-
- 2