Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP多个_utoString方法,在运行时切换_Php_Tostring - Fatal编程技术网

PHP多个_utoString方法,在运行时切换

PHP多个_utoString方法,在运行时切换,php,tostring,Php,Tostring,对于同一个类,我需要不同的\uuu toString() 实例 我有一个Person类,它包含名字和姓氏。根据当前上下文,我希望以不同的顺序、格式等显示它。想象三种场景: 名字排在第一位,然后是空格和姓氏Thomas Müller 姓氏排在第一位,大写,然后是空格和名字MÜLLER Thomas 姓氏排在第一位,后面是逗号,然后是空格和名字Müller,Thomas 我可以为每个显示创建公共方法 <meta charset='utf-8'/> <?php class Per

对于同一个类,我需要不同的
\uuu toString()

实例 我有一个Person类,它包含名字和姓氏。根据当前上下文,我希望以不同的顺序、格式等显示它。想象三种场景:

  • 名字排在第一位,然后是空格和姓氏
    Thomas Müller
  • 姓氏排在第一位,大写,然后是空格和名字
    MÜLLER Thomas
  • 姓氏排在第一位,后面是逗号,然后是空格和名字
    Müller,Thomas
我可以为每个显示创建公共方法

<meta charset='utf-8'/>
<?php
class Person
{
  protected $firstname;
  protected $surname;

  public function __construct($firstname, $surname)
  {
    $this->firstname = $firstname;
    $this->surname = $surname;
  }

  public function toStringWithFirstnameFirst()
  {
    return $this->firstname . " " . $this->surname;
  }

  public function toStringWithSurnameFirstUppercase()
  {
    $surnameConverted = mb_convert_case($this->surname, MB_CASE_UPPER, "UTF-8");
    return $surnameConverted . " " . $this->firstname;
  }

  public function toStringWithSurnameFirstAndFirstnameAfterComma()
  {
    return $this->surname . ", " . $this->firstname;
  }
}

$person = new Person("Thomas", "Müller");
echo $person->toStringWithFirstnameFirst() . "<br/>";
echo $person->toStringWithSurnameFirstUppercase() . "<br/>";
echo $person->toStringWithSurnameFirstAndFirstnameAfterComma() . "<br/>";
?>
我看到了这种解决方案的一些缺点:

  • 上课越来越重
  • switch case
    语句可以隐藏一些错误

我希望
Person
类只包含自己的功能,而不是所有类型的toString。我希望有一些模式可以动态注入
\uuuToString()

好吧,我想你问这个问题的原因是,你想保持事情的整洁,但是没有办法将uuToString()方法设置为现有对象,所以最好的解决方案是拆分功能

首先创建PersonRender:

class PersonRender 
{
    const PRINT_FIRSTNAME_FIRST = 1;
    const PRINT_SURNAME_FIRST_UPPERCASE = 2;
    const PRINT_SURNAME_FIRST_FIRSTNAME_AFTER_COMMA = 3;

    static public $chosenToStringMethod;

    private $person;

    public function __construct($person) 
    {
        $this->person = $person;
    }

    public function render() 
    {
        switch (self::$chosenToStringMethod) 
        {
            case self::PRINT_SURNAME_FIRST_UPPERCASE :
                return $this->toStringWithSurnameFirstUppercase();
            case self::PRINT_SURNAME_FIRST_FIRSTNAME_AFTER_COMMA :
                return $this->toStringWithSurnameFirstAndFirstnameAfterComma();
            default :
                return $this->toStringWithFirstnameFirst();
        }
    }

    private function toStringWithFirstnameFirst()
    {
        return "{$this->person->firstname} {$this->person->surname}";
    }

    private function toStringWithSurnameFirstUppercase()
    {
        $surnameConverted = mb_convert_case($this->person->surname, MB_CASE_UPPER, "UTF-8");
        return "{$surnameConverted} {$this->person->firstname}";
    }

    private function toStringWithSurnameFirstAndFirstnameAfterComma()
    {
        return "{$this->person->surname}, {$this->person->firstname}";
    }

}
然后是Person类:

class Person 
{

    public $firstname, $surname;

    public function __construct($firstname, $surname) 
    {
        $this->firstname = $firstname;
        $this->surname = $surname;
    }

    public function __toString() {
        $render = new PersonRender($this);
        return $render->render();
    }
}
还有一个小测试:

$person = new Person('Foo', 'Bar');
echo $person;
echo '<hr />';
PersonRender::$chosenToStringMethod = PersonRender::PRINT_SURNAME_FIRST_UPPERCASE;
echo $person;
$person=新人('Foo','Bar');
回声$人;
回声“
”; PersonRender::$chosenToStringMethod=PersonRender::打印姓氏首字母大写; 回声$人;
编辑1
为了保持代码干净,Person实体类当然应该设置私有道具firstname和surename以及方法,并获取它们。在我看来,最干净的方法就是为firstname和姓氏提供getter,并在需要的地方手动组装字符串。在您当前的解决方案中,您只是用不必要的类污染了您的工作区,使类
Person
变得比它应该的更复杂。

那么,您在哪里以及如何决定输出哪种格式?这能从一行变到下一行吗?那么,为它设置全局配置是没有意义的。怎么样
echo$person->name(person::FORMAL)
;i、 e.通过一系列预定义的可能格式传递参数?我不确定您在这里期望什么;你的第一个缺点似乎是不可避免的,我不明白你说的第二个缺点是什么意思。如果有某种方法可以“动态注入
\uuuu-toString
”,那么该方法的代码将存在于某个地方。而且一个
switch
语句似乎不比任何其他实现更可能隐藏错误。或者有一个专用的、可配置的呈现程序。这似乎是开销,但从长远来看,它使事情变得容易。
$person = new Person('Foo', 'Bar');
echo $person;
echo '<hr />';
PersonRender::$chosenToStringMethod = PersonRender::PRINT_SURNAME_FIRST_UPPERCASE;
echo $person;