वैश्विक चर सेट और उपयोग कैसे करें? या उनका उपयोग क्यों न किया जाए


27

अद्यतन: मेरा मूल प्रश्न हल हो गया है, लेकिन यह इस बारे में एक वैध चर्चा में बदल रहा है कि वैश्विक चर का उपयोग क्यों नहीं किया जाए, इसलिए मैं उस प्रश्न को प्रतिबिंबित करने के लिए अपडेट कर रहा हूं। समाधान <?php global $category_link_prop; echo esc_url( $category_link_prop ); ?>@TomJNowell के अनुसार था ।

अद्यतन 2: मेरे पास अब वही है जो मैं चाहता था। लेकिन मैं अभी भी वैश्विक दायरे का उपयोग कर रहा हूं और बेहतर तरीका पाकर खुश हूं।

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

यह इस प्रकार है कि मैं वर्तमान में उन्हें बना रहा हूं (मैंने केवल कुछ चरों में चिपकाया है)।

function set_global_nav_var()
{
    //proposal
    global $prop;
    // Get the ID of a given category
    $category_id_prop = get_cat_ID( 'proposal' );
    // Get the URL of this category
    $category_link_prop = get_category_link( $category_id_prop );
    $prop = '<a href="' .esc_url( $category_link_prop ). '" title="Proposal">Proposal</a>';

    //Calvinball
    global $cb;
    // Get the ID of a given category
    $category_id_cb = get_cat_ID( 'calvinball' );
    // Get the URL of this category
    $category_link_cb = get_category_link( $category_id_cb );
    $cb = '<a href="' .esc_url( $category_link_cb). '" title="Calvinball">Calvinball</a>';
}
add_action( 'init', 'set_global_nav_var' );

मैं अब <?php global $prop; echo $prop; ?>वह 4 जगह int कर सकता हूं जो कोड के लिए पूरे लिंक को जाता है और वापस मिलता है। जब उस परिवर्तन को मुझे केवल एक स्थान पर बदलना होगा। मैं उन विकल्पों के लिए खुला हूं जिनमें वैश्विक गुंजाइश शामिल नहीं है।


1
कौन सा लिंक इस कथन को गूंजता है esc_url ($ category_link_prop); प्रदर्शित करता है? आपका अपेक्षित लिंक क्या है?
विनोद दलवी

1
आप कभी भी 'get_cat_ID (****)' का उपयोग क्यों नहीं करेंगे जहां आपने कभी वैश्विक चर का उपयोग करने की योजना बनाई है। मुझे संदेह है कि आपके काम करने के तरीके में कोई गति होगी। पठनीयता के दृष्टिकोण से, 'get_cat_ID (****)' हाथ नीचे जीतता है।
क्रिस स्ट्रेटन ने

1
क्या आप reword कर सकते हैं? मैंने आपका प्रश्न पढ़ा और मैं अभी भी अनिश्चित हूं कि आप क्या करना चाहते हैं और क्यों करना चाहते हैं। मेरे सामान्य सलाह वैश्विक चर का उपयोग नहीं करने के लिए होगा, और वैश्विक क्षेत्र को प्रदूषित करने के लिए नहीं
टॉम जम्मू नॉवेल

1
यह एक एक्स / वाई समस्या की तरह लग रहा है । शायद आपको बैकअप लेना चाहिए और यह बताना चाहिए कि आपका वांछित परिणाम क्या है। मुझे यकीन है कि वैश्विक संस्करणों का एक समूह स्थापित करने की तुलना में कहीं अधिक सुंदर समाधान है, तो कहीं और कहीं उन्हें केवल एक हार्डकोड के संदर्भ में
मिलो

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

जवाबों:


21

जबकि मैं इसके खिलाफ दृढ़ता से सलाह देता हूं, और यह चीजों को गति नहीं देगा, आपका उपयोग गलत है।

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

कार्यों में उदाहरण के लिए। पीपी:

function test() {
    global $hello;
    $hello = 'hello world';
}
add_action( 'after_theme_setup', 'test' );

Single.php में, यह काम नहीं करेगा:

echo $hello;

क्योंकि $ हैलो अपरिभाषित है। हालांकि यह काम करेगा :

global $hello;
echo $hello;

बेशक आपको न तो करना चाहिए। वर्डप्रेस पहले ही ऑब्जेक्ट कैश में इन चीजों को कैश करने का प्रयास करता है। आप ऐसा करने से कोई गति वृद्धि नहीं देखेंगे (आप एक छोटी गति में कमी देख सकते हैं), आप सभी को अतिरिक्त जटिलता मिलेगी और बहुत सारी वैश्विक घोषणाओं को टाइप करने की आवश्यकता है जो आवश्यक नहीं हैं।

आप संरचित डेटा, जैसे ऑब्जेक्ट या निर्भरता इंजेक्शन, या आपके मामले में, फ़ंक्शन का एक सेट का उपयोग करना बेहतर होगा।

उदाहरण के लिए, यहाँ स्थिर चर के माध्यम से कुछ ऐसा ही करने का एक साधन है (फिर भी समान कारणों से बुरा है, लेकिन बस थोड़ा कम है, और टाइप करना आसान है) उदा।

function awful_function( $new_hello='' ) {
    static $hello;
    if ( !empty( $new_hello ) ) {
        $hello = $new_hello;
    }
    return $hello;
}

awful_function( 'telephone' );
echo awful_function(); // prints telephone
awful_function( 'banana');
echo awful_function(); // prints banana

यदि आप वास्तव में डेटा को फिर से उपयोग करने के लिए कहीं संग्रहीत करके समय बचाना चाहते हैं, तो WP_Cacheसिस्टम का उपयोग करने wp_cache_getआदि पर विचार करें


मुझे पता है कि यह वैश्विक दायरे का उपयोग करने के लिए थोड़ा पागल है, लेकिन सबसे ज्यादा, अगर ये सभी चर हर पृष्ठ पर उपयोग नहीं किए जाएंगे। मैं बेहतर विचारों के लिए खुला हूं। मैं अपने इरादे को थोड़ा स्पष्ट करने के लिए प्रश्न को संपादित करने जा रहा हूं। BTW यह पूरी तरह से ठीक काम करता है जब मैं <?php global $category_link_prop; echo esc_url( $category_link_prop ); ?>आपके सुझाव के अनुसार करता हूं । धन्यवाद!
JPollock

2
यदि मेरा समाधान काम करता है, तो क्या आप स्वीकार किए जाते हैं? आपके वैश्विक चर मूल कॉल करने में उतने ही तेज़ हैं, आप फ़ंक्शंस का उपयोग करने के बजाय कोशिश करना चाह सकते हैं, इसलिए आपको 2 लाइनें टाइप करने की ज़रूरत नहीं है, बेहतर अभी तक, एक सिंगलटन, बेहतर अभी तक, उस सभी को गतिशील बनाने और एक में टेम्पलेट भाग get_template_part के माध्यम से शामिल
टॉम जम्मू नॉवेल

इसके रूप में स्वीकार किया जाता है कि मैं अब क्या कर रहा हूं, हालांकि मैं एक रणनीति के साथ चल सकता हूं @MarkKaplun नीचे सुझाव दे रहा है। Get_template_part () का उपयोग करना एक दिलचस्प विचार है, लेकिन मुझे यकीन नहीं है कि मुझे इस तरह की छोटी फ़ाइलों से भरा एक डायर चाहिए ...
JPollock

oooh नहीं नहीं, आप प्रत्येक श्रेणी के लिए एक फ़ाइल नहीं चाहते हैं, आप बस वही चाहेंगे जो वर्तमान श्रेणी का नाम पकड़ता है और उसका उपयोग करता है। आप hardcode कुछ भी नहीं करना चाहिए, यह सब हार्डकोड की परेशानी की कल्पना
टॉम जम्मू नॉवेल

मैंने अपने बच्चे के कार्यों में कोड डाल दिया है। एफपी जो सक्रिय है। लेकिन मैं एक "सामान्य" डेटाबेस-जनरेटेड पोस्ट से कॉल करने वाले php- शामिल फ़ाइल में चर का उपयोग नहीं कर सकता। कृपया मुझे सलाह दें, मैं क्या गलत करूँ? (मैं इसे वैश्विक रूप से परिभाषित करता हूं। निश्चित रूप से।)
ycc_swe

19

वैश्विक चर का उपयोग न करें , जितना सरल।

ग्लोबल्स का उपयोग क्यों नहीं करना चाहिए

क्योंकि ग्लोबल्स के इस्तेमाल से लॉन्ग टर्म में सॉफ्टवेयर को बनाए रखना मुश्किल हो जाता है।

  • एक वैश्विक कोड में कहीं भी घोषित किया जा सकता है, या कहीं भी, कहीं भी ऐसा कोई स्थान नहीं है जिसमें आप सहजता से इस बारे में कुछ टिप्पणी पा सकें कि वैश्विक उपयोग के लिए क्या है?
  • कोड पढ़ते समय आप आमतौर पर मान लेते हैं कि चर फ़ंक्शन के लिए स्थानीय हैं और यह नहीं समझते हैं कि फ़ंक्शन में उनके मूल्य को बदलने से सिस्टम में व्यापक परिवर्तन हो सकता है।
  • यदि वे इनपुट को नहीं संभालते हैं, तो फ़ंक्शन को उसी मान / आउटपुट को वापस करना चाहिए जब उन्हें समान मापदंडों के साथ बुलाया जाता है। किसी फ़ंक्शन में ग्लोबल्स का उपयोग अतिरिक्त मापदंडों का परिचय देता है जो फ़ंक्शन घोषणा में दस्तावेज़ नहीं हैं।
  • ग्लोबल्स के पास कोई विशिष्ट आरंभीकरण निर्माण नहीं है और इसके बाद आप कभी भी सुनिश्चित नहीं हो सकते हैं कि आप वैश्विक मूल्य तक पहुँच प्राप्त कर सकते हैं, और आरंभीकरण से पहले वैश्विक उपयोग करने का प्रयास करते समय आपको कोई त्रुटि नहीं मिलती है।
  • कोई और (शायद एक प्लगइन) एक ही नाम के साथ ग्लोबल्स का उपयोग कर सकता है, आपके कोड को बर्बाद कर सकता है, या आप प्रारंभिक आदेश के आधार पर इसे बर्बाद कर सकते हैं।

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

तो क्या किया जा सकता है जब एक वैश्विक में पहला रन परिणाम को संग्रहीत करने के बजाय कोड की कई पंक्तियों की प्रतिलिपि बनाने और चिपकाने से रोकने की कोशिश की जाती है? कई दृष्टिकोण, कार्यात्मक और ओओपी हैं।

स्वीटनर फ़ंक्शन। यह कॉपी / पेस्ट को बचाने के लिए बस एक आवरण / मैक्रो है

// input: $id - the category id
// returns: the foo2 value of the category
function notaglobal($id) {
  $a = foo1($id);
  $b = foo2($a);
  return $b;
}

लाभ यह है कि अब एक दस्तावेज है कि पूर्व वैश्विक क्या करता है, और आपके पास डिबगिंग के लिए एक स्पष्ट बिंदु है जब वापस लौटाया जा रहा मूल्य वह नहीं है जिसकी आप अपेक्षा करते हैं।

एक बार जब आपके पास एक स्वीटनर होता है, तो परिणाम को कैश करना आसान होता है यदि आवश्यक हो (ऐसा केवल तभी करें जब आपको पता चले कि इस फ़ंक्शन को निष्पादित करने में लंबा समय लगता है)

function notaglobal($id) {
  static $cache;

  if (!isset($cache)) {
    $a = foo1($id);
    $b = foo2($a);
    $cache = $b;
  } 
  return $cache;
} 

यह आपको एक वैश्विक व्यवहार के समान व्यवहार देता है, लेकिन हर बार जब आप इसे एक्सेस करते हैं तो एक सुनिश्चित आरंभीकरण होने के लाभ के साथ।

आपके पास OOP के समान पैटर्न हो सकते हैं। मुझे लगता है कि OOP आमतौर पर प्लगइन्स और थीम में कोई मूल्य नहीं जोड़ता है, लेकिन यह एक अलग चर्चा है

class notaglobal {
   var latestfoo2;

   __constructor($id) {
     $a = foo1($id);
     $this->latestfoo2 = foo2($a)
   }
}

$v = new notaglobal($cat_id);
echo $v->latestfoo2;

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

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

class notaglobal {
   var latestfoo2;

   __constructor() {}

   foo2($id) {  
     if (!isset($this->latestfoo2)) {    
       $a = foo1($id);
       $b = foo2($a);
       $this->latestfoo2= $b;
     } 
     return $this->latestfoo2;
   }
}

$v = new notaglobal();
echo $v->foo2($cat_id);

7
कृपया, चिल्लाओ मत । यह समझाने का मन क्यों और किसी प्रकार का प्रशस्ति पत्र प्रदान करना?
ब्रासोफिलो

मुझे लगता है कि आपने उत्तर को गलत समझा। अगर वह वैश्विक चर में मूल्यों को संग्रहीत करके जल्दी अनुकूलन करने की कोशिश नहीं कर रहा होता तो उसका कोड काम कर जाता। चिल्ला क्योंकि बुनियादी स्थापित सॉफ्टवेयर विकास सिद्धांतों का पालन करना कुछ ऐसा है जिस पर पर्याप्त जोर नहीं दिया जा सकता है। जो लोग उन मूल सिद्धांत (आपके स्थानीय Google पर उपलब्ध) को नहीं समझते हैं उन्हें नेट पर कोड नहीं फैलाना चाहिए।
मार्क कप्लून

1
IMO यह एक जवाब है, जो लोग यहां आते हैं, वे Google का गठन करते हैं, उन्हें यह देखना चाहिए कि अभी भी ग्लोबल्स का उपयोग करने के बारे में सोचना एक बुरा विचार है।
मार्क कप्लून

6
यह कहना पर्याप्त नहीं है कि एक्स न करें, आपको यह समझाना होगा कि आप ऐसा क्यों कहते हैं या आप इसे किस तरह से कह रहे हैं
टॉम जे नोवेल

1
@TomJNowell, मुझे यह मज़ेदार लगता है कि मैं केवल एक ही प्रश्न को कम कर रहा था, क्योंकि यह स्पष्ट रूप से WASE के दायरे से बाहर था। मुझे उस विषय पर विस्तार करने का मूल्य नहीं दिखाई दिया जो यहां शुरू नहीं होना चाहिए था।
मार्क कप्लून

8

आपका सवाल कैसे php काम करता है के साथ शामिल है।

उदाहरण के लिए $ wpdb लें

$ wpdb एक प्रसिद्ध वैश्विक चर है।

क्या आप जानते हैं कि यह कब घोषित किया जाएगा और मूल्यों के साथ सौंपा जाएगा?

हर बार जब आप अपने वर्डप्रेस साइट पर जाते हैं, तो हर पेज लोड किया जाता है।

इसी तरह, आपको यह सुनिश्चित करने की आवश्यकता है कि आप जिन वैरिएबल्स को वैश्वीकृत करना चाहते हैं, उन्हें हर पेज लोड किए गए संबंधित मानों के साथ घोषित और असाइन किया जाएगा।

हालांकि मैं एक थीम डिजाइनर नहीं हूं, मैं after_setup_theme को एक समय हुक बता सकता हूं। यह तभी सक्रिय होगा जब थीम सक्रिय होगी।

अगर मैं तुम थे, मैं init या अन्य हुक का उपयोग करेंगे। नहीं, अगर मैं तुम थे, मैं वैश्विक चर का उपयोग नहीं करेंगे ...

मैं चीजों को समझाने में वास्तव में अच्छा नहीं हूं। यदि आप PHP में तल्लीन करना चाहते हैं, तो आपको एक पुस्तक लेनी चाहिए।


2

आप हमेशा स्टैटिक गेटर्स के माध्यम से सिंगलटन पैटर्न का उपयोग कर सकते हैं।

<ul>
    <li><?php echo MyGlobals::get_nav_prop( 'proposal' )[ 'html' ]; ?></li>
    <li><?php echo MyGlobals::get_nav_prop( 'calvinball', 'html' ); ?></li>
</ul>


<?php

if ( ! class_exists('MyGlobals') ):

class MyGlobals {

    public $props;

    public function __construct(){
      $this->props = array (
        'proposal' => array( 'title' => 'Proposal', 'text' => 'Proposal' ),
        'calvinball' => array( 'title' => 'Calvinball', 'text' => 'Calvinball' ),
      );
    }

    public function get_nav_prop ( $term, $prop = false )
    {
      $o = self::instance();
      if ( ! isset( $o->props[$term] ) ) {  return falst; }
      if ( ! isset( $o->props[$term][ 'html' ] ) ) {
          $id = get_cat_ID( $term );
          $link = esc_url ( get_category_link( $id ) );
          $title = $o->props[$term]['title'];
          $text = $o->props[$term]['text'];
          $o->props[$term]['html'] = '<a href="'.$link.'" title="'.$title.'">'.$text.'</a>';
          $o->props[$term]['link'] = $link;
          $o->props[$term]['id'] = $id;
      }

      if($prop){ return isset($o->props[$term][$prop]) ? $o->props[$term][$prop] : null; }

      return $o->props[$term];
    }

    // -------------------------------------

    private static $_instance;

    public static function instance(){

      if(!isset(self::$_instance)) {
        self::$_instance = new MyGlobals();
      }
      return self::$_instance;
    }

}

endif; // end MyGlobals
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.