我正在尝试完成this PHP challenge,并且我目前拥有以下代码:
<?php
/*
Challenge 2: Implement AnswerInterface and get Question to echo "4".
*/
class Question
{
public function __construct(AnswerInterface $answer)
{
echo "What is 2 + 2?\n";
$answer = $answer->get()->the()->answer();
if ($answer instanceof AnswerInterface) {
echo $answer . PHP_EOL;
}
}
}
interface AnswerInterface
{
public function get();
public function the();
public function answer();
}
class Answer implements AnswerInterface
{
public function get()
{
return new Answer();
}
public function the()
{
return new Answer();
}
public function answer()
{
return new Answer();
}
public function __toString()
{
return '4';
}
}
$answer = new Answer;
$question = new Question($answer);
当我运行这样的代码时,它给了我错误:
Fatal error: Allowed memory size of 134217728 bytes exhausted
我可以通过在代码中插入以下内容来纠正错误:
public function __construct() {}
我不完全了解它是如何工作的...我想了解这里发生了什么。非常感谢您提供任何帮助,以解释其工作原理。
答案 0 :(得分:6)
在PHP拥有__construct
之前,您将通过命名与该类同名的方法来创建构造函数。它仍然受支持,但是在PHP 7中已弃用。这意味着,如果您的Answer
类没有现代构造函数(__construct
),则answer
方法将被称为构造函数。由于它返回new Answer
,因此将在新对象上一次又一次地调用构造函数。您有无限的递归,一旦内存耗尽,就会引发错误。
我只能猜测此练习的原因是什么。但是您也可以只在$this
,get
和the
中返回answer
。如果您希望您的类支持“链接”,那通常就是您要做的。当然,在现实世界中,这些方法还会做其他事情。
答案 1 :(得分:2)
基本上您有正确的思维方式,但是问题是您不需要在所有方法中都创建新实例,您需要的只是返回对象的当前实例,因为您已经创建了对象Answer并将其传递给问题对象,因此正确的代码应如下所示:
class Answer implements AnswerInterface
{
public function get()
{
return $this;
}
public function the()
{
return $this;
}
public function answer()
{
return $this;
}
public function __toString()
{
return "4";
}
}
您还可能想在PHP: The Basics
上了解有关$ this关键字的信息如果您在PHP 5.3.3之后不使用命名空间,则方法answer()也将被视为类Answer的构造函数方法(无论是小写还是大写)(或者如果您有,则将其视为构造函数) PHP 5.3.0-5.3.2)。因此,在您的情况下,尝试在已实现的方法中调用新的Answer()时也会遇到无限循环。