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;