PHP方法链接设置并获取值

时间:2018-02-14 02:14:28

标签: php oop

我目前正在学习OOP Method Chaining,但我在使其工作方面遇到了困难。

我创建了setValue方法,它根据参数返回一个值。

然后,我创建了setLabel方法并添加了一个参数,在调用setValue之后使用。

这是我目前的代码: -

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;
  }
}

检索数据的示例代码: -

$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

我无法弄清楚我的代码有什么问题。请帮忙。

5 个答案:

答案 0 :(得分:2)

假设您的目标如下:

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

如果你想要这个:

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

然后你需要做这样的事情:

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;
    }
}

进一步思考,我们可以补充:

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;
    }
}

现在你可以这样做:

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

答案 1 :(得分:0)

如果您想在$this->$property->label$this->label之间保持引用,assign the value by reference

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

演示〜https://eval.in/955943

请注意,该引用有两种方式,因此如果您为$field->textfield->label分配新标签,它也会更改$field->label

我觉得更好的方法是使用魔术方法自动创建每个属性。然后,您可以在私有字段中跟踪所有内容并相应地更新其标签。

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's 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; // ¯\_(ツ)_/¯
  }
}

答案 2 :(得分:0)

如果你想OOP方式,我想,我需要像下面这样做。创建基础Field类:

class Field
{
    public $value;
    public $label;

    public function setValue($value)
    {
        $this->value = $value;

        return $this;
    }

    public function setLabel($label)
    {
        $this->label = $label;

        return $this;
    }
}

也许,即使是abstract

然后你可以扩展这个类,创建特定的字段:

final class TextField extends Field
{

}

$textField = (new TextField)
    ->setValue('something to print')
    ->setLabel('Label here');

这是the demo

这样,您可以稍后在程序中使用polymorphism。假设你有一个对象,你传递了一堆Field类型的不同对象(read extend Field)。然后按照自己的方式操作,此对象无法知道每个$property具有哪些内容,并且无法访问valuelabel - #39; t共享公共接口。但是,对于共享公共接口的对象(在我们的示例中扩展相同的基类),我们可以简单地遍历一堆字段并检索值和标签。

为了渲染这个字段,一个(读得有点难看)的解决方案是利用get_class函数:

switch ($class = get_class($field)) {
    case 'TextField':
        $this->renderTextField($field);
        break;
    case 'InputField':
        $this->renderInputField($field);
        break;

    // ...

    default:
        throw new Exception("Cannot render $class.");
}

答案 3 :(得分:0)

您正在更改label$property)的'textfield'属性,而不是$this。这意味着var_dump($field->textfield->label);除了var_dump($field->label);之外不包含任何内容。

说你需要存储$property的名字,以便以后你可以参考它。一个快速工作的解决方案是:

<?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

答案 4 :(得分:-1)

在您的代码&#34;标签&#34;将值赋入Field Object,而不是textfield对象,如您所见:

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

你使用$field->label,因为它们存储在不同的对象中,或者试试这个:

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;

输出

something to printLabel here
相关问题