تطوير ووردبريس المستوى المتقدم: مقدمة إلى البرمجة غرضية التوجه


Mohammad Hammal

هل تريد تطوير مهاراتك في تطوير ووردبريس إلى مرحلة متقدمة؟ هل أنت مستعد لرفع مستواك في لغة PHP لأعلى مستوى وإضافة المزيد من القوة إلى إضافات وقوالب ووردبريس التي تقوم بتطويرها.

قبل أن نبدأ

يُفترض قبل البدء أنك تعرف برمجة ووردبريس وتعلم كيف تعمل قوالب وإضافات ووردبريس بشكل بسيط إذا لم تكن تعلم فيمكنك البحث في الموقع وستجد مقالات للمبتدئين.

ماذا سنغطي في هذه المقالة

في هذه المقالة، سوف نبدئ مباشرة في البرمجة غرضية التوجه (object-oriented programming) وكيف يتم استخدامها في تطوير ووردبريس. البرمجة غرضية التوجه لا تحتاجها بشدة كمطور ووردبريس لكن بعد استخدامي لها لاحظت أن جودة تعليماتي البرمجية قد تحسنت بشكل سريع وقوي عندما بدأت في وضع مفاهيم البرمجة غرضية التوجه في عين الاعتبار، واستطعت أن أتعلم لغات برمجة آخرى لأن مفهوم الأصناف(classes) والكائنات(objects) متشابهة في كل لغات البرمجة. لنلقي نظرة على مبادئ البرمجة غرضية التوجه لنرى ما هي ولنستعملها في برمجة قوالب وإضافات قوية.

ما هي البرمجة غرضية التوجه؟

البرمجة غرضية التوجه هي منطق تفكيري أكثر من أن تكون طريقة لكتابة التعليمات البرمجية، لأنها تعني التفكير في البرمجة بشكل منظم أكثر، وتغليف التعليمات البرمجية وجعلها كوحدات منفصلة من أجل استخدامها بشكل أفضل لاحقًا. لا تقلق إذا لم تستوعب ما شرحناه، لأننا سنلقي نظرة على كثير من الأمثلة خلال هذه المقالة لتساعدك في ترسيخ هذه المفاهيم.

لماذا نستخدم البرمجة غرضية التوجه؟

البرمجة غرضية التوجه تُغلف المجموعات المتماثلة منطقيًا من التعليمات البرمجية موفرةً بذلك تعليمات برمجية أكثر قابلية للقراءة وأكثر تنظيمًا وهي توفر الفوائد التالية:
• تعليمات برمجية أسهل تتبعًا.
• تطوير هذه التعليمات البرمجية يصبح فيما بعد أسهل بكثير.
• أسماء الدوال لا داعلي لأن تكون طويلة بعد الآن، والدوال داخل الأصناف لا تتضارب مع الدوال خارج هذه الأصناف.
• درجة أعلى من قابلية إعادة استخدام التعليمات البرمجية.

تعلم عن طريق مثال

لنبدأ مع مثال على تعليمات برمجية عادية وتحويلها إلى تعليمات برمجية غرضية التوجه، لنفترض أننا نبني موقع تويتر Twitter، ونريد أن نقوم بحذف الأحرف من نص معين، وتحويل النصوص إلى روابط، لذا سأقوم بكتابة بعض الدوال لاستعمالها في المشروع:

// Cut text down to required length
function get_chirp_text( $text ) {
  return substr( $text, 0, 200 );
}

// Parse hashtags from text
function get_hashtags( $text ) {
    preg_match_all("/S*#((?:\[[^\]]+\]|\S+))/", $text, $matches);
    return $matches;
}

// Create the final chirp text
function create_chirp( $text ) {
    $chirp_text = get_chirp_text( $text );
    $hastags = get_hashtags( $chirp_text );
    if( !empty( $hastags[1] ) ) {
        foreach( $hastags[1] as $key => $match ) {
            $hastags[1][$key] = "<a href='http://chirp.chip/hastags/" . $match . "/'>" . '#' . $match . "</a>";
        }

        $chirp_text = str_replace( $hastags[0], $hastags[1], $chirp_text );
    }

    return $chirp_text;
}

$text = 'This is a chirp with an #example hashtag created with code that is #procedural';
echo create_chirp( $text );

دالة ()get_chirp_text تقوم باستلام نص كوسيط و تقتطعه، أما دالة ()get_hashtags تقوم باستلام نص و إرجاع الجزء من النص الذي يبدأ ب “#”. دالة ()create_chirp تستعمل القيم المعادة من الدالتين السابقتين لتحويلها إلى روابط.

img-1.png

صحيح أن هذه التعليمات البرمجية تعمل بشكل صحيح، لكن ماذا لو أردنا تغيير عدد الأحرف التي نريد اقتطاعها إلى 200 أو 300 حرف، أو نريد تغيير الروابط. هذه المشاكل لن يتم ملاحظتها ولكن من الممكن أن تعقد التعليمات البرمجية إذا كانت هذه التعليمات كثيرة. لنقم بتغليف هذه التعليمات البرمجية وتحويلها إلى تعليمات برمجية غرضية التوجه سأبدأ مع التعليمات البرمجية كاملة وسأقوم بشرحها بالتتالي:

class Chirp {
    var $text;
    var $length;
    var $hashtag_base;
    var $hashtags;
    var $chirp;

    function __construct( $text ) {
        $this->hashtag_base = 'http://chirp.chip/hastags/';
        $this->text = $text;
        $this->set_length();
        $this->set_hashtags();
        $this->set_chirp();
    }

    function set_length() {
        $this->length = 200;
    }

    function set_hashtags() {
        preg_match_all("/S*#((?:\[[^\]]+\]|\S+))/", $this->text, $matches);
        $hashtags = array();
        foreach( $matches[1] as $key => $match ) {
            $hashtags['#' . $match] = "<a href='http://chirp.chip/hastags/" . $match . "/'>" . '#' . $match . "</a>";
        }
        $this->hashtags = $hashtags;
    }

    function set_chirp() {
        $chirp = substr( $this->text, 0, $this->length );
        $chirp = str_replace( array_keys( $this->hashtags )  , array_values( $this->hashtags ), $chirp);
        $this->chirp = $chirp;
    }

}

$chirp = new Chirp( 'This is a chirp with an #example hashtag created with code that is #procedural' );

echo $chirp->chirp;

من البداية قمت بتعريف صنف اسمه chirp. يحوي بداخله عددًا من المتغيرات والدوال. المتغيرات تمثل خصائص مهمة للكائنات التي سيتم بناءها من هذا الصنف.

  • متغير text$ يحمل النص الأصلي الذي نريد معالجته
  • متغير length$ يحمل عدد الأحرف المسموحة بها في التغريدة
  • متغير hashtag_base$ يحمل القيمة الأساسية لروابط الهاشتاغ
  • متغير hashtags$ يحمل خريطة الهاشتاغ
  • متغير chirp$ يحمل ال html النهائية للتغريدة

لنتخطى دالة __construct() للوقت الحالي و نركز على دالة ()set_length . كل ما تفعله هذه الدالة هي تعيين قيمة 200 ل this->$length. من المؤكد أنك تتساءل عن المتغير ?this$ يستخدم للإشارة إلى المتغيرات والدوال داخل الصنف، كما قمنا بتعيين قيمة length$ عن طريق this->$length سنكون قادرين على مناداة هذا المتغير في أي مكان في الصنف باستخدام this->$length والنتيجة أننا لا نحتاج لتمرير هذا المتغير كوسيط عند استعماله في كل دالة. الدالة التالية هي ()set_hashtage، تقوم بهذه الدالة بجلب النص للقيام بمعالجته من this->$text و الذي سوف يوضع في دالة __construct() و التي سنقوم بشرحها لاحقًا، لقد قمت بتغيير المصفوفة التي تنتجها هذه الدالة لتحتوي على الهاشتاغ كمفتاح و الرابط الكامل كقيمة هذا المفتاح و هذه سيجعل استبدال النص أسهل. و أخيرًا الدالة ()set_chirp تستخدم this->$text و this->$length لقطع النص و this->$hashtags لتبديل النصوص مع الروابط. أخيرًا تقوم بتعيين نتيجة html إلى this->$chirp. و في النهاية قمت باستخدام هذا الصنف لإنشاء الكائنات مخزن في chirp$ قمت بتمرير وسيط واحد لهذا الصنف عندما تم إنشاء الكائن من الدالة __construct() عندما تم تفعيل هذا الصنف.
هذه الدالة يتم تفعيلها فورًا عند إنشاء الكائن يمكنك رؤية كيف يتم تمرير الوسائط وتقوم ايضًا بالتالي:

  • تضع قيمة المتغير $this->hashtag_base مباشرةً
  • تضع قيمة للمتغير this->$text مباشرةً
  • تستخدم الدالة ()set_length لضبط الطول، لاحظ بما أن الدالة داخل الصنف فيتم الإشارة إليها ب this$
  • تقوم بإنشاء تعليمات html النهائية باستخدام الدالة ()set_chirp.

بعد إنشاء الكائن يمكننا إظهار أي قيمة من الكائن ونعلم أن تعليمات html النهائية مخزنة في الخاصية chirp$، ويمكننا الدخول إليها باستخدام الصيغة chirp->$chirp.

عناصر الأصناف والكائنات

في هذا القسم، سوف نشرح عناصر الأصناف والكائنات. الاختلاف بين الأصناف والكائنات، بأن الأصناف هي المخططات التي تصنع منها الكائنات. الأصناف تعرف باستخدام الكلمة class متبوعة باسم الصنف الذي نريده و كل التعليمات البرمجية الخاصة به موضوعة بين { }.

<p>These are just 8 of our awesome posts. Click here for <?php echo $posts->found_posts - 8 ?> more!</p>

الأصناف يمكن أن تحوي شيئين هما المتغيرات والدوال، لكن داخل الأصناف يشار لهم بالخصائص(properties) والطرق(methods) وهذا هو الصنف فقط عبارة عن مجموعة من الخصائص والطرق. لاستخدام الخصائص والطرق داخل الصنف نحتاج إلى الإشارة لها ب this$. الأصناف يمكن أن تحوي عددًا من الدوال الخاصة. واحدة من هذه الدوال __construct() والتي يبدأ تنفيذها مباشرةً عندما ننشأ كائن من صنف. أي عدد من الكائنات يمكن إنشاءه من صنف واحد.

$chirp_one = new Chirp( 'This is a chirp with an #example hashtag created with code that is #procedural' );
echo $chirp_one->chirp;

$chirp_two = new Chirp( 'This is a chirp with an #example hashtag created with code that is #procedural' );
echo $chirp_two->chirp;

استخدام الكائنات بشكل صحيح

ليس هناك طريقة واحدة صحيحة لاستعمال الكائنات، لأن ذلك يعتمد بشكل كبير على ماهية ما تبنيه. لنراجع بعض النقاط المهمة في المثال السابق

تحديد الطول

لدينا دالة منفصلة لتعيين الطول، لكن كل ما تفعله هو تعيين الطول ل 200 و كان يمكننا أن نضع القيمة يدويًا في دالة ()substr الموجودة في ()set_chirp. السبب هو التفكير للأمام، لأنه لا يجب أن نكون هذه مهمة ()set_chirp لمعرفة الطول. لأنه من الممكن أن نقرر أن يكون عدد الحروف 160، وتوفير أطوال مختلفة بناء على حالة المستخدم على سبيل المثال. إذا أسندنا مهمة تعيين الطول لدالة منفصلة يمكننا تغيير المنطق الخاص بالطول من دون التأثير على أجزاء آخرى في التعليمات البرمجية.

دوال الضبط Setter Methods

الطرق أو الدوال التي تقوم بتعيين قيمة لخاصية يتم الإشارة إليها بدوال الضبط أو التعيين. يمكنك ملاحظة أنني قمت بتعيين بعض الخصائص من الدالة البانية __construct() و بعضها من الدوال الآخرة. طريقة تفكيري هنا كانت أن الخصائص التي لا أحتاج إلى إجراء العمليات عليها يمكنني تعيين قيمها في الدالة البانية أما التي أريد معالجة قيمها أسندتها لدوال خاصة.

العمل مع الكائنات

القدرة على الإشارة إلى الخصائص والطرق داخل الأصناف توفر لنا كثيرًا من الاستراتيجيات في التعامل مع الأصناف. إذا أزلنا معظم التعليمات من الدالة البانية في مثالنا السابق يمكننا القيام بالعمليات المطلوبة من خارج الأصناف. لنلقي نظرة:

class Chirp {
    var $text;
    var $length;
    var $hashtags;
    var $chirp;

    function __construct( $text ) {
        $this->hashtag_base = 'http://chirp.chip/hastags/';
        $this->text = $text;
        $this->set_length();
    }

    function set_length() {
        $this->length = 200;
    }

    function set_hashtags() {
        preg_match_all("/S*#((?:\[[^\]]+\]|\S+))/", $this->text, $matches);
        $hashtags = array();
        foreach( $matches[1] as $key => $match ) {
            $hashtags['#' . $match] = "<a href='http://chirp.chip/hastags/" . $match . "/'>" . '#' . $match . "</a>";
        }
        $this->hashtags = $hashtags;
    }

    function get_chirp() {
        $chirp = substr( $this->text, 0, $this->length );
        if( !empty( $this->hashtags ) ) {
            $chirp = str_replace( array_keys( $this->hashtags )  , array_values(    $this->hashtags ), $chirp);
        }
        return $chirp;
    }

}

الفرق هنا أن الدالة البانية لا تقوم بتشغيل دالة ()set_hashtags و بالتالي يمكننا بناء التغريدة بطريقتين:

$chirp = new Chirp( 'This is a chirp with an #example hashtag created with code that is #procedural' );
// Hashtags will not be links here
echo $chirp->get_chirp();

$chirp->set_hashtags();

// Hashtags are now links because they have been set
echo $chirp->get_chirp();

مثال ووردبريس

يمكننا أخذ مثال رائع من ووردبريس يستخدم البرمجة غرضية التوجه وهو WP_Query. إذا كنت قد استخدمته من قبل من دون علم بالبرمجة غرضية التوجه فسيصبح أوضح بالنسبة لك الآن. لنفترض أنك تقوم بإنشاء صفحة خاصة في ووردبريس ستحتوي على أحدث 8 مقالات و3 من تقييمات الكتب القادمة. يمكنك صناعة كائنين باستخدام هذا الصنف:

$posts = new WP_Query(array(
  'post_type' => 'post',
  'posts_per_page' => 8,
  'post_status' => 'publish'
));

$books = new WP_Query(array(
  'post_type' => 'book',
  'posts_per_page' => 3,
  'post_status' => 'future'
))

إذا اطلعت على التوثيق الخاص بهذا الصنف يمكنك روية أنه يملك العديد من الخصائص ومن بينها $found_posts. ولقد أصبحنا نعرف كيف نشير إلى هذه الخصائص:

<p>These are just 8 of our awesome posts. Click here for <?php echo $posts->found_posts - 8 ?> more!</p>

أصعب جزء في الأصناف والكائنات هو ليس استخدامها بل كيف تستخدمها بشكل صحيح، وأنا أشجعك أن تبدأ باستخدام البرمجة غرضية التوجه في مشاريعك، ربما في البداية سترى أنها غير مفيدة. لكن عندما بدأت في تطبيقها في مشاريعي وجدت الفائدة الكبيرة للبرمجة غرضية التوجه ومعظم إطارات العمل الحديثة ك Laravel تستخدم البرمجة غرضية التوجه.

احتراف تطوير ووردبريس

نحن فقط بدأنا في تعلم ما يمكننا فعله، ويوجد الكثير مما يمكن تعلمه عن الأصناف وأنصحك في التدريب والتجريب وارتكاب الأخطاء وعدم الاستسلام.

ترجمة -وبتصرّف- للمقال Advanced WordPress Development: Introduction to Object-Oriented Programming لصاحبه Daniel Pataki





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن