क्या सभी प्लगइन्स को एक कक्षा में समझाया जाना चाहिए?


28

एक प्लगइन विकसित करते समय नामस्थान संघर्षों से बचने के लिए कार्यों को एक कक्षा में एक साथ रखा जाना चाहिए?

क्या कक्षाओं का उपयोग करना PHP के लिए प्रदर्शन ओवरहेड्स बनाता है?

यदि कोई प्रदर्शन हिट होता है, तो क्या इसके बजाय नाम पूर्व निर्धारित होना चाहिए?


8
शायद एक वर्डप्रेस की तुलना में PHP प्रश्न अधिक है, यह देखें कि क्या यह स्टैकओवरफ़्लो प्रश्न आपके प्रश्न को उपयुक्त रूप से संबोधित करता है।
t31os

जवाबों:


24

एक प्लगइन विकसित करते समय नामस्थान संघर्षों से बचने के लिए कार्यों को एक कक्षा में एक साथ रखा जाना चाहिए?

हां, लेकिन यह केवल एक मामूली तर्क है। वास्तव में यह OOAD में एक वर्ग की "सत्य" प्रकृति नहीं है ।

क्या कक्षाओं का उपयोग करना PHP के लिए प्रदर्शन ओवरहेड्स बनाता है?

नहीं, विशेष रूप से नहीं। खराब डिज़ाइन और / या खराब लिखित कोड या पूर्व-परिपक्व अनुकूलन वास्तविक भाषा सुविधाओं की तुलना में कहीं अधिक प्रदर्शन की समस्याएं पैदा करता है।

यदि कोई प्रदर्शन हिट होता है, तो क्या इसके बजाय नाम पूर्व निर्धारित होना चाहिए?

जैसा कि लिखा गया है, कोई प्रदर्शन हिट नहीं है। खराब लिखित कोड अच्छे लिखित कोड की तुलना में एक प्रदर्शन हिट से अधिक होगा जिसमें कोड की कुछ और लाइनें होती हैं, लेकिन आपको बुरे काम करने के लिए मजबूर नहीं करती हैं।


जमीनी स्तर:

आप प्लगइन्स के लिए कक्षाओं का अलग-अलग उपयोग कर सकते हैं। आप उन्हें केवल कुछ प्रकार के नामस्थान रखने के लिए उपयोग कर सकते हैं और उन्हें वैश्विक कार्यों के लिए "बस" का उपयोग कर सकते हैं। इसका सबसे प्रत्यक्ष रूप स्टेटिक क्लास फ़ंक्शंस हैं, निम्न कोड-उदाहरण दोनों को दिखाता है, पहले वैश्विक फ़ंक्शंस, फिर ग्लोबल स्टैटिक क्लास फ़ंक्शंस:

/* global function */
function myplug_hook()
{
}

add_filter('the_hook', 'myplug_hook');


/* global static function */
class myplug
{
    public static function hook()
    {
    }
}

add_filter('the_hook', 'myplug::hook');

यह केवल एक छोटा सा उदाहरण है जो बताता है कि आपको सिंगल हुक के लिए अधिक टाइप करने की आवश्यकता है। इसके अतिरिक्त यह दिखाता है कि नाम स्थान कैसे काम करता है: आप सभी स्थिर कार्यों का नाम बदलने के लिए एकल वर्ग के नाम को आसानी से बदल सकते हैं और फिर खोज सकते हैं और बदल myplug::सकते हैं जो myplug_झूठी सकारात्मकता के कारण कठिन हो सकता है । लेकिन अंत में बहुत अंतर नहीं है।

मुख्य बिंदु यह है: स्थिर वर्ग फ़ंक्शंस डॉक्स वास्तव में बहुत अधिक नहीं हैं तो वैश्विक फ़ंक्शंस डॉक्स

और यह उदाहरण भी दिखाता है: नेमस्पेसिंग ठीक है, लेकिन वर्पड्रेस के साथ, नाम स्थान हुक के उपयोग से बंद हो जाता है: कॉलबैक फ़ंक्शन हार्डकोडेड है, इसलिए कक्षा का उपयोग करके नाम स्थान में लाभ (आधार-नाम के लिए एक स्थान, क्लासनाम) नहीं करता है जब आप हुक नामों के लिए अपने कोड को वर्डप्रेस के साथ हस्तक्षेप करने में मदद करें।

वास्तविक लाभ वास्तविक वर्ग के उदाहरणों और गैर-स्थिर कार्यों का उपयोग करने से शुरू होता है। इसका लाभ यह है कि आप ओओ सिद्धांतों का उपयोग करना शुरू कर सकते हैं और आप अपने कोड को सुव्यवस्थित कर सकते हैं। स्टैटिक क्लास फ़ंक्शंस एक सॉल्यूशन इन्फैक्ट की तुलना में अधिक समस्या है।

तब यह सिंटैक्टिक शुगर से अधिक है।

मुख्य बिंदु यह है: कुछ ऐसा करें जो आपको कोड लिखने में मदद करे जो आप आसानी से कर सकते हैं और बनाए रख सकते हैं। ओवर-दर प्रदर्शन न करें, यह एक सामान्य गलती है। अधिक महत्वपूर्ण यह है कि आप ऐसा कोड लिखें जो पढ़ने और समझने में आसान हो, बस वही करें जो आपको चाहिए। हो सकता है कि यह प्रश्न और उत्तर इस संदर्भ में एक बड़ी तस्वीर के लिए सहायक हो: एकाधिक कस्टम मेटाबॉक्स सहायता

छोटे प्लग इन के साथ भी मेरे पास एक सामान्य दृष्टिकोण है, ताकि प्लगइन को इंस्टेंट करने के लिए एक स्टैटिक हेल्पर फंक्शन का उपयोग किया जा सके और बाकी तब प्लगइन के भीतर रहता है। यह मुख्य प्लगइन लॉजिक को एनकैप्सुलेट करने में मदद करता है और यह हुक के साथ नाम स्थान से लाभान्वित करता है साथ ही निजी सदस्यों को हुक के बीच फिर से उपयोग किया जा सकता है जो मानक वैश्विक कार्यों के साथ संभव नहीं है। निम्नलिखित कोड-उदाहरण पैटर्न दिखाता है:

<?php
/** Plugin Headers ... */

return MyPlugin::bootstrap(); 

class MyPlugin
{
    /** @var MyPlugin */
    static $instance;
    static public function bootstrap() {
        if (NULL === self::$instance) {
            self::$instance = new __CLASS__;
        }
        return self::$instance;
    }
    # ...
}

यह एक सामान्य पैटर्न है जो मैं आधार प्लगइन फ़ाइल के लिए उपयोग करता हूं। एक ओर प्लगइन वर्ग वर्डप्रेस के लिए प्लगइन का प्रतिनिधित्व करता है और दूसरी ओर यह स्वयं के कोड के लिए ऑब्जेक्ट ओरिएंटेड प्रतिमानों का उपयोग करना शुरू करने की अनुमति देता है जो पूरी तरह से ऑब्जेक्ट ओरिएंटेड हो सकते हैं (लेकिन आवश्यकता नहीं है)। यह एक तरह का नियंत्रक है, अनुरोध (ओं) के रूप में पूरे वर्डप्रेस एपीआई के साथ इंटरफेस करता है।

जैसा कि उदाहरण से पता चलता है, प्लगइन का एक उदाहरण बनाया जाएगा। यह आपको वास्तविक प्लगइन को इनिशियलाइज़ करने के लिए कंस्ट्रक्टर डॉक्स ( __construct) जैसे ज्ञात कॉमन्स का उपयोग करने की अनुमति देता है :

# ...
class MyPlugin
{
    # ...
    public function __construct()
    {
        add_filter('the_hook', array($this, 'hook'));
    }

    public function hook()
    {
    }
    # ...
}

जिस समय हुक पंजीकृत होता है, यह प्लगइन ऑब्जेक्ट पहले से ही इसके डिज़ाइन से लाभान्वित होता है: आप ठोस प्लगइन क्लासनाम के खिलाफ वास्तविक हुक फ़ंक्शन को हार्ड-कोड करना बंद कर चुके हैं । कॉलबैक के लिए ऑब्जेक्ट उदाहरण के लिए वर्ग के बंधन के कारण यह संभव है। ध्वनि जटिल, बस कह रही: $this है प्लगइन। हुक कॉलबैक में इस्तेमाल किया जा सकता है, हुकिंग कॉलबैक के रूप में रजिस्टरिंग क्लास तरीकों की तुलना करें

यह पैटर्न वर्डप्रेस के साथ इंटरफ़ेस को आसान बनाने की अनुमति देता है: इंजेक्शन हुक के नाम और जो डेटा वे प्रदान करते हैं, उसके लिए कम हो जाता है। फिर आप सीधे इस प्लगइन वर्ग में लागू करना शुरू कर सकते हैं या इसके खिलाफ अपने कार्यान्वयन को फिर से शुरू कर सकते हैं, इसलिए केवल प्लगइन वर्ग में कोड डालें जो कि वर्डप्रेस के खिलाफ आपके प्लग इन इंटरफ़ेस को परिभाषित करने के लिए न्यूनतम है, लेकिन वर्पड्रेस के सामान्य तर्क को अलग रखें। यह वह जगह है जहाँ मज़ा शुरू होता है और सबसे शायद यही कि प्रत्येक प्लगइन लेखक लंबे समय में क्या हासिल करना चाहता है।

तो worpdress के साथ कार्यक्रम नहीं है, लेकिन इसके खिलाफ है। के रूप में worpdress काफी लचीला है, के खिलाफ प्रोग्राम के लिए इंटरफ़ेस का वर्णन करने के लिए कोई आम या आसान नहीं है। एक आधार प्लगइन वर्ग इस भूमिका को ले सकता है, जिससे आप अपने स्वयं के कोड के लिए अधिक लचीलेपन की अनुमति देंगे जिससे आसान कोड और एक बेहतर प्रदर्शन होगा।

तो नाम-रिक्ति के लिए सिर्फ एक लाभ से अधिक है। सबसे अच्छा सुझाव मैं दे सकता हूं: स्वयं प्रयास करें। बहुत कुछ नहीं है आप ढीले होंगे, केवल नई चीजों की खोज करने के लिए।

जब आप अपने प्लगइन को संगत रखते हुए वर्डप्रेस के कुछ और प्रमुख अपडेट पास कर लेते हैं, तो आप शायद सबसे अधिक अंतर नोटिस करेंगे।

कैविएट : यदि आपका प्लगइन सीधे काम करने के लिए वर्डप्रेस के साथ एकीकृत करता है, तो एक या दो सार्वजनिक कार्यों का उपयोग करना आपके लिए बेहतर हो सकता है। नौकरी के लिए सही उपकरण लें।


1
यदि स्थैतिक वर्ग फ़ंक्शंस वास्तव में वैश्विक फ़ंक्शंस से अलग नहीं हैं, और आपका उद्देश्य नेमस्पेसिंग संघर्षों को रोकने के लिए है, तो मैं वास्तव में वर्गों के रूप में लेखन प्लगइन्स पर स्विच करने की आवश्यकता (अभी तक) नहीं समझ पाया हूं। इसके अलावा, मैं आपके सहायक बूटस्ट्रैप फ़ंक्शन द्वारा भ्रमित हूं। क्यों न केवल नई वस्तु को $ new_object = नए MyClass () के रूप में घोषित किया जाए??
AlxVallejo

@AlxVallejo: अकेले नाम रखने के लिए, कोई वास्तविक आवश्यकता नहीं है (जैसा कि मैंने उत्तर में लिखा है, स्थैतिक वर्ग विधियां वैश्विक कार्यों के समान ही बहुत अधिक हैं)। तो आप अपने स्वयं के नामस्थान (पूर्व PHP 5.3 प्रकार के नामस्थान जो कर सकते हैं) कर सकते हैं। तो आपने देखा कि बिल्कुल सही है। स्थैतिक बूटस्ट्रैप फ़ंक्शन के साथ समान: तकनीकी रूप से यह आवश्यक नहीं है, एक साधारण भी return $myPlugin = new MyPlugin(); करता है। हालाँकि बड़ी तस्वीर के लिए, एक साधारण नया पर्याप्त नहीं हो सकता है, वर्डप्रेस प्लगइन की तुलना करें: मैं "तंग युग्मन" से कैसे बचूँ?
हकरे

9

क्लासेस VS फंक्शन सेट


प्रदर्शन

सामान्य: Afaik, कक्षाओं और फ़ंक्शन सेटों के बीच "प्रदर्शन" में कोई अंतर नहीं है।

विवरण:

  • वहाँ एक बड़ा अंतर है अगर आप सवाल करते हैं function_exists()class_exists()आम तौर पर आप बहुत सारे कार्य करते हैं (~ 1.800 (?) Wp कोर में) बनाम कक्षाएं (~ 100 (?) Wp कोर में)। इसलिए सामान को "प्लग करने योग्य" बनाना और इसलिए अस्तित्व पर सवाल उठाना है निष्पादन समय में एक फर्क।
  • फ़ंक्शंस सेट पर कक्षाएं एक बड़ा लाभ प्रदान करती हैं : आप बहुत आसानी से इसे अनुरोध पर कॉल करने से बच सकते हैं जहां आपको इसकी आवश्यकता नहीं है, फिर फ़ंक्शन के साथ। आपको केवल कक्षा के लिए सशर्त जाँच करनी है और प्रत्येक फ़ंक्शन के लिए नहीं। इसलिए अगर आपको हर पेज लोड पर इसकी आवश्यकता नहीं है और बहुत सारे कॉल करने से बच सकते हैं, तो / एक और बयान, एक फ़ंक्शन "बेहतर प्रदर्शन करता है"।

वास्तुकला - सामान कैसे काम करता है:

फ़ंक्शन सेट: सामान्य तौर पर, फ़ंक्शन उस पंक्ति में निष्पादित हो जाता है जिसे आप कहते हैं। इसलिए हर बार जब आप सामान कहते हैं, तो आपको इसे फिर से लिखना होगा, अगर आपको इसे एक से अधिक बार कॉल करना है।

वर्ग: वर्गों के लिए अलग-अलग प्रकृतियां हैं। एक फ़ंक्शन सेट के सबसे करीब आने वाला वर्ग "फ़ैक्टरी" वर्ग ( विकिपीडिया / गूगल ) है। Imo यह लगभग कार्यों के एक सेट के समान है, लेकिन एक वर्ग में समझाया गया है। लेकिन वर्गों के अन्य "प्रकार" भी हैं। आप उदाहरण के लिए एक अमूर्त या मूल वर्ग वर्ग लिख सकते हैं , कि आप एक बाल वर्ग के साथ विस्तार करते हैं। एक वास्तविक दुनिया उदाहरण में: मान लीजिए कि आपको एक क्लास मिला है जो कुछ स्थिर टेक्स्ट फ़ील्ड बनाता है। आपके __construct()फ़ंक्शन में आपके पास "left_column", "right_column" और "footer_field" जैसे परिदृश्यों का एक सेट है। फिर आप $text_field = new TextFieldClass();क्लास को इंस्टेंट करने के लिए कुछ कहते हैं । और बाद में आप बस कॉल करें$text_field->add( $case => 'left_column', 'case' => 'foo text' ); और$text_field->add( $case => 'footer_field', 'case' => 'bar text' );। तब आपकी सभी अवस्थाएँ और अन्य पहले ही प्रदर्शित हो चुकी होती हैं जब आप कक्षा को तुरंत तैयार करते हैं और जब आप पाठ फ़ील्ड का निर्माण करते हैं तो सिर्फ दो कक्षा के कार्यों को बुलाया जाता था। इस szenario में आप निष्पादन समय के कुछ एमएस बचा सकता है।


निजी राय

यदि आप अपनी कक्षाओं को बुद्धिमानी से लिखते हैं, तो आपको प्रदर्शन में मामूली लाभ होगा । लेकिन आपके पास काम करने के लिए एक अच्छी तरह से संगठित संरचना होगी। अभी तक कुछ भी शानदार नहीं है। लेकिन यदि आप एक प्लगइन में वर्गों और कार्यों के लिए निम्नलिखित "विभाजन" मामलों का उपयोग करते हैं, तो आपको मेरा अंतिम बिंदु मिलेगा : कक्षा आंतरिक है, फ़ंक्शन एपीआई है । जब तक आप केवल सार्वजनिक रूप से उपयोग करने योग्य कार्यों (कि तब कक्षाओं या वर्ग कार्यों को कॉल करते हैं) के माध्यम से एपीआई की पेशकश करते हैं, तो आप अपने प्लगइन को और अधिक विकसित करने के लिए सेव साइड पर होंगे। आपने किसी भी समय और हर जगह उपयोगकर्ताओं को प्रभावित किए बिना आंतरिक संरचना या यहां तक ​​कि अपने प्लगइन की संभावनाओं को बदलने की स्वतंत्रता को कम कर दिया।

उदाहरण:

// construction of object
if ( ! class_exists( 'WPSE_HelloWorld' ) )
{

class WPSE_HelloWorld
{
    function __construct( $args = array( 'text', 'html', 'echo' ) )
    {
        // call your object building procedures here
        $this->hello_world( 'text', 'html', 'echo' );
    }

    function hello_world( 'text', 'html', 'echo' )
    {
        $start_el = '<{$html}>';
        $end_el = '</{$html}>';
        if ( $echo )
        {
            return print "{$start_el}{$some}{$end_el}";
        }

        return "{$start_el}{$some}{$end_el}";
    }
} // END Class 

}

// API: public functions
function the_hello_world( $args( 'echo' => true ) )
{
    $new = new WPSE_HelloWorld();
    return $new->hello_world( $args );
}

function get_hello_world( array( $args( 'echo' => false) ) )
{
    $new = new WPSE_HelloWorld();
    return $new->hello_world( $args );
}

// then you can call it like get_the_title() or the_title(), which you know from the WP API:
// 'echo' is set to false per default:
$some_var = get_hello_world( array( 'text' => 'hello reader', 'html' => 'strong' ) );
# *returns* "<strong>hello reader</strong>"

// 'echo' is set to true per default:
the_hello_world( array( 'text' => 'hello reader', 'html' => 'strong' ) );
# *prints/echos* "<strong>hello reader</strong>"

नोट: कृपया Q में टिप्पणी में पोस्ट किए गए लिंक @ t310 को भी पढ़ें।


बस जिज्ञासु, आप अपने प्लगइन फ़ाइल को वर्डप्रेस के साथ एक से अधिक बार शामिल करने की अपेक्षा क्यों करते हैं?
हैक्रे

@ ठाकरे वास्तव में मैंने ऐसा कहां कहा? sry, माँ पर बहुत थक गया।
कैसर

1
@kaiser, मुझे लगता है कि @hakre if( ! class_exists )शुरुआत में आपके पास मौजूद लाइन का जिक्र कर रहा है?
jjeaton

1
@hakre मुझे लगता है कि @kaiser class_existsचेक नहीं कर रहा है क्योंकि इसे एक बार फिर शामिल किया जा सकता है लेकिन किसी अन्य वर्ग के साथ टकराव से बचने के लिए?
मिशाल मउ

हाँ मैं class_exists के बारे में सोच रहा था।
हकर्रे

4

यह प्लगइन लेखक की ओर से एक विशुद्ध रूप से शैलीगत पसंद है। गति के मामले में कोई वास्तविक अंतर नहीं है।


1

कक्षाएं आमतौर पर प्रदर्शन के मामले में कोई लाभ नहीं देती हैं, लेकिन उनके पास बहुत कम ही कोई नकारात्मक प्रभाव होता है। उनका वास्तविक लाभ कोड को स्पष्ट करने और नाम स्थान के टकराव से बचने में है।


फिर भी, जैसा कि @hakre ने उल्लेख किया है, वैश्विक कार्यों पर उपसर्गों का उपयोग करते समय नेमस्पेस संघर्ष वास्तव में अलग नहीं है। "क्लीनर" कोड और नाम स्थान के टकराव को रोकना इस मामले में पर्याय हैं, नहीं?
AlxVallejo

@AlxVallejo मुझे ऐसा लगता है :)
बैनेटर्न

0

अधिकांश समय, यदि आप फ़ंक्शन का उपयोग करते हैं, तो आप प्रत्येक फ़ंक्शन नाम में प्लगइन का नाम डालेंगे, इसलिए प्रभावी रूप से, आप उस नाम को एक दर्जन बार डुप्लिकेट करेंगे यदि प्लगइन में एक दर्जन फ़ंक्शन हैं जो थोड़ा सा खींचना है ।

कक्षाओं के साथ, आपको कक्षा नाम में प्लगइन का नाम एक बार होने की संभावना है।

इसके अतिरिक्त, आप व्यवहार को बहुत साफ तरीके से कार्यान्वित करने के लिए वंशानुक्रम या अन्य ऊ निर्माण का उपयोग कर सकते हैं। यहाँ एक पूर्व है:

class animalplugin{
  //plugin functions...
  function talk(){print "animalnoise";}
}
class animalplugin_with_cat_mods extends abcplugin{
  //cat functions overrides
  function talk(){print "meow";}
}
if (iscat()){
  new animalplugin_with_cat_mods();
} else {
  new animalplugin();
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.