दिलचस्प पोस्ट
सर्वर PHP से फ़ाइलें डाउनलोड करें एक ListBox के साथ WPF ListBox – यूआई वर्चुअलाइजेशन और स्क्रॉलिंग एकाधिक बटन प्रेस के साथ ध्वनि ओवरलैपिंग ऑब्जेक्ट स्लाइसिंग क्या है? अजगर का उपयोग कर स्ट्रिंग से एक चरित्र को कैसे हटाया जाए? गिट: तेजी से उपेक्षा करने और मूल को पूर्व में वापस करने के लिए कैसे? मैं मूल्य से एक शब्दकोश कैसे सॉर्ट कर सकता हूं? JQuery के उपयोग से एचटीएमएल संस्थाओं को व्याख्या कैसे करें? प्रोग्रामिंग पहेली: आप किसी संख्या में Excel कॉलम नाम का अनुवाद कैसे कर सकते हैं? असाइनमेंट स्टेटमेंट क्यों एक मान लौटाते हैं? MySQL में खंड द्वारा संघ और व्यवस्था का उपयोग करना पृष्ठभूमि छवि के साथ JTextArea के लिए आंतरिक पैडिंग Android में उपयोगकर्ता के स्थान को प्राप्त करने का अच्छा तरीका जावा प्रतिबिंब: क्या कक्षा के क्षेत्र और विधियों का मानदंड मानकीकृत है? क्या हेड, बॉडी और एचटीएमएल टैग लिखना आवश्यक है?

क्या आप गतिशील रूप से PHP में उदाहरण गुण बना सकते हैं?

क्या सभी इंस्टेंस गुणों को गतिशील बनाने का कोई तरीका है? उदाहरण के लिए, मैं कन्स्ट्रक्टर में सभी विशेषताओं को उत्पन्न करने में सक्षम होना चाहूंगा और अभी भी इस तरह से इस प्रकार की शुरुआत के बाद उन तक पहुंचने में सक्षम हो: $object->property ध्यान दें कि मैं अलग से गुणों का उपयोग करना चाहता हूं, और किसी सरणी का उपयोग नहीं करना चाहता हूं; यहां एक उदाहरण है जो मुझे नहीं चाहिए:

 class Thing { public $properties; function __construct(array $props=array()) { $this->properties = $props; } } $foo = new Thing(array('bar' => 'baz'); # I don't want to have to do this: $foo->properties['bar']; # I want to do this: //$foo->bar; 

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

वेब के समाधान से एकत्रित समाधान "क्या आप गतिशील रूप से PHP में उदाहरण गुण बना सकते हैं?"

की तरह। जादू पद्धतियां हैं जो आपको रनटाइम पर क्लास व्यवहार को कार्यान्वित करने के लिए अपने कोड को हुक करने की अनुमति देती हैं:

 class foo { public function __get($name) { return('dynamic!'); } public function __set($name, $value) { $this->internalData[$name] = $value; } } 

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

 print(new foo()->someProperty); 

मुद्रित होगा, इस मामले में, "गतिशील!" और आप एक मनमाने ढंग से नामित संपत्ति के लिए एक मूल्य भी निर्दिष्ट कर सकते हैं, जिस स्थिति में __set () विधि चुपचाप लागू होती है। __call ($ name, $ params) विधि ऑब्जेक्ट विधि कॉल के लिए समान है विशेष मामलों में बहुत उपयोगी लेकिन ज्यादातर समय, आप इसके साथ मिलेंगे:

 class foo { public function __construct() { foreach(getSomeDataArray() as $k => $value) $this->{$k} = $value; } } 

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

इसे ओवरलोडिंग कहा जाता है http://php.net/manual/en/language.oop5.overloading.php

यह बिल्कुल वही निर्भर करता है जो आप चाहते हैं क्या आप गतिशील रूप से कक्षा को संशोधित कर सकते हैं? ज़रुरी नहीं। लेकिन क्या आप उस गुण के एक विशेष उदाहरण के रूप में गतिशील रूप से वस्तु गुण बना सकते हैं? हाँ।

 class Test { public function __construct($x) { $this->{$x} = "dynamic"; } } $a = new Test("bar"); print $a->bar; 

आउटपुट:

गतिशील

इसलिए कंस्ट्रक्टर में "बार" नामक ऑब्जेक्ट प्रॉपर्टी गतिशील रूप से बनाई गई थी।

हाँ तुम कर सकते हो।

 class test { public function __construct() { $arr = array ( 'column1', 'column2', 'column3' ); foreach ($arr as $key => $value) { $this->$value = ''; } } public function __set($key, $value) { $this->$key = $value; } public function __get($value) { return 'This is __get magic '.$value; } } $test = new test; // Results from our constructor test. var_dump($test); // Using __set $test->new = 'variable'; var_dump($test); // Using __get print $test->hello; 

उत्पादन

 object(test)#1 (3) { ["column1"]=> string(0) "" ["column2"]=> string(0) "" ["column3"]=> string(0) "" } object(test)#1 (4) { ["column1"]=> string(0) "" ["column2"]=> string(0) "" ["column3"]=> string(0) "" ["new"]=> string(8) "variable" } This is __get magic hello 

यह कोड निर्माता में गतिशील गुण स्थापित करेगा जो कि तब $ $ -> कॉलम के साथ पहुंचा जा सकता है। क्लास के भीतर परिभाषित नहीं होने वाले गुणों से निपटने के लिए __get और __set जादू पद्धतियों का उपयोग करने के लिए भी यह अच्छा अभ्यास है। अधिक जानकारी उन्हें यहां पाया जा सकता है

http://www.tuxradar.com/practicalphp/6/14/2

http://www.tuxradar.com/practicalphp/6/14/3

आप एक आवृत्ति चर का उपयोग मनमाने मान के लिए धारक के रूप में कर सकते हैं और फिर नियमित गुणों के रूप में उन्हें पुनः प्राप्त करने के लिए __get जादू विधि का उपयोग कर सकते हैं:

 class My_Class { private $_properties = array(); public function __construct(Array $hash) { $this->_properties = $hash; } public function __get($name) { if (array_key_exists($name, $this->_properties)) { return $this->_properties[$name]; } return null; } } 

हर उदाहरण इतना जटिल क्यों है?

 <?php namespace example; error_reporting(E_ALL | E_STRICT); class Foo { // class completely empty } $testcase = new Foo(); $testcase->example = 'Dynamic property'; echo $testcase->example; 

वर्ग के सदस्यों को सार्वजनिक किए बिना वस्तु सदस्यों को आबाद करने के लिए यहां सरल कार्य है यह कंसट्रक्टर को अपने स्वयं के उपयोग के लिए छोड़ देता है, कन्स्ट्रक्टर बनाने के बिना ऑब्जेक्ट का नया इंस्टेंस बना रहा है! इसलिए, आपका डोमेन ऑब्जेक्ट डेटाबेस पर निर्भर नहीं है!


 /** * Create new instance of a specified class and populate it with given data. * * @param string $className * @param array $data eg array(columnName => value, ..) * @param array $mappings Map column name to class field name, eg array(columnName => fieldName) * @return object Populated instance of $className */ function createEntity($className, array $data, $mappings = array()) { $reflClass = new ReflectionClass($className); // Creates a new instance of a given class, without invoking the constructor. $entity = unserialize(sprintf('O:%d:"%s":0:{}', strlen($className), $className)); foreach ($data as $column => $value) { // translate column name to an entity field name $field = isset($mappings[$column]) ? $mappings[$column] : $column; if ($reflClass->hasProperty($field)) { $reflProp = $reflClass->getProperty($field); $reflProp->setAccessible(true); $reflProp->setValue($entity, $value); } } return $entity; } /******** And here is example ********/ /** * Your domain class without any database specific code! */ class Employee { // Class members are not accessible for outside world protected $id; protected $name; protected $email; // Constructor will not be called by createEntity, it yours! public function __construct($name, $email) { $this->name = $name; $this->emai = $email; } public function getId() { return $this->id; } public function getName() { return $this->name; } public function getEmail() { return $this->email; } } $row = array('employee_id' => '1', 'name' => 'John Galt', 'email' => 'john.galt@whoisjohngalt.com'); $mappings = array('employee_id' => 'id'); // Employee has id field, so we add translation for it $john = createEntity('Employee', $row, $mappings); print $john->getName(); // John Galt print $john->getEmail(); // john.galt@whoisjohngalt.com //... 

PS ऑब्जेक्ट से डेटा पुनर्प्राप्त करना समान है, जैसे $ reflProp-> setValue ($ इकाई, $ मान) का उपयोग करें; पीपीएस इस फंक्शन को डॉकट्रिन 2 ओआरएम से बहुत प्रेरित किया गया है जो कमाल है!

 class DataStore // Automatically extends stdClass { public function __construct($Data) // $Data can be array or stdClass { foreach($Data AS $key => $value) { $this->$key = $value; } } } $arr = array('year_start' => 1995, 'year_end' => 2003); $ds = new DataStore($arr); $gap = $ds->year_end - $ds->year_start; echo "Year gap = " . $gap; // Outputs 8 

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

 $variable = 'foo'; $this->$variable = 'bar'; 

ऑब्जेक्ट की विशेषता foo जिसे bar कहा जाता है।

आप फ़ंक्शन भी उपयोग कर सकते हैं:

 $this->{strtolower('FOO')} = 'bar'; 

यह भी foo (नहीं FOO ) bar को सेट करेगा

स्टड क्लास बढ़ाएं

 class MyClass extends stdClass { public function __construct() { $this->prop=1; } } 

मुझे आशा है कि आप यही चाहते हैं।

इस तरह के तेजी से विकास को संभालने के लिए यह वास्तव में जटिल तरीका है मुझे जवाब और जादू के तरीकों की तरह है लेकिन मेरी राय में कोडएस्मिथ जैसी कोड जनरेटर का इस्तेमाल करना बेहतर है।

मैंने टेम्प्लेट बनाया है जो डेटाबेस से जुड़ता है, सभी कॉलम और उनके डेटा प्रकारों को पढ़ता है और तदनुसार पूरे वर्ग उत्पन्न करता है।

इस तरह मुझे त्रुटि मुक्त (कोई typos) पठनीय कोड नहीं है और अगर आपका डेटाबेस मॉडल फिर से जनरेटर चलाता है … यह मेरे लिए काम करता है

यदि आप वाकई सचमुच इसे करना चाहते हैं, तो सबसे अच्छा तरीका है एक अर्रेऑब्जेक्ट को अधिभार देना, जो कि आपके सभी गुणों के माध्यम से फिर से चलना (foreach) बनाए रखने की अनुमति देता है

मुझे लगता है कि आपने कहा है कि "किसी सरणी का उपयोग किए बिना", और मैं आपको यह आश्वासन देना चाहता हूं कि जब तकनीकी रूप से पृष्ठभूमि में एक सरणी का इस्तेमाल किया जा रहा है, तो आपको यह देखने की ज़रूरत नहीं है। आप सभी गुणों के माध्यम से -> properyname या foreach ($ नाम $ $ => $ value) तक पहुंच सकते हैं।

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

आप उस पाठ्यक्रम को हटा सकते हैं

एक AddProperty () सदस्य समारोह भी है, हालांकि यह उदाहरण में प्रदर्शित नहीं किया गया है। यह आपको बाद में संपत्तियों को जोड़ने की अनुमति देगा

नमूना उपयोग:

  $Action = new StronglyTypedDynamicObject("Action", new StrongProperty("Player", "ActionPlayer"), // ActionPlayer new StrongProperty("pos", "integer"), new StrongProperty("type", "integer"), new StrongProperty("amount", "double"), new StrongProperty("toCall", "double")); $ActionPlayer = new StronglyTypedDynamicObject("ActionPlayer", new StrongProperty("Seat", "integer"), new StrongProperty("BankRoll", "double"), new StrongProperty("Name", "string")); $ActionPlayer->Seat = 1; $ActionPlayer->Name = "Doctor Phil"; $Action->pos = 2; $Action->type = 1; $Action->amount = 7.0; $Action->Player = $ActionPlayer; $newAction = $Action->factory(); $newAction->pos = 4; print_r($Action); print_r($newAction); class StrongProperty { var $value; var $type; function __construct($name, $type) { $this->name = $name; $this->type = $type; } } class StronglyTypedDynamicObject extends ModifiedStrictArrayObject { static $basic_types = array( "boolean", "integer", "double", "string", "array", "object", "resource", ); var $properties = array( "__objectName" => "string" ); function __construct($objectName /*, [ new StrongProperty("name", "string"), [ new StrongProperty("name", "string"), [ ... ]]] */) { $this->__objectName = $objectName; $args = func_get_args(); array_shift($args); foreach ($args as $arg) { if ($arg instanceof StrongProperty) { $this->AddProperty($arg->name, $arg->type); } else { throw new Exception("Invalid Argument"); } } } function factory() { $new = clone $this; foreach ($new as $key => $value) { if ($key != "__objectName") { unset($new[$key]); } } // $new->__objectName = $this->__objectName; return $new; } function AddProperty($name, $type) { $this->properties[$name] = $type; return; if (in_array($short_type, self::$basic_types)) { $this->properties[$name] = $type; } else { throw new Exception("Invalid Type: $type"); } } public function __set($name, $value) { self::sdprintf("%s(%s)\n", __FUNCTION__, $name); $this->check($name, $value); $this->offsetSet($name, $value); } public function __get($name) { self::sdprintf("%s(%s)\n", __FUNCTION__, $name); $this->check($name); return $this->offsetGet($name); } protected function check($name, $value = "r4nd0m") { if (!array_key_exists($name, $this->properties)) { throw new Exception("Attempt to access non-existent property '$name'"); } $value__objectName = ""; if ($value != "r4nd0m") { if ($value instanceof StronglyTypedDynamicObject) { $value__objectName = $value->__objectName; } if (gettype($value) != $this->properties[$name] && $value__objectName != $this->properties[$name]) { throw new Exception("Attempt to set {$name} ({$this->properties[$name]}) with type " . gettype($value) . ".$value__objectName"); } } } } class ModifiedStrictArrayObject extends ArrayObject { static $debugLevel = 0; /* Some example properties */ static public function StaticDebug($message) { if (static::$debugLevel > 1) { fprintf(STDERR, "%s\n", trim($message)); } } static public function sdprintf() { $args = func_get_args(); $string = call_user_func_array("sprintf", $args); self::StaticDebug("D " . trim($string)); } protected function check($name) { if (!array_key_exists($name, $this->properties)) { throw new Exception("Attempt to access non-existent property '$name'"); } } //static public function sget($name, $default = NULL) { /******/ public function get ($name, $default = NULL) { self::sdprintf("%s(%s)\n", __FUNCTION__, $name); $this->check($name); if (array_key_exists($name, $this->storage)) { return $this->storage[$name]; } return $default; } public function offsetGet($name) { self::sdprintf("%s(%s)\n", __FUNCTION__, implode(",", func_get_args())); $this->check($name); return call_user_func_array(array(parent, __FUNCTION__), func_get_args()); } public function offsetSet($name, $value) { self::sdprintf("%s(%s)\n", __FUNCTION__, implode(",", func_get_args())); $this->check($name); return call_user_func_array(array(parent, __FUNCTION__), func_get_args()); } public function offsetExists($name) { self::sdprintf("%s(%s)\n", __FUNCTION__, implode(",", func_get_args())); $this->check($name); return call_user_func_array(array(parent, __FUNCTION__), func_get_args()); } public function offsetUnset($name) { self::sdprintf("%s(%s)\n", __FUNCTION__, implode(",", func_get_args())); $this->check($name); return call_user_func_array(array(parent, __FUNCTION__), func_get_args()); } public function __toString() { self::sdprintf("%s(%s)\n", __FUNCTION__, $name); foreach ($this as $key => $value) { $output .= "$key: $value\n"; } return $output; } function __construct($array = false, $flags = 0, $iterator_class = "ArrayIterator") { self::sdprintf("%s(%s)\n", __FUNCTION__, implode(",", func_get_args())); parent::setFlags(parent::ARRAY_AS_PROPS); } } 

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

 class DBModelConfig { public $host; public $username; public $password; public $db; public $port = '3306'; public $charset = 'utf8'; public $collation = 'utf8_unicode_ci'; public function __construct($config) { foreach ($config as $key => $value) { if (property_exists($this, $key)) { $this->{$key} = $value; } } } } 

तब आप जैसे सरणियों को पारित कर सकते हैं:

 [ 'host' => 'localhost', 'driver' => 'mysql', 'username' => 'myuser', 'password' => '1234', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'db' => 'key not used in receiving class' ]