स्ट्रिंग द्वारा PHP वर्ग की संपत्ति प्राप्त करें


139

मुझे स्ट्रिंग के आधार पर PHP में संपत्ति कैसे मिलेगी? मैं इसे बुला लूंगा magic। तो क्या है magic?

$obj->Name = 'something';
$get = $obj->Name;

की तरह होगा...

magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');

जवाबों:


241

ऐशे ही

<?php

$prop = 'Name';

echo $obj->$prop;

या, यदि आपके पास कक्षा पर नियंत्रण है, तो ArrayAccess इंटरफ़ेस लागू करें और बस ऐसा करें

echo $obj['Name'];

पहले से दूसरे विकल्प का उपयोग करने का कोई लाभ?
Clox

2
@ क्लॉक्स आम तौर पर, उत्तरार्द्ध का उपयोग करने का मुख्य लाभ यदि आपके पास एक मौजूदा प्रणाली है जो एक सरणी-जैसे तरीके से चर का उपभोग करता है, लेकिन आप वस्तुओं द्वारा प्रस्तावित लचीलापन और शक्ति चाहते हैं। यदि एक वर्ग लागू करता है ArrayAccess, Countableऔर एक इट्रेटर इंटरफेस में से एक है, तो यह ज्यादातर एक सामान्य से अप्रभेद्य हैarray()
पीटर बेली

158

यदि आप एक मध्यवर्ती चर बनाए बिना संपत्ति का उपयोग करना चाहते हैं, तो {}नोटेशन का उपयोग करें :

$something = $object->{'something'};

यह भी आप उदाहरण के लिए एक लूप में संपत्ति का नाम बनाने के लिए अनुमति देता है:

for ($i = 0; $i < 5; $i++) {
    $something = $object->{'something' . $i};
    // ...
}

8
यह एकमात्र तरीका है यदि आप किसी ऐरे मूल्य पर पहुँच प्राप्त करना चाहते हैं $this->{$property}[$name], अन्यथा $this->$property[$name]एक त्रुटि होगी
goyote

@goyote: यह मान और PHP संस्करण पर निर्भर करता है। 5.3 में यह एक E_NOTICE को चलाता है क्योंकि संपत्ति "त्रुटि" के बजाय नहीं मिल सकती है, क्योंकि यह अभी भी वैध PHP सिंटैक्स है। यह संभव है कि $this->$property[$name]वास्तव में सफल हो सकता है, हालांकि यह एक बग होने की संभावना है। $nameचुपचाप एक पूर्णांक के लिए डाली जाती है। एक गैर-संख्यात्मक स्ट्रिंग के मामले में यह है 0। तब के मूल्य के इस स्ट्रिंग इंडेक्स$property को संपत्ति के नाम के रूप में उपयोग किया जाता है। यदि $propertyमूल्य "एबीसी" रखता है, तो यह संपत्ति $this->a(सूचकांक 0) को संदर्भित करेगा । अगर ऐसी कोई संपत्ति है तो यह सफल होगी।
Mrhhite

@goyote: हालांकि, PHP 5.4 में, एक गैर-संख्यात्मक स्ट्रिंग इंडेक्स चुपचाप पूर्णांक 0 में नहीं डाला जाता है, यह एक E_WARNING को ट्रिगर करेगा।
Mrhhite

13

आप जिस चीज के बारे में पूछ रहे हैं उसे वेरिएबल वेरिएबल्स कहा जाता है । आपको बस अपनी स्ट्रिंग को एक वैरिएबल में स्टोर करना है और इसे इस तरह एक्सेस करना है:

$Class = 'MyCustomClass';
$Property = 'Name';
$List = array('Name');

$Object = new $Class();

// All of these will echo the same property
echo $Object->$Property;  // Evaluates to $Object->Name
echo $Object->{$List[0]}; // Use if your variable is in an array

3
चर चर एक और बात है।
लाफुर वेज

2
सवाल यह है कि एक स्ट्रिंग (चर) में नाम समाहित होने पर वर्ग गुण (चर) कैसे प्राप्त किया जाए। या मैंने प्रश्न को गलत बताया?
परिपक्वता

8

कुछ इस तरह? यह परीक्षण नहीं किया है, लेकिन ठीक काम करना चाहिए।

function magic($obj, $var, $value = NULL)
{
    if($value == NULL)
    {
        return $obj->$var;
    }
    else
    {
        $obj->$var = $value;
    }
}

2
+1, पता नहीं था कि ऑब्जेक्ट गुण स्ट्रिंग्स का उपयोग करके प्राप्त किए जा सकते हैं।
मार्को डेमायो

5

बस एक चर में संपत्ति का नाम स्टोर करें, और संपत्ति का उपयोग करने के लिए चर का उपयोग करें। ऐशे ही:

$name = 'Name';

$obj->$name = 'something';
$get = $obj->$name;


4

यह सरल है, $ obj -> {$ obj-> नाम} घुंघराले कोष्ठक एक चर की तरह संपत्ति को बहुत लपेटेंगे।

यह एक शीर्ष खोज थी। लेकिन मेरा सवाल हल नहीं हुआ, जो इस $ का उपयोग कर रहा था। मेरी स्थिति के मामले में घुंघराले ब्रैकेट का उपयोग करने से भी मदद मिली ...

कोड इग्नाइटर के साथ उदाहरण मिलता है

एक स्रोत पुस्तकालय में एक अभिभावक वर्ग उदाहरण के साथ कुछ कहा जाता है

$this->someClass='something';
$this->someID=34;

पुस्तकालय वर्ग को माता-पिता के उदाहरण के साथ दूसरे वर्ग से भी स्रोत की आवश्यकता होती है

echo $this->CI->{$this->someClass}->{$this->someID};

2

बस एक अतिरिक्त के रूप में: इस तरह आप उन नामों के साथ गुणों तक पहुंच सकते हैं जो अन्यथा अनुपयोगी होंगे

$ x = नया StdClass;

$ प्रोप = 'ए बी'; $ x -> $ प्रोप = 1; $ x -> {'x y'} = 2; var_dump ($ x);

ऑब्जेक्ट (stdClass) # 1 (2) {
  ["ए बी"] =>
  पूर्णांक (1)
  ["x y"] =>
  पूर्णांक (2)
}
(ऐसा नहीं है कि आपको होना चाहिए, लेकिन अगर आपको ऐसा करना है)।
यदि आप भी कट्टरपंथी सामान करना चाहते हैं तो आपको प्रतिबिंब में देखना चाहिए


1

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

उदाहरण के लिए, $ Foo-> Bar-> baz, या $ Foo-> baz, या $ Foo-> Bar-> Baz-> dave को खोजने के लिए, जहाँ $ path 'foo / bar / baz' की तरह एक स्ट्रिंग है।

public function callModule($pathString, $delimiter = '/'){

    //split the string into an array
    $pathArray = explode($delimiter, $pathString);

    //get the first and last of the array
    $module = array_shift($pathArray);
    $property = array_pop($pathArray);

    //if the array is now empty, we can access simply without a loop
    if(count($pathArray) == 0){
        return $this->{$module}->{$property};
    }

    //we need to go deeper
    //$tmp = $this->Foo
    $tmp = $this->{$module};

    foreach($pathArray as $deeper){
        //re-assign $tmp to be the next level of the object
        // $tmp = $Foo->Bar --- then $tmp = $Bar->baz
        $tmp = $tmp->{$deeper};
    }

    //now we are at the level we need to be and can access the property
    return $tmp->{$property};

}

और फिर कुछ इस तरह से कॉल करें:

$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz'
$propertyString = substr($propertyString, 1);
$moduleCaller = new ModuleCaller();
echo $moduleCaller->callModule($propertyString);

0

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

आप उन 'प्रॉपर्टी_एक्सिस्ट' चेक को क्रमशः __set और __get तक ले जा सकते हैं और उन्हें सीधे जादू () के भीतर बुला सकते हैं।

<?php

class Foo {
    public $Name;

    public function magic($member, $value = NULL) {
        if ($value != NULL) {
            if (!property_exists($this, $member)) {
                trigger_error('Undefined property via magic(): ' .
                    $member, E_USER_ERROR);
                return NULL;
            }
            $this->$member = $value;
        } else {
            if (!property_exists($this, $member)) {
                trigger_error('Undefined property via magic(): ' .
                    $member, E_USER_ERROR);
                return NULL;
            }
            return $this->$member;
        }
    }
};

$f = new Foo();

$f->magic("Name", "Something");
echo $f->magic("Name") , "\n";

// error
$f->magic("Fame", "Something");
echo $f->magic("Fame") , "\n";

?>

0

यह कार्य क्या करता है यह जाँच करता है कि क्या संपत्ति उसके किसी बच्चे के इस वर्ग पर मौजूद है, और यदि ऐसा है तो इसे मूल्य मिलता है अन्यथा यह अशक्त हो जाता है। तो अब गुण वैकल्पिक और गतिशील हैं।

/**
 * check if property is defined on this class or any of it's childes and return it
 *
 * @param $property
 *
 * @return bool
 */
private function getIfExist($property)
{
    $value = null;
    $propertiesArray = get_object_vars($this);

    if(array_has($propertiesArray, $property)){
        $value = $propertiesArray[$property];
    }

    return $value;
}

उपयोग:

const CONFIG_FILE_PATH_PROPERTY = 'configFilePath';

$configFilePath = $this->getIfExist(self::CONFIG_FILE_PATH_PROPERTY);

-6
$classname = "myclass";
$obj = new $classname($params);

$variable_name = "my_member_variable";
$val = $obj->$variable_name; //do care about the level(private,public,protected)

$func_name = "myFunction";
$val = $obj->$func_name($parameters);

क्यों संपादित करें: इससे पहले: eval (बुराई) का उपयोग करने के बाद: बिल्कुल नहीं eval। इस भाषा में पुराना होना।


यह बहुत बुरी सलाह है, eval () फ़ंक्शन एक बहुत ही खतरनाक उपकरण है और आपको इंजेक्शन के हमलों के लिए बेहद कमजोर बना देगा। blog.highub.com/php/php-core/php-eval-is-evil आपको कुछ जानकारी देनी चाहिए।
१०

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