PHP chaining and getting value

I am currently studying the OOP method method, but I am having difficulty with its operation.

I created a setValue method where it returns a value based on parameters.

Then I created the setLabel method and added a parameter that will be used after calling setValue.

Here is the current code that I have: -

class Field { public $label; public function setValue($property, $value) { $this->$property = new \stdClass(); $this->$property->value = $value; $this->$property->label = $this->label; return $this; } public function setLabel($label) { return $this->label = $label; } } 

Sample code to retrieve data: -

 $field = new Field; $field->setValue('textfield', 'something to print')->setLabel('Label here'); print $field->textfield->value; // Returns the value print $field->textfield->label; // Returns an empty string 

I can’t understand what happened to my code. Please, help.

+5
source share
5 answers

Assuming your goal is as follows:

 print $field->textfield->value; // Returns the value print $field->textfield->label; // Returns the label 

if you want this to work:

 $field = new Field; $field->setValue('textfield', 'something to print')->setLabel('Label here'); 

Then you need to do something like this:

 class FieldProperty { public $label public $value; public setValue($value) { $this->value = $value; return $this; } public setLabel($label) { $this->label = $label; return $this; } } class Field { public function setValue($property, $value) { $this->$property = new FieldProperty(); $this->$property->setValue($value); return $this->$property; } } 

Thinking about this further, we can add:

 class Field { public function setValue($property, $value) { $this->$property = new FieldProperty(); $this->$property->setValue($value); return $this->$property; } public function setProperty($propertyName) { $this->$propertyName = new FieldProperty; return $this->$propertyName; } } 

Now you can do this:

 $field->setProperty('textfield')->setLabel('my label')->setValue('some value'); 
+2
source

If you want to keep the link between $this->$property->label and $this->label , assign a value by reference

 $this->$property->label =& $this->label; 

Demo ~ https://eval.in/955943


Be careful, the link works both ways, so if you assign a new label to $field->textfield->label , it will also change $field->label .

I find it best to use magic methods to automatically create each property. Then you can track them all in a private field and update your tags accordingly.

 class Field { public $label; private $properties = []; // this will store all your dynamic properties public function __get($name) { // lazily create properties on demand if (!isset($this->properties[$name])) { $this->properties[$name] = new \stdclass(); } return $this->properties[$name]; } public function setValue($property, $value) { // this will automatically create "$property" if it not defined $this->$property->value = $value; $this->$property->label = $this->label; return $this; } public function setLabel($label) { // Set the field label and any known property labels $this->label = $label; foreach($this->properties as $property) { $property->label = $label; } return $label; // Β―\_(ツ)_/Β― } } 
0
source

If you want to do this OOP , I think I need to do it as follows. Create the base Field class:

 class Field { public $value; public $label; public function setValue($value) { $this->value = $value; return $this; } public function setLabel($label) { $this->label = $label; return $this; } } 

Perhaps even make it abstract .

Then you can extend this class by creating specific fields:

 final class TextField extends Field { } $textField = (new TextField) ->setValue('something to print') ->setLabel('Label here'); 

Here is a demo .

That way you can use polymorphism later in your program. Let's say you have an object to which you pass a bunch of different objects of type Field (read extend Field ). Then, making its way, this object does not know that each of them has $property , and it will not be able to access value and label - objects do not have a common interface. But with objects that have a common interface (in our case, extend the same base class), we can simply iterate over a bunch of fields and get values ​​and labels.

To display these fields, one (read a bit ugly) solution would be to use the get_class function:

 switch ($class = get_class($field)) { case 'TextField': $this->renderTextField($field); break; case 'InputField': $this->renderInputField($field); break; // ... default: throw new Exception("Cannot render $class."); } 
0
source

You are changing the label property $property ( 'textfield' ) not $this . This means that var_dump($field->textfield->label); contains nothing but var_dump($field->label); .

Saying that you need to keep the name $property so that you can refer to it later. Fast decision:

 <?php class Field { public $label; public $propName; public function setValue($property, $value) { $this->propName = $property; $this->$property = new \stdClass(); $this->$property->value = $value; $this->$property->label = $this->label; return $this; } public function setLabel($label) { $this->{$this->propName}->label = $label; } } $field = new Field; $field->setValue('textfield', 'something to print')->setLabel('Label here'); var_dump($field->textfield->value, $field->textfield->label); 

Live demo

0
source

In your "label" of your code there is a value in the "Object" field, and not in the text field, as you can see:

  Field object { label => (string) Label here textfield => stdClass object { value => (string) something to print label => null } } 

You are using colode $field->label because they are stored in another object, or try the following:

 class Field { public function setValue($value) { $this->property = new \stdClass(); $this->property->value = $value; return $this; } public function setLabel($label) { $this->property->label = $label; return $this->property; } } $field = new Field(); $field->setValue('something to print')->setLabel('Label here'); print $field->property->value; print $field->property->label; 

Output

 something to printLabel here 
-1
source

Source: https://habr.com/ru/post/1275352/


All Articles