क्या PHP क्लास में Getters / setters को संभालने का एक उचित तरीका है?


Answers

@Brian

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

यह बिल्कुल सच नहीं है मेरा पहला उदाहरण लें:

class PropTest extends PropertyHandler
{
    public function __construct()
    {
        parent::__construct();
    }
}

$props = new PropTest();

$props->setFirstName("Mark");
echo $props->getFirstName();

मान लें कि मुझे फर्स्टनेम्स मान्य करने के लिए कुछ तर्क जोड़ना होगा। मुझे जो करना है उसे सबवेस के लिए एक सेटफर्स्ट नाम विधि जोड़ना है और वह विधि स्वचालित रूप से इसके बजाय उपयोग की जाती है

class PropTest extends PropertyHandler
{
    public function __construct()
    {
        parent::__construct();
    }

    public function setFirstName($name)
    {
        if($name == 'Mark')
        {
            echo "I love you, Mark!";
        }
    }
}

मैं बस सीमाओं के साथ संतुष्ट नहीं हूं जो कि PHP में है जब यह अंतर्निहित एक्सेसर विधियों के लिए आता है।

मैं पूरी तरह से सहमत हूँ। मुझे यह संभाल करने का पायथन तरीका पसंद है (मेरा कार्यान्वयन केवल यह एक अनियमित चीर है)।

Question

मैं इस प्रश्न के प्रारूप के साथ कुछ कोशिश करने जा रहा हूँ और मैं इसे बेहतर तरीके से सुझाव देने के लिए खोल रहा हूँ

मैं सिर्फ सवाल में कोड का एक गुच्छा डंप नहीं करना चाहता था इसलिए मैंने refactormycode पर वर्ग के लिए कोड पोस्ट किया है।

आसान श्रेणी संपत्ति प्रबंधन के लिए आधार वर्ग

मेरा विचार था कि लोग या तो कोड स्निपेट पोस्ट कर सकते हैं या फिर रिफैक्टमर्मोड पर परिवर्तन कर सकते हैं और लिंक को अपने पुनर्संयोजन में वापस कर सकते हैं। मैं उस पर आधारित अपवत्तों और एक उत्तर स्वीकार करूँगा (एक स्पष्ट "विजेता" माना जा रहा है)

किसी भी दर पर, कक्षा में ही:

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

public function getFirstName()
{
   return $this->firstName;
}
public function setFirstName($firstName)
{
   return $this->firstName;
}

अब मुझे यकीन है कि मैं ऐसा करने वाला पहला व्यक्ति नहीं हूँ (मुझे उम्मीद है कि ऐसा करने का एक बेहतर तरीका है कि कोई मुझे सुझाव दे सकता है)

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

मुझे __call का उपयोग करना पसंद है क्योंकि यह स्वचालित रूप से इस मामले की देखभाल करेगा जहां उप-वर्ग में पहले से ही "getFirstName" विधि परिभाषित की गई है मेरी धारणा (और मैं गलत हो सकता है) यह है कि __get और __set जादू तरीकों ऐसा नहीं करते हैं।

तो यह एक उदाहरण है कि यह कैसे काम करेगा:

class PropTest extends PropertyHandler
{
    public function __construct()
    {
        parent::__construct();
    }
}

$props = new PropTest();

$props->setFirstName("Mark");
echo $props->getFirstName();

नोटिस कि प्रॉपटीस्ट में वास्तव में "सेटफर्स्ट_नाम" या "जाओफर्स्ट-नाम" तरीके नहीं हैं और न ही संपत्तिहैंडलर जो भी कर रहा है वह सरणी मानों को जोड़ता है।

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

class PropTest2
{
    private $props;

    public function __construct()
    {
        $this->props = new PropertyHandler();
    }

    public function __call($method, $arguments)
    {
        return $this->props->__call($method, $arguments);
    }
}

$props2 = new PropTest2();

$props2->setFirstName('Mark');
echo $props2->getFirstName();

ध्यान दें कि उपवर्ग के पास एक __call पद्धति है जो बस सबकुछ संपदाहैण्डलर __कॉल विधि से गुजरता है।

गेटर्स और सेटर्स से निपटने के लिए एक और अच्छा तर्क यह है कि यह दस्तावेज को वास्तव में कठिन बना देता है

वास्तव में, किसी भी प्रकार की दस्तावेज़ पीढ़ी उपकरण का उपयोग करना मूल रूप से असंभव है क्योंकि दस्तावेज नहीं होने के स्पष्ट तरीके मौजूद नहीं हैं।

मैंने अब तक इस दृष्टिकोण को बहुत ज्यादा त्याग दिया है यह एक दिलचस्प सीखने का अभ्यास था लेकिन मुझे लगता है कि यह बहुत स्पष्टता बलिदान करता है




मैं सिर्फ सार्वजनिक क्षेत्रों का उपयोग करने के बजाय, लेकिन PHP की डिफ़ॉल्ट कार्यान्वयन (__get () और __set () का उपयोग करके मेरी समस्याएं पसंद करना पसंद करना चाहता हूं या आपके कस्टम कार्यान्वयन यह है कि आप प्रति-संपत्ति पर गेटर्स और सेटर्स स्थापित नहीं कर रहे हैं आधार। इस के साथ मेरी समस्या यह है कि "बाद में अधिक तर्क" जोड़ना आवश्यक है कि आप कम्बल तर्क जोड़ते हैं जो गेस्टेटर / सेटर के साथ अभिगम सभी सम्पत्तियों पर लागू होता है या जो आप उपयोग करते हैं, तो आप उस संपत्ति का मूल्यांकन करने के लिए उपयोग करते हैं जो कि आप उपयोग करते हैं विशिष्ट तर्क

मुझे आपका समाधान पसंद है, और मैं इसके लिए आपको सराहना करता हूं - मैं बस उन सीमाओं से संतुष्ट नहीं हूं जो कि PHP में है जब यह निहित अभिगम्य तरीकों के लिए आता है।




मैंने हमेशा इस मुद्दे को एक __ कॉल के साथ समान रूप से संभाला है जो मेरी कई कक्षाओं में बॉयलर प्लेट कोड के रूप में बहुत अधिक समाप्त होता है। हालांकि, यह कॉम्पैक्ट है, और केवल पहले से सेट किए गए गुणों के लिए getters / setters को जोड़ने के लिए प्रतिबिंब वर्ग का उपयोग करता है (नए जोड़ नहीं होगा)। बस गेटर / सेटर को जोड़कर स्पष्ट रूप से अधिक जटिल कार्यक्षमता जोड़ देगा यह होने की उम्मीद है

कोड इस तरह दिखता है:

/**
* Handles default set and get calls
*/
public function __call($method, $params) {

    //did you call get or set
    if ( preg_match( "|^[gs]et([A-Z][\w]+)|", $method, $matches ) ) {

        //which var?
        $var = strtolower($matches[1]);

        $r = new ReflectionClass($this);
        $properties = $r->getdefaultProperties();

        //if it exists
        if ( array_key_exists($var,$properties) ) {
            //set
            if ( 's' == $method[0] ) {
                $this->$var = $params[0];
            }
            //get
            elseif ( 'g' == $method[0] ) {
                return $this->$var;
            }
        }
    }
}

इसे उस क्लास में जोड़ना जहां आपने डिफ़ॉल्ट गुण की घोषणा की है जैसे:

class MyClass {
    public $myvar = null;
}

$test = new MyClass;
$test->setMyvar = "arapaho";

echo $test->getMyvar; //echos arapaho    

रिफ्लेक्शन क्लास कुछ का इस्तेमाल कर सकता है जो आप का प्रस्ताव कर रहे थे। साफ समाधान @ मार्क




मैं अपने 2 सेंट में डालने में मदद नहीं कर सकता ...

मैं इस __set में http://gist.github.com/351387 (उसी तरह के सिद्धांत के समान) __get और __set का उपयोग करने के लिए ले लिया है, फिर केवल कभी बाहर $obj->var माध्यम से संपत्तियों तक पहुंच प्राप्त कर सकते हैं कक्षा। इस तरह से आप एक विशाल __get या __set फ़ंक्शन, या बाल कक्षाओं में __get और __set को ओवरराइड करने के बजाय आवश्यकतानुसार कार्यक्षमता ओवरराइड कर सकते हैं।






Links



Tags

php php   oop