سامح أشرف
-
المساهمات
2934 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
56
إجابات الأسئلة
-
إجابة سامح أشرف سؤال في كيفية إستخدام صور SVG في React Native؟ كانت الإجابة المقبولة
يمكنك إستخدام الحزمة react-native-svg لإضافة دعم صور SVG إلى React Native، في البداية عليك تثبيت الحزمة من خلال الأمر التالي:
npm i react-native-svg // using yarn yarn add react-native-svg ثم قم بربط الحزمة من خلال الأمر التالي:
react-native link react-native-svg أو إذا كنت تستعمل expo فيمكنك تثبيت الحزمة من خلال الأمر التالي فقط:
expo install react-native-svg وتستطيع إستخدام الحزمة بالشكل التالي:
import * as React from 'react'; import { SvgXml } from 'react-native-svg'; import testSvg from './test.svg'; export default () => <SvgXml width="200" height="200" xml={testSvg} />; أو من خلال عوان URL:
import * as React from 'react'; import { SvgUri } from 'react-native-svg'; export default () => ( <SvgUri width="100%" height="100%" uri="http://example.com/images/svg-image.svg" /> );
-
إجابة سامح أشرف سؤال في كيفية تحديث إصدار react native إلى أحدث إصدار؟ كانت الإجابة المقبولة
يمكنك إستعمال أداة سطر الأوامر React Native CLI للقيام بهذا الأمر من خلال تشغيل الأمر التالي:
npx react-native upgrade تستطيع أيضًا تحديد إصدار معين للتحديث إليه بدلًا من التحديث إلى أحدث إصدار:
npx react-native upgrade 0.61.0-rc.0
-
إجابة سامح أشرف سؤال في كيفية إيقاف إضافة eslint في مشروع React؟ كانت الإجابة المقبولة
يمكنك أن تقوم بعمل ملف env. وتضع فيه السطر التالي:
DISABLE_ESLINT_PLUGIN=true أو في ملف package.json يمكنك أن تقوم بتعديل قيمة scripts للشكل التالي:
{ "scripts": { "start": "DISABLE_ESLINT_PLUGIN=true react-scripts start", "build": "DISABLE_ESLINT_PLUGIN=true react-scripts build", "test": "DISABLE_ESLINT_PLUGIN=true react-scripts test" } } طريقة أخرى هي عمل ملف .eslintignore وتضع فيه نجمة * ليتم تجاهل كل الملفات الموجودة في المشروع:
# .eslintignore file *
-
إجابة سامح أشرف سؤال في كيفية إستدعاء method من داخل تابع آخر في JavaScript عبر prototype؟ كانت الإجابة المقبولة
سبب المشكلة لديك هو أن التابع method2 ليس دالة عامة global function وإنما هو تابع method ضمن الكائن Obj، وبتالي بإستدعائها، يجب أن تستخدم this، على النحو التالي:
const Obj = function(){ // ... } Obj.prototype.method1 = function(){ // في هذا الجزء نُشير إلى التابع method2 // الموجود ضمن الكائن Obj // وبما أننا داخل تابع آخر ضمن نفس الكائن // فيجب أن نستخدم this للإشارة إلى الكائن الحالي this.method2(); } // هنا نضيف التابع method2 إلى الكائن Obj Obj.prototype.method2 = function(){ console.log('execute method2'); } const o = new Obj(); o.method1(); وستجد أن التابع method2 يتم إستدعائه بشكل سليم.
-
إجابة سامح أشرف سؤال في اختصارات flutter كانت الإجابة المقبولة
هذا الأمر متوقف على محرر الأكواد الذي تستعمله وليس لغة البرمجة أو إطار العمل نفسه.
إن كنت تستعمل برنامج VS Code فحاول إستخدام الإختصارات التالية:
لإقفال كل الدوال أضغط CTRL + K ثم CTRL + 0 (صفر) أو إضغط على CTRL + K + 0 معًا لإقفال كل شيء (دوال، أصناف، توابع .. إلخ). لإعادة فتحهم أضغط CTRL + K ثم CTRL + J كما يمكنك معرفة كل الإختصارات الموجودة في البرنامج من خلال الضغط على CTRL + K ثم CTRL + S وستظهر لك كل الإختصارات shortcuts المتاحة لديك ويمكنك تعديلها حسب رغبتك.
-
إجابة سامح أشرف سؤال في كيفية إستدعاء تابع method موجود في صنف class من خلال نص في JavaScript؟ كانت الإجابة المقبولة
يوجد أكثر من طريقة للقيام بهذا الأمر، وأسهل طريقة هي إستخدام طريقة الأقواس للوصول إلى التابع، كما يلي:
firstUser["getAll"]; // access the method firstUser["getAll"](); // call the method وبالتالي يمكننا إستخدام ما يرجعه التابع methodName مكان النص في المثال السابق:
firstUser[methodName()]; // access the method firstUser[methodName()](); // call the method أيضًا توجد طريقة أخرى عبر إستخدام الدالة eval:
eval("firstUser." + methodName() + "()"); لكن لا يُفضل إستخدام هذه الطريقة لأنها قد تؤدي إلى وجود ثغرة XSS والتي تسمح للمهاجم بتنفيذ أكواد JavaScript ضارة بالمستخدم بغرض سرقة البيانات أو التخريب بشكل عام.
-
إجابة سامح أشرف سؤال في خطأ unexpected token في كود JavaScript كانت الإجابة المقبولة
يوجد خطأ لديك في JavaScript حيث أنك نسيت علامة = بعد كلمة langs مباشرة.
حاول أن تقوم بتعديل كود JavaScript وإضافة علامة المساواة بعد كلمة let langs مباشرة وقم بحفظ الملف وأعد تحديث الصفحة في المتصفح وسيعمل الكود بدون مشكلة.
-
إجابة سامح أشرف سؤال في كيفية عمل أصناف مجهولة Anonymous classes في PHP؟ كانت الإجابة المقبولة
لم تكن لغة PHP تدعم فكرة الأصناف المجهولة Anonymous classes في الماضي ولكن بداية من الإصدار 7 تم إضافة هذا المصطلح إلى اللغة وأصبح بإمكانك أن تقوم بهذا الأمر بشكل بسيط من خلال إستخدام الكلمة المفتاحية new و عمل صنف class بدون اسم على النحو التالي:
new class { public function log($msg) { echo $msg; } } ويمكن تخزين الصنف في متغير أيضًا:
<?php class Foo {} $child = new class extends Foo {}; var_dump($child instanceof Foo); // true تكون الأصناف المجهولة Anonymous classes مفيدة عندما يلزم إنشاء كائنات بسيطة لمرة واحدة وبشكل سريع.
-
إجابة سامح أشرف سؤال في كيفية التحقق من أن صنف class ما يستخدم واجهة معينة interface في PHP؟ كانت الإجابة المقبولة
تدعم لغة PHP المعامل instanceof والذي يسمح لك بالتأكد من أن كائن معين عبارة عن مثيل instance من صنف معين أو يستخدم واجهة معينة interface، ويمكن إستخدامه كما يلي:
<?php interface IUser { // ... } class MyClass implements IUser { // ... } $obj = new MyClass(); if ($obj instanceof IUser) { echo "obj implements IUser\n"; } if ($obj instanceof MyClass) { echo "obj is instance of MyClass"; } /* Output: obj implements IUser obj is instance of MyClass */ أيضًا يمكنك إستخدام الدالة class_implements والتي تسمح بمعرفة الواجهات التي يستعملها الصنف:
$obj = new MyClass(); print_r(class_implements('MyClass')); /* Output: Array ( [IUser] => IUser ) */ وبالتالي يمكن إستخدام هذه الطريقة للتحقق من أن الصنف يستخدم واجهة معينة من خلال isset كما يلي:
$obj = new MyClass(); $interfaces = class_implements('MyClass'); if (isset($interfaces['IUser'])) { echo "obj implements IUser"; } مع العلم أن الطريقة الأولى (المعامل instanceof) أسرع في الأداء من الطريقة الثانية (الدالة class_implements).
-
إجابة سامح أشرف سؤال في كيفية عمل abstract class في JavaScript؟ كانت الإجابة المقبولة
في إصدار جافاسكريبت ECMAScript 2015 (المعروفة بـ ES6) تم دعم صيغة الصنف class-syntax لعمل أصناف جديدة ولكن لم يتم تقديم أي صيغة لعمل أصناف مجردة، ولكن بالرغم من ذلك إلا أنه يمكن عمل أصناف مجرد بمساعدة الكلمة المفتاحية new على النحو التالي:
class AbstractUser { constructor () { if (new.target === AbstractUser) throw TypeError("Cannot instantiate abstract class AbstractUser"); } } وفي الدالة البانية يمكن إستخدام نفس الطريقة كما يلي:
function AbstractUser() { if (this.constructor === AbstractUser) throw new Error("Cannot instantiate abstract class AbstractUser"); } وعند محاولة عمل نسخة جديدة من الصنف AbstractUser سيظهر خطأ:
new AbstractUser(); // Error: Uncaught TypeError: Cannot instantiate abstract class AbstractUser في حالة كنت تستعمل TypeScript فيمكنك عمل صنف مجرد abstract class بشكل بسيط مثل أغلب لغات البرمجة المعروفة من خلال الكلمة المفتاحية abstract على النحو التالي:
abstract class AbstractUser { name: string; constructor(name: string) { this.name = name; } }
-
إجابة سامح أشرف سؤال في كيفية نسخ كائن Object بالكامل في جافاسكريبت JavaScript؟ كانت الإجابة المقبولة
يوجد العديد من الطرق التي تُمكنك من نسخ clone كائن بالكامل، من ضمن هذه الطرق:
إستخدام JSON
const clone = JSON.parse(JSON.stringify(myObj)); تفي هذه الطريقة بالغرض عند التعامل مع الكائنات البسيطة (التي لا تحتوي على توابع Methods)، ولكن سيظهر خطأ TypeError إذا كان الكائن myObj يحتوي على أي توابع Methods.
طريقة Shallow Copy
const shallowClone = { ...myObj }; تقوم هذه الطريقة بعمل نسخة سطحية من الكائن وتخزينها في المتغير الجديد، ولكن ستظل كل التوابع والخصائص تُشير إلى نفس الكائنات بدون تغير.
إستعمال مكتبة jQuery
مثل مكتبة lodash توفر jQuery التابع extend والذي يقوم بنسخ الكائن بشكل كامل أيضًا:
var clone = $.extend(true, {}, myObj); ستعمال مكتبة Lodash
توفر مكتبة lodash الكثير من التوابع للتعامل مع الكائنات بشكل عام، ومن ضمن هذه التوابع يوجد التابع clone والذي يوفر إمكانية نسخ كائن بالكامل بطريقة سهلة وبسيطة:
var clone = _.clone(myObj); لا يوجد فرق بين طريقة shallow clone السابقة والتابع clone، ولكن توفر lodash أيضًا تابع باسم cloneDeep والذي يقوم بنسخ الكائن بالكامل وليس مجرد نسخ سطحي:
var clone = _.cloneDeep(myObj);
-
إجابة سامح أشرف سؤال في مساعدة في توجيهي لمواصلة تعلم البرمجة كانت الإجابة المقبولة
وعليكم السلام ورحمة الله وبركاته
من الجيد جدًا أنك لا تريد تخطي أي نقاط بدون فهما بشكل كامل، وتريد تعلم كل ما تحتويه الدروس بشكل جيد، وهذا الأمر من صفات المبرمج البارع.
أعتقد أن المشكلة لديك في عدم تحديد هدف واضح وصريح، فالبرمجة متشعبة للغاية وتحتوي على العديد من الفروع والأقسام ومن الصعب للغاية أن يتعلم شخص واحد كل الفروع، في الواقع من الصعب حتى تجربة كل فروع البرمجة بشكل متأنٍ تجربة شاملة، لذلك يجب في البداية تحديد هدف واضح، هل تريد أن تكون مطور واجهات أمامية Frontend Developer؟ أم تريد أن تكون مبرمج واجهات خلفية Backend Developer؟ أم تريد أن تجمع بينه المجالين معًا لتصبح مطور شامل Full-stack Developer؟ بناءً على إجابة هذا السؤال ستحدد ما الذي عليك تعلمه بشكل متعمق وما الذي تحتاج إلى الإطلاع عليه فقط ولا تحتاج إلى دراستها بشكل مفصل.
بما أنك إشترك في دورة PHP الخاصة بالأكاديمية فأتوقع أنك تريد أن تصبح أما مبرمج واجهات خلفية Backend Developer أو مبرمج شامل Full-stack Developer، في الحالة الأولى ليس عليك الإهتمام بأمور التنسيق مثل CSS و SCSS و Tailwind وغيرها من الأمور، يكفي فقط أن الإطلاع على هذه التقنيات إطلاعًا بسيطًا يساعدك على تخيل كيف يتم إنشاء باقي الموقع في جزء الوجهة الأمامية Frontend، وأنا لا أقصد أن تعلم هذه التقنيات ليس مفيدًا بل أقصد أن التركيز على تقنيات الوجهات الخلفية Backend والخوادم Server وقواعد البيانات Databases له الأولوية ومن الأفضل تعلم تقنيات مجالك على التنقل بين تنقيات مجال مختلف بدون فائدة مرجوة وواضحة منها.
أما إن كان هدفك هو أن تصبح مبرمج شامل Full-stack Developer فحينها سيختلف الأمر كثيرًا لأنك يجب أن تتعلم التقنيات الموجودة في المجالين (Frontend + Backend)، وفي هذه الحالة يجب أن تدرس CSS و SCSS و Tailwind CSS و Bootstrap وغيرها من التقنيات لأنها جزء لا يتجزء من عملك كمطور شامل، بالطبع مع تعلم تقنيات الواجهات الخلفية Backend كذلك.
في العادة يتعلم الشخص الذي يهدف إلى أن يصبح مطور شامل تقنيات الواجهات الأمامية Frontend، لأنها أسهل وترى نتيجة الكود الخاص بك بشكل مباشر في المتصفح، مما يعغطية دفعة معنوية ويساعدة على إكمال رحلته في تعلم البرمجة، على عكس تقنيات الواجهات الخلفية التي لا تحتوي على أي تأثيرات أو ألوان وفي الغالب تكون تعامل مع الكود المنطقي وقواعد البيانات فقط، ولكن بما أنك تعلمت أساسيات PHP وقواعد البيانات وكذلك إطار عمل مثل Laravel بالإضافة إلى إدراكك كيفية إستخدام HTML و CSS ولو بشكل بسيط، فمتاح لك الآن أما أن تكمل بتعلم تقنيات الواجهات الأمامية Frontend أو تقنيات الواجهات الخلفية Backend ولن تواجهة مشكلة في فهم أي منهما لأن لديك بالفعل فكرة واضحة عن التقنيات المستخدم في كلا المجالين.
لاحظ أيضًا أن لغات مثل CSS و JavaScript هي لغات ضخمة وتحتوي على العشرات والمئات من الخصائص والكائنات والكثير من الأمور التي يجب تعلمها، وهذا الأمر سيستغرق منك الكثير من الوقت، ولهذا السبب أنصحك أن تتعلم CSS بجانب دراسة دورة PHP التي إشتركت بها، ويمكنك خلال تطبيق الدروس أن تستخدم CSS للتدريب عليها، وبهذا تستفيد من كلا الجانبين.
بما أنك مشترك في دورات حسوب فستجد أن المسار الأول من كل دورة متاح لك ويمكنك الإطلاع عليه، وأنصحك أن تستغل هذه الفرصة وتقوم بالإطلاع على المسار الأول من دورة تطوير واجهات المستخدم Frontend لتدرس CSS و Bootstrap و jQuery بشكل جيد وتقوم بعمل موقع شخصي بسيط من الصفر بإستخدام هذه التقنيات. بعد إتمام هذا المسار تستطيع الإطلاع على Tailwind CSS من خلال التوثيق الرسمي له، ولن تواجهة مشاكل في فهم كيفية إستخدامه في مشاريعك، كما ستفهم أكثر ما هي أصناف Tailwind التي يضيفها المدرب ضمن مشاريع Laravel في دورة PHP.
ليكون الأمر أكثر وضوحًا، ستجد هنا مجموعة من الخطوات المتسلسلة التي يمكنك إتباعها لتعلم ما ينقصك لتصبح مبرمج شامل Full-stack Developer:
تابع المسار الأول ضمن دورة تطوير واجهات المستخدم Frontend، ستتعلم في هذا المسار أساسيات CSS و Bootstrap و jQuery بشكل جيد وتقوم بعمل موقع شخصي بسيط من الصفر بإستخدام هذه التقنيات. أقرأ توثيق Tailwind CSS بعناية وحاول أن تستخدمه ضمن المشاريع التي قمت بها سابقًا، وسيتجد ضمن توثيق Tailwind شرح كيفية إستخدامه من الصفر أو ضمن مشاريع Laravel أيضًا. تابع إكمال دورة تطوير الواجهات الخلفية بإستخدام PHP، وحاول أن تقوم بعمل جزء الواجهة الأمامية بنفسك دون الإطلاع على شرح المدرب، لتتدرب على CSS و Tailwind معًا. بعد إكمال دورة تطوير الواجهات الخلفية بإستخدام PHP، حاول أن تقوم بالإطلاع على دورة تطوير التطبيقات بإستخدام JavaScript لأنها تحتوي على الكثير من الأمور المفيدة لك مثل Node.js و React.js و MongoDB .. إلخ. الآن ستكون قد أتمت رحلة التعلم، ولكن البرمجة لا تتوقف وستجد في كل يوم تحديثات كثيرة لكل التقنيات التي تستخدمها، حاول أن تبقى على إطلاع بالمواقع التقنية وتحديثات حسوب وكذلك المقالات التي يتم نشرها ضمن الأكاديمية. الخطوات السابقة ليست إجبارية ويمكنك أن تقوم بتعديلها لتتوافق مع أهدافك وظروفك الشخصية كما تشاء.
-
إجابة سامح أشرف سؤال في كيفية إستدعاء تابع في الصنف الأب من الصنف الأبن في جافاسكريبت JavaScript؟ كانت الإجابة المقبولة
يمكن القيام بهذا الأمر بطريقة سهلة من خلال الكلمة المفتاحية super والتي تُستخدم للإشارة إلى الصنف الأب Parent Class على النحو التالي:
class User { showAll() { console.log('showAll method from User class'); } } class Admin extends User { showAll() { super.showAll(); console.log('showAll method from Admin class'); } } الآن يمكن عمل كائن من الصنف Admin وإستدعاء التابع showAll:
const admin = new Admin(); admin.showAll(); /* Output: showAll method from User class showAll method from Admin class */ ملاحظة: إن كان التابع showAll الموجود في الصنف User عبارة عن تابع ساكن Static Method فيجب أن يتم إستدعائه عبر تابع ساكن أيضًا، على النحو التالي:
class User { static showAll() { console.log('showAll method from User class'); } } class Admin extends User { static showAll() { super.showAll(); console.log('showAll method from Admin class'); } } Admin.showAll(); /* Output: showAll method from User class showAll method from Admin class */
-
إجابة سامح أشرف سؤال في كيف يمكن عمل method chaining في صنف Class في PHP؟ كانت الإجابة المقبولة
يمكن عمل هذا الأمر بشكل بسيط للغاية في PHP، فكل ما عليك فعله هو إرجاع نفس الكائن في نهاية كل تابع:
على سبيل المثال إن كان لدينا الصنف التالي:
<?php class MyClass { public function doSomething() { // ... } public function doSomethingElse() { // ... } } يجب فقط إرجاع نفس الكائن في نهاية كل تابع عبر الكلمة this$:
<?php class MyClass { public function doSomething() { // ... return $this; } public function doSomethingElse() { // ... return $this; } } بهذا الشكل يمكن إستخدام التوابع كما يلي:
$obj = new MyClass(); $obj->doSomething()->doSomethingElse(); لاحظ أن هذه الطريقة لا يمكن عملها إن كان يجب إرجاع شيء مُحدد من أحد التوابع.
-
إجابة سامح أشرف سؤال في كيفية الوصول إلى خاصية property في صنف class عبر نص في PHP؟ كانت الإجابة المقبولة
يمكنك أن تستخدم الأقواس المعقوفة { } للوصول إلى الخاصية content على النحو التالي:
<?php class MyObject { public $content = "hello"; } $obj = new MyObject(); $obj->property_name = 'content'; $result = $obj->{$obj->property_name}; echo $result; // hello ليس عليك حتى تخزين اسم الخاصية content في خاصية أخرى property_name ويمكنك إستخدام المتغيرات مباشرة:
<?php class MyObject { public $content = "hello"; } $obj = new MyObject(); $name = 'content'; $result = $obj->$name; echo $result; // hello
-
إجابة سامح أشرف سؤال في كيف أقوم باختيار تدرجات الألوان المناسبة كانت الإجابة المقبولة
يوجد العديد من الأدوات التي تساعدك في الحصول على ألوان متناسقة لإستعمالها في أي نوع من التصاميم، هنا بعض هذه الأدوات:
color mind mycolor space colorhunt coolors كما دوجد بعض الأدوات التي تسمح لك برفع صورة وإستخراج نمط الألوان منها مثل أداة image-picker من coolors، وتوجد أداوت تساعدك في مقارنة الأوان وحساب نسبة التباين بين الأوان مثل أداة contrast-checker التي تعرض لك رقم ما بين 1 و 21، تستخدم هذه الأداة لكي تعرف الأوان الصحيحة التي يجب إستخدامها في النصوص والخلفيات.
كما توجد أدوات تسمح لك بإضافة لون معين وتعرض عليك بعد ذلك مجموعة من الألوان المتناسقة مع اللون الذي أدخلته، بالإضافة إلى مجموعة واسعة من تدرجات هذا اللون، بعض الأمثلة:
colorhexa paletton في هذه المقالة المقدمة من موقع مستقل ستجد شرح لأشهر الألوان ومتى تستخدم كل لون، وبالرغم من أن المقالة تتحدث عن الهوية البصرية بشكل أساسي إلا أن المعلومات التي تحتويها تصلح كذلك في تصميم المواقع والتطبيقات: كيف تختار ألوان الهوية البصرية التي تناسب علامتك التجارية؟
-
إجابة سامح أشرف سؤال في كيفية التأكد من أن الكائن Object عبارة عن نسخة instance من صنف معين في JavaScript؟ كانت الإجابة المقبولة
توفر لغة JavaScript العديد من الطرق التي تُمكنك من التأكد من نوع كائن Object معين، هنا بعضها:
إستخدام typeof
تستخدم هذه الطريقة للتأكد من أن متغير ما عبارة عن كائن Object من صنف آخر:
class User {} const user1 = new User(); typeof User; // 'function' typeof user1; // 'object' إستخدام instanceof
توفر هذه الطريقة إمكانية التأكد من أن كائن Object معين عبارة عن نسخة instance من صنف ما:
user1 instanceof User; // true user1 instanceof Array; // false التابع isPrototypeOf
بما أن لغة JavaScript تعتمد بشكل أساسي على prototype، فيمكننا إستخدام التابع isPrototypeOf للتأكد من أن كائن ما عبارة عن نسخة من صنف معين:
User.prototype.isPrototypeOf(user1); // true إستخدام constructor.name
هذه طريقة مختلفة لأداء نفس مهمة instanceof السابقة:
user1.constructor.name === "User"; // true ملاحظة: لا يًفصل إستعمال هذه الطريقة إذا كنت تستعمل أدوات مثل Uglify أو minify التي تغير أسماء الأصناف لتصبح أقصر، لكن يمكن في هذه الحالة إستخدام المقارنة المباشرة باسم الصنف class بدون مشكلة على النحو التالي:
user1.constructor.name; // == "User" User.name; // User user1.constructor.name === User.name; // true
-
إجابة سامح أشرف سؤال في كيفية إستدعاء التابع الباني constructor من الصنف الجد بدون المرور على الصنف الأب في PHP؟ كانت الإجابة المقبولة
يمكنك كذلك إستخدام الدالة get_parent_class، حيث تمكنك الدالة get_parent_class من معرفة الصنف الأب لأي صنف آخر (بما في ذلك الصنف الحالي عبر this$)، ومع إستخدام الصنف ReflectionMethod يمكنك تنفيذ التابع الباني constructor على النحو التالي:
<?php class GrandFather { public function __construct() { echo "GrandFather's constructor \n"; } } class Father extends GrandFather { public function __construct() { // call GrandFather's constructor parent::__construct(); } } class Son extends Father { public function __construct() { $grandpa = get_parent_class(get_parent_class($this)); $reflectionMethod = new ReflectionMethod($grandpa, '__construct'); // calling grandFather constructor $reflectionMethod->invoke($this); echo "calling the constructor from " . $grandpa . " Class"; } } $son = new Son(); /* Output: GrandFather's constructor calling the constructor from GrandFather Class */ توثيق الدالة get_parent_class في موسوعة حسوب.
-
إجابة سامح أشرف سؤال في كيفية عمل نموذج Model للتعامل مع بيانات الموجودة في قاعدة البيانات في PHP؟ كانت الإجابة المقبولة
يمكن عمل لنموذج Model بسيط يعبر عن جدول معين في أي لغة برمجة، ولكن في البداية يجب أن تقوم بعمل صنف Class للإتصال بقاعدة البيانات والتعامل معها بالشكل التالي:
class Database { protected $conn; public function __construct($connection) { $this->conn = $connection; } public function ExecuteQuery($sql, $data) { // ... } } الصنف السابق يأخذ مدخل واحد وهو إتصال بقاعدة البيانات ويمكننا إستخدامه بالشكل التالي:
$conn = new PDO("mysql:host=localhost;dbname=myDB", "username", "password"); $db = new Database($conn); الآن يمكن إستعمال التابع ExecuteQuery لتنفيذ جمل SQL مباشرة في قاعدة التي إتصلنا بها.
نحتاج الآن إلى عمل صنف مجرد abstract class يُعبر عن النموذج الواحد Model، بحيث يمكننا عمل أي عدد من النماذج Models كما نريد:
abstract class Model { protected $db; public function __construct(Database $db) { $this->db = $db; } // ... } يمكننا الآن عمل نموذج Model يعبر عن المستخدم أو منشور ما .. إلخ:
class User extends Model { protected $table = "users"; public function save() { // ... $sql = "INSERT INTO " . $this->table . " VALUE ..."; return $this->db->ExecuteQuery($sql, $data); } } وتستطيع إستخدام هذا النموذج على النحو التالي:
$db = new Database($conn); $user = new User($db); $user->name('username'); $user->email('user@gmail.com'); $user->save(); الكود السابق ما هو إلا تجريد لجدول users في قاعدة البيانات، ولكن النموذج من المفترض أن المستخدم الواحد وليس جدول المستخدمين، لذلك يجب أن تقوم بإضافة بعض التوابع حسب حاجتك لإتمام عمليات أخرى مثل جلب بيانات مستخدم معين من قاعدة البيانات عبر id أو تعديل هذه البيانات لاحقًا .. إلخ.
ملاحظة: كل الكود السابق يمكن تطبيقه بعدة طرق مختلفة، ولكن ستحصل على نفس النتيجة في النهاية وهي وجود نموذج يعبر عن كائن معين (مستخدم، تعليق، منشور .. إلخ)، لذلك عليك أن تقوم بتعديل الكود السابق حسب رغبتك وإحتياجاتك.
-
إجابة سامح أشرف سؤال في ما هي مبادئ SOLID في البرمجة الكائنية OOP في PHP؟ كانت الإجابة المقبولة
مبادئ SOLID أو SOLID principles هي مجموعة من القواعد النظرية التي تهدف لجعل الكود أسهل في الكتابة والصيانة، وتساعدك على العمل في مشاريع كبيرة بدون بذل جهد كبير في عملية إصلاح الأخطاء، وهذه المبادئ مفيدة بصورة خاصّة في التصميم كائنيّ التوجّه object-oriented design، حيث تقدم هذه القواعد الأساسيات التي يجب إتباعها عند إنشاء الأصناف وربطها معًا. هذه المبادئ ليست ضرورية لتصميم البرمجيات ولكنها تساعد مطوّري البرمجيّات على تحقيق تصاميم برمجيّة عالية الجودة. كل حرف من أحرف كلمة SOLID عبارة عن أختصار لأحد المبادئ:
مبدأ المسؤولية الواحدة Single Responsibility Principle (SRP) مبدأ الفتح والإغلاق Open/Closed Principle (OCP) مبدأ ليسكوف للاستبدال Liskov Substitution Principle (LSP) مبدأ فصل الواجهات Interface Segregation Principle (ISP) مبدأ عكس التابعيّة Dependency Inversion Principle (DIP) هنا شرح بسيط لكل مبدأ من مبادئ SOLID:
مبدأ المسؤولية الواحدة Single Responsibility Principle (SRP)
ينص هذا المبدأ على التالي:
على سبيل المثال إن كان لديك الصنف User للتعامل مع بيانات المستخدم في قاعدة البيانات، وبفرض أن هذا الصنف مسؤول عن عرض البيانات في الصفحة الشخصية للمستخدم، فسيكون لدينا سببين للتعديل على هذا الصنف في المستقبل:
عندما نُريد عمل تغير ما في بيانات المستخدم في قاعدة البيانات. عندما نريد تغير شكل البيانات التي يتم عرضها في الصفحة الشخصية للمستخدم وبالتالي يوجد أكثر من سبب يدفعنا للذهاب إلى هذا الصنف والتعديل عليه، أي أن هذا الصنف لا يُحقق مبدأ المسؤولية الواحدة Single Responsibility Principle، ويجب فصله إلى صنفين كلُ منهما مسؤول عن أمر واحد ومحدد.
يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة:
مبدأ الفتح والإغلاق Open/Closed Principle (OCP)
المبدأ الثاني ضمن مبادئ SOLID هو مبدأ الفتح والإغلاق Open/Closed Principle، وينص هذا المبدأ على التالي:
الهدف من هذا المبدأ هو التفكير في المستقبل (البناء الآن، التخطيط للمستقبل) بحيث نصمم البرمجيات وجعلها لا تحتاج إلى تغيير الكود المكتوب مسبقًا عند إضافة ميزات ووظائف جديدة إليها.
على سبيل المثال إن كان لديك صنف Shape يصف أي شكل مُضلع ثنائي البعد، وقمت بإضافة الخواص width و height و area و perimeter فيه، فهذا الصنف لا يُحقق مبدأ الفتح والإغلاق Open/Closed Principle، لأننا سنحتاج إلى تعديل هذا الصنف في حالة أردنا عمل مثلث أو شكل خماشي، حيث أن هذه الأشكال لديها مُحيط perimeter ومساحة area ولكن ليس لديها طول وعرض.
يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة:
مبدأ ليسكوف للاستبدال Liskov Substitution Principle (LSP)
سُمي هذا المبدأ باسم صاحبه البروفسور باربارا ليسكوف، الذي طرحته لأوّل الأمر عام 1987. يهدف هذا المبدأ إلى تحديد شكل عملية الوراثة inheritance بين الأصناف، ويمكننا صياغة هذا المبدأ بالشكل التالي:
لفهم معنى هذا المبدأ، تخيل أن لدينا صنف Rectangle والذي يصف أي مستطيل، ويوجد في هذا الصنف تابع يقوم بتعيّن الطول setHeight وتابع يقوم بتعين العرض setWidth، حتى الآن لا يوجد مشكلة، ولكن عندما نريد عمل صنف Square ويرث من الصنف Rectangle (حيث أن المربع حالة خاصة من المستطيل (مستطيل طوله مساوي لعرضه))، فسنواجه مشكلة في هذا الأمر، لأن المربع لا يمكن أن يحتوي على طول مختلف عن العرض، ولهذا يجب عمل صنف مختلف تمامًا للمربع Square بدون أن يرث من Rectangle
يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة:
مبدأ فصل الواجهات Interface Segregation Principle (ISP)
هدف هذا المبدأ هو التفكير في المستقيل كذلك، ولكن بطريقة مختلفة عن مبدأ المسؤولية الوحيدة السابق ذكره، حيث ينص هذا المبدأ على التالي:
لفهم نص هذا المبدأ، يجب أن تفهم الواجهات Interfaces في لغة PHP (أو في البرمجة بشكل عام)، هنا مقالة توفر شرح لهذا الأمر بالإضافة لبعض المفاهيم الأساسية الأخرى:
الآن تخيل أن لدينا واجهة تصف الشخص الواحد بالشكل التالي:
interface iHuman { public function work(); // الإنسان يمكنه العمل public function sleep($hours); // يمكن أن ينام لعدة ساعات public function eat(); // يمكنه أن يأكل } بعد ذلك نريد أن نقوم بعمل صنف لموظف employee وبالتأكيد سوف نستخدم الواجهة السابقة بالشكل التالي:
class Employee implements iHuman { public function work() {} public function sleep($hours) {} public function eat() {} } حتى الآن لا يوجد مشكلة، لكن ماذا إذا أردنا عمل صنف يُعبر عن طفل رضيع صغير Baby (ليس لديه عمل Work)، لذلك سوف يتم إجبارنا على إضافة التابع work إلى الصنف Baby حتى وإن لم يكن له فائدة تُذكر، لذلك ظهر مبدأ فصل الواجهات والذي ينص على فصل الواجهات عن بعضها البعض، بالشكل التالي:
interface iWorkable { public function work(); // الإنسان يمكنه العمل } interface iHuman { public function sleep($hours); // يمكن أن ينام لعدة ساعات public function eat(); // يمكنه أن يأكل } class Employee implements iHuman, iWorkable { public function work() {} public function sleep($hours) {} public function eat() {} } class Baby implements iHuman { public function sleep($hours) {} public function eat() {} } يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة:
مبدأ عكس التابعيّة Dependency Inversion Principle (DIP)
هذا المبدأ هو آخر مبادئ التصميم الكائنيّ SOLID، قد يكون صعبًا قليلًا لكنه مفيد للغاية، خصوصًا في البرمجيات الكبيرة والتي تحتوي على أصناف كثيرة ومتعددة، وينص على التالي:
تخيل أن لديك صنف Button وصنف Window وتقوم بإستخدام كائنات من الصنف Button في العديد من الأمكان داخل الصنف Window، تكمن المشكلة الآن في أن الصنف Window أصبح يعتمد بشكل أساسي عل ىالصنف Button، وإذا أردت إجراء بعض التعديلات على الصنف Button (تغير بعض التوابع أو حذفها أو نغير المعاملات التي تأخذها)، فيجب أن تقوم بالتعديل على الصنف Window في الأماكن التي تستعمل كائنات من نوع Button ليجاري هذه التغيرات ويعمل بشكل سليم.
حل المشكلة هنا هو عمل واجهة interface تسمى iButton على سبيل المثال، يعتمد عليها كلُ من الصنفين Button و Window، وبالتالي لن يعتمد أحد الأصناف على صنف آخر.
يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة:
-
إجابة سامح أشرف سؤال في ما الفرق بين إستخدام self و this$ في البرمجة الكائنية OOP في PHP؟ كانت الإجابة المقبولة
الأصناف Classes في PHP يمكن أن تحتوي على خصائص أو توابع ساكنة static أو عادية (موروثة inherited)، ولكي يمكننا الوصول إلى الخصائص العادية من داخل التوابع نستعمل this$ بينما تُستعمل self للوصول إلى الخصائص الساكنة
أي أنك يجب أن تستخدم this$ للإشارة إلى الكائن الحالي Current Object. واستخدم self للإشارة إلى الصنف الحالي Current Class. بمعنى آخر ، استخدم this->member$ للتوابع غير الساكنة non-static ، واستخدم self::$member للتوابع الساكنة static.
مثال:
<?php class MyClass { // Current Class public $normal_value = "non-static value"; static $static_value = "static value"; function __construct() { echo $this->normal_value // للوصول إلى تابع أو خاصية عادية . ' + ' . self::$static_value; // للوصول إلى تابع أو خاصية ساكنة Static } } $c = new MyClass(); // Current Object // Output: non-static value + static value وإذا حاولت إستخدام self مكان this$ سيظهر لك الخطأ التالي:
Fatal error: Uncaught Error: Access to undeclared static property سوف يتضح الأمر أكثر عن محاولة وراثة صنف إلى صنف آخر:
<?php class X { function foo() { echo 'X::foo()'; } function bar() { self::foo(); // تُشير إلى الصنف الحالي، حتى بعد الوراثة } } class Y extends X { function foo() { echo 'Y::foo()'; } } $x = new Y(); $x->bar(); // X::foo() السبب في هذه النتيجة هو أن self تُشير إلى الصنف بحد ذاته وليس الكائنات التي يتم إنشائها منه (أو حتى الأصناف التي ترث منه)، وبالتالي ستظل self في المثال السابق تُشير إلى الصنف X
على الجانب الآخر عند إستعمال this$ سيتم الإشارة إلى الكائن Object نفسه وليس الصنف Class:
<?php class X { function foo() { echo 'X::foo()'; } function bar() { $this->foo(); // تُشير إلى الكائن الذي سيتم إنشائه } } class Y extends X { function foo() { echo 'Y::foo()'; } } $x = new Y(); $x->bar(); // Y::foo() ملاحظة: يمكن إستخدام self للوصول إلى التوابع بدون مشكلة (مثل this$) تمامًا:
<?php class Person { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } public function sayGoodbye() { echo "Goodbye, " . self::getName() . "<br/>"; } } $p = new Person("Sameh"); $p->sayGoodbye(); // // Goodbye, Sameh
-
إجابة سامح أشرف سؤال في ما الفرق بين الدالة function والتابع method في البرمجة الكائنية OOP؟ كانت الإجابة المقبولة
تعريف كلًا من الدالة Function والتابع Method
هذه مجرد مصطلحات لوصف جزء معين من الكود، وهنا تعريف بسيط لكلٍ منهما:
الدالة Function: تسمى أيضًا "وظيفة"، هي كتلة من الكود (مجموعة من الأسطر البرمجية) لها اسم معين، ويمكن تمرير بعض المدخلات لها لتغير سلوك الدالة أو نتيجتها (تسمى هذه المدخلات بـ Parameters)، وأيضًا يمكن للدالة إرجاع قيمة return بشكل إختياري، ويمكن إنشائها ضمن أي مجال namespace. التابع Method: تسمى أيضًا "طريقة"، وهي كذلك كتلة من الأكواد لها اسم معين، ولكن يكون التابع موجودًا ضمن كائن Object معين، ولها نفس خواص الدالة من حيث المدخلات التي يمكن تمريرها إليها وإرجاع قيمة كذلك. في بعض اللغات مثل ++C يطلق على التوابع "دوال أعضاء Member Functions"، ويمكن فقط إنشائها ضمن أصناف Classes. بناءً على التعريف السابق، يمكننا القول أن كل التوابع Methods عبارة عن دوال functions، ولكن ليس كل الدوال functions عبارة عن توابع Methods.
الإختلافات بين الدالة Function والتابع Method
تكمن الإختلافات بين الدالة Function والتابع Method في أن التابع له بعض المميزات الإضافية، مثل:
عند إستدعاء تابع Method يتم الإشارة صراحة إلى الكائن الذي يحتويه. يمكن للتابع أيضًا الوصول لخواص الكائن Object والتوابع الأخرى الموجودة فيه (أو أي خواص وتوابع موروثة من صنف أب). مثال بلغة JavaScript عن الفرق بين التابع Method والدالة Function:
class User { // getFullName عبارة عن تابع لأنه ضمن صنف Class getFullName() { // ... } } // sum هنا عبارة عن دالة لأنها ضمن المجال العام وليست ضمن صنف معين function sum(x, y) { return x + y; } مثال بلغة PHP:
<?php class User { // getFullName عبارة عن تابع لأنه ضمن صنف Class public function getFullName() { // ... } } // sum هنا عبارة عن دالة لأنها ضمن المجال العام وليست ضمن صنف معين function sum($x, $y) { return $x + $y; } ملاحظة: بعض اللغات مثل Java و#C لا تحتويان على دوال Functions لأن اللغة بأكملها تستعمل البرمجة الكائنية OOP، وبالتالي يمكن عمل توابع Methods فقط، على الجانب الآخر لغات مثل C لا تحتوي على أصناف Class وبالتالي لا يمكن عمل توابع Methods فيها وتحتوي فقط على دوال Functions.
-
إجابة سامح أشرف سؤال في كيف أقوم بحذف خاصية من كائن Object في JavaScript؟ كانت الإجابة المقبولة
يمكن إزالة أي خاصية أو تابع من كائن Object بعدة طريق:
إستخدام الكلمة المفتاحية delete
// لا يوجد أي فرق بين الطرق التالية delete user.age; // أو delete user['age']; // أو var prop = "age"; delete user[prop]; إستخدام القيمة undefined
عند محاولة الوصول إلى خاصية غير موجودة في أي كائن سوف يتم إرجاع undefined ، ويمكننا أن نستخدم هذا الأمر لمحاكاة حذف الخاصية أو التابع من الكائن خاصتنا:
user.age = undefined; console.log(user); console.log(user.hasOwnProperty('age')); // true /* { age: undefined, email: 'emad@gmail.com', firstName: 'Emad', lastName: 'Saif', getFullName: ƒ } */ هذه الطريقة سوف تبقى الخاصية أو التابع موجودًا في الكائن لكن بقيمة undefined، بينما إستعمال الكلمة المفتاحية delete سوف يزل الخاصية أو التابع بشكل كامل:
delete user.age; console.log(user); console.log(user.hasOwnProperty('age')); // false /* { email: 'emad@gmail.com', firstName: 'Emad', lastName: 'Saif', getFullName: ƒ } */ عمل كائن Object جديد
يمكن عمل كائن Object جديد يحتوي على كل الخصائص والتوابع ما عدا التلك التي نريد حذفها:
const {age, ...newUser} = user; console.log(newUser.age); // undefined console.log(user.age); // 19 ميزة هذه الطريقة أنها تُبقى على العنصر الأصلي كما هو بدون تغير وتقوم بإنشاء كائن جديد كليًا بالخصائص والتوابع التي نريدها فقط، لكن من عيوبها أنها تقوم بعمل متغيرات جديدة في المجال الحالي، ففي المثال السابق تم إنشاء متغير جديد باسم age بقيمة 19
-
إجابة سامح أشرف سؤال في ما الفرق بين public و private و protected في البرمجة الكائنية OOP في PHP؟ كانت الإجابة المقبولة
تستخدم محددات الوصول للتحكم في مسار الكود ولسهولة تتبعه وفهم آليه عمله وبالتالي تكون صيانته وحمايته من الأخطاء أسهل، هنا شرح لمعنى كلٍ منهم:
الكلمة المفتاحية public
public تعني عام ويمكن الوصول لأي تابع عام public method من داخل جميع التوابع الأخرى الموجودة داخل نفس الصنف وفي حالة الوراثة أو من خلال الكائن المنشأ من هذا الصنف.
<?php class User { public function SayHi() { // ... } public function Hello() { $this->SayHi(); // في حالة الوصول إلى التابع من داخل تابع آخر في نفس الصنف } } $user = new User(); // حالة إنشاء كائن من الصنف $user->SayHi(); class Admin extends User { public function Hello() { $this->sayHi(); // في حالة الوراثة } } الكلمة public هي إختيارية ويمكن عدم كتابتها كذلك بدون مشكلة، وأي تابع لم يتم تحديده (public أو private أو protected) فسوف يكون عام public بشكل إفتراضي، لكنها إجبارية في حالة الخواص properties
الكلمة المفتاحية private
private تعني خاص، فأي تابع يُعرف على أنه خاص لا يمكن إستخدامه إلا داخل الصنف class المعرف بها فقط فلا يمكن الوصول له من خلال كائن منشأ من هذا الصنف وأيضاً لا يمكن الوصول للمكونات الخاصة في حالة الوراثة.
<?php class User { private function SayHi() { // ... } public function Hello() { $this->SayHi(); // في حالة الوصول إلى التابع من داخل تابع آخر في نفس الصنف } } $user = new User(); $user->SayHi(); //ERROR: حالة إنشاء كائن من الصنف class Admin extends User { public function Hello() { $this->sayHi(); //ERROR: في حالة الوراثة } } الكلمة المفتاحية protected
protected تعني محمي، وهي أعم من الحالة السابقة فأي تابع يُعرف على أنه محمي protected يمكن إستخدامه داخل نفس الصنف وفي حالة الوراثة فقط ولكن لا يمكن الوصول لتوابع الصنف المحمية من خلال الكائن المنشأ من هذا الصنف:
<?php class User { protected function SayHi() { // ... } public function Hello() { $this->SayHi(); // في حالة الوصول إلى التابع من داخل تابع آخر في نفس الصنف } } $user = new User(); $user->SayHi(); //ERROR: حالة إنشاء كائن من الصنف class Admin extends User { public function Hello() { $this->sayHi(); // في حالة الوراثة لا يوجد مشكلة } } يمكنك معرفة المزيد من خلال موسوعة حسوب: قابلية الرؤية في كائنات PHP
-
إجابة سامح أشرف سؤال في ما هي فائدة react ؟ كانت الإجابة المقبولة
مكتبة React تستعمل لتسهيل العمل على المشاريع الكبيرة من خلال تقسيم المشروع بالكامل إلى مكونات Components وبالتالي يمكن التعامل مع كل مكون على حدى، ويمكن أن يعمل أكثر من مبرمج على نفس المشروع في وقت واحد بشكل أسهل من التعامل مع المشروع في شكل صفحات، فتخيل أنك تقوم بإستعمال زر معين Button في أكثر من مكان وفي أكثر من صفحة، وبعد تطوير المشروع أردت أن تقوم بتغير هذا الزر أو ما يفعله، حيناها سيكون عليك أن تبحث عن كل مكان أستعملت فيه هذا الزر وتقوم بالتعديل عليه، أو على الأقل سوف تتنقل بين ملفات CSS و JavaScript، أما في حالة إستعمال React.js (أو أي مكتبة أو إطار عمل يستعمل نظام المكونات) فستقوم بالتوجه مباشرة إلى ملف معين والتعديل عليه وأنتهى الأمر، وبالتالي تصبح عملية التطوير أسهل وأسرع من ذي قبل.
كما يوفر React الكثير من الأشياء التي تسهل عليك عملية التطوير مثل الخطافات Hooks والتي من خلال يمكنك عمل الكثير من الأمور بأسطر بسيطة بدلًا من كتابتها من الصفر، بالإضافة إلى أن React.js يُمكن المبرمد من إنشاء التطبيقات بدون التعامل مع DOM بشكل مباشر، حيث يقوم المبرمج بوصف شكل المكون وما يقوم به (عبر أكواد JavaScript و CSS) ويقوم React بالتعامل مع DOM مما يعطي أفضل أداء ممكن بدون الدخول في تعقيدات لا حاجة لها.
هنا مدخل بسيط للتعرف على React.js:
وتستطيع الإطلاع على المقالات موجودة في أكاديمية حسوب من هنا، أو قراءة توثيق React باللغة العربية في موسوعة حسوب من هنا.