php में वर्ग के सदस्यों को आरम्भ करने के लिए सर्वोत्तम अभ्यास


10

मेरे पास अपने निर्माणकर्ताओं में बहुत सारे कोड हैं: -

function __construct($params) {

    $this->property = isset($params['property']) ? $params['property'] : default_val;

}

क्या संपत्ति की परिभाषा में डिफ़ॉल्ट मूल्य को निर्दिष्ट करने के बजाय ऐसा करना बेहतर है? यानी public $property = default_val? कभी-कभी डिफ़ॉल्ट मान के लिए तर्क होता है, और कुछ डिफ़ॉल्ट मान अन्य गुणों से लिए जाते हैं, यही कारण है कि मैं कंस्ट्रक्टर में ऐसा कर रहा था।

क्या मुझे बसने वालों का उपयोग करना चाहिए ताकि डिफ़ॉल्ट मानों के लिए सभी तर्क अलग हो जाएं?

जवाबों:


8

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

एक बात जो मैं देख रहा हूँ कि इस सवाल का जवाब देने में मदद मिल सकती है वह है $ परमों का पास होना जो सेट किए गए एट्रिब्यूट्स / एरे सदस्यों के पास हो भी सकते हैं और नहीं भी।

वर्षों से मैं इस निष्कर्ष पर पहुँचा हूँ:

सरणियों के पारित होने से बचें।

क्यों? खैर, वैकल्पिक उत्तीर्ण तर्कों के लिए निर्धारित प्रहरी मूल्यों को निर्धारित करने या करने का कोई तरीका नहीं है।

दूसरे शब्दों में, आपके द्वारा निर्दिष्ट कोड के साथ, आप ऐसा कुछ नहीं कर सकते:

function __construct($arg1 = NULL, $arg2 = DEFAULT_VAL) {

    $this->arg1 = $arg1;

    $this->arg2 = $arg2;

}

$ arg1 और $ arg2 वैकल्पिक तर्क हैं - यदि पारित नहीं हुए हैं तो उनके पास क्रमशः NULL और DEFAULT_VAL हैं - स्पष्ट रूप से जांचने की कोई आवश्यकता नहीं है।

हो सकता है कि यह एक तरह की मनमानी हो।

मुझे लगता है कि आप जो हासिल करने की कोशिश कर रहे हैं वह मुझे मिलता है - एक ही संदर्भ के पारित होने के रूप में तर्कों के विपरीत। यह मुझे मेरे अगले संरक्षण में लाता है:

यदि "परमाणु" चर (तार, पूर्णांक, शाब्दिक) पास नहीं कर रहे हैं तो ऑब्जेक्ट पास करें।

यहां परफॉरमेंस बेनिफिट्स हैं क्योंकि पासिंग ऑब्जेक्ट्स को रेफरेंस द्वारा किया जाता है (हालाँकि मुझे लगता है कि PHP के अंदर लगभग वही हैं)।

तो आप कुछ ऐसा कर सकते हैं:

function __construct(MyAwesomeObject $oArg) {

        $this->oArg = $oArg;

    }

पारित वस्तु तर्क के बाद "प्रॉपर्टी 1", "प्रॉपर्टी 2" की गारंटी दी जाएगी, भले ही डिफ़ॉल्ट मानों के साथ संभवतः।

इसके अतिरिक्त, यहां आप संकेत टाइप कर सकते हैं और एक अच्छी IDE सही ढंग से स्वतः पूर्ण कोड भी पूरा कर सकती है।

लेकिन हमें जल्दी से पता चलता है कि हमारे पास एक चिकन और एक अंडे की चीज चल रही है: आप एक वस्तु का निर्माण कर रहे हैं जो कि पास की गई वस्तु तर्कों के साथ हो रही है, जिसे स्वयं किसी बिंदु पर निर्माण की आवश्यकता है।

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

तो क्या मैंने आपके सवाल का जवाब दिया? शायद बिल्कुल नहीं। लेकिन मुझे आशा है कि मैं कुछ शैलीगत कुछ उपयोगी यद्यपि सचित्र। मुझे लगता है कि कोड थोड़ा साफ है, अधिक पठनीय है, और कम खर्चीला है।

अब, यह कहने की ज़रूरत नहीं है कि आपको अपने इनपुट को सैनिटाइज़ नहीं करना चाहिए। यह पूरी तरह से एक और चर्चा है।

उम्मीद है की यह मदद करेगा।


1
यह एक अच्छा बिंदु है, और आईडीई संकेतों के लिए बहुत आसान है, लेकिन इन सभी मापदंडों के रूप में पास करने के लिए बहुत अधिक ऑब्जेक्ट गुण हैं। यदि आपके पास 7 तर्क हैं, जिनमें से 5 का कहना है कि आप वैकल्पिक हैं जैसे new object($param1,-some default value so I can specify the next parameter-, $param3);कि आप चीजों के साथ समाप्त होते हैं और इसलिए आपके पास कई अलग-अलग स्थानों में आपके डिफ़ॉल्ट मान कठोर हैं
rgvcorley

3

हालाँकि, मैं एक कंस्ट्रक्टर को पासिंग एरे से बचने के लिए प्रेरित करता हूं, कभी-कभी मुझे एक आवक ऐरे वैल्यू (जैसे कि एक क्लास के लिए जो कॉन्फ़िगरेशन फ़ाइल से मान पढ़ता है) को संसाधित करना आवश्यक लगता है।

इस तरह के एक मामले में, मैं यह सुनिश्चित करने के लिए PHP के सरणी फ़ंक्शंस का लाभ उठाऊंगा कि मैं ठीक उसी तरह से काम कर रहा हूं जो मुझे लगता है कि मैं इसके साथ काम कर रहा हूं:

public function import( array $incoming )
{
  $defaults = array(
      'foo' => DEFAULT_FOO
    , 'bar' => DEFAULT_BAR
    ...
  );

  $values = array_merge($defaults, array_intersect_key($incoming, $defaults));

  ...
}

वह अंतिम पंक्ति array_merge()किसी भी मान $defaultsको उनके संबंधित मानों से अधिलेखित करने के लिए उपयोग करती है $incoming। मैं यह array_intersect_key()सुनिश्चित करने के लिए भी उपयोग करता हूं कि परिणामी सरणी में कोई अतिरिक्त कुंजी नहीं है जो वर्ग / विधि को नहीं पता होगा कि प्रक्रिया कैसे की जाती है।


नमस्कार, सरल चर के बजाय यदि $ चूक में एक सरणी है तो व्यवहार क्या है?
पोल डेलैरा

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