我正在制作一个模板系统,我使用foreach循环实例化每个标签。问题是一些标签相互依赖,所以我想知道如何绕过循环中的那个排序。
以下是一个例子:
Class A {
public $width;
__construct() {
$this->width = $B->width; // Undefined! Or atleast not set yet..
}
}
Class B {
public $width;
__construct() {
$this->width = "500px";
}
__tostring() {
return "Hello World!";
}
}
的template.php
$tags = array("A", "B");
foreach ($tags as $tag) {
$TagObj[$tag] = new $tag();
}
echo $TagObj['A']->width; // Nadamundo!
编辑:好的只是为了澄清.. 我的主要问题是A类依赖于B类,但A类在B类之前被实例化,因此宽度尚未定义在B类中。我正在寻找一种好的方法来确保为每个人加载所有类,从而允许存在相互依赖性。对于将来,请不要考虑任何语法错误..我只是当场编写了这个例子。还假设在B类实例化后我可以从A类访问B类。
我知道这在其他地方也有应用,我确信之前已经解决了这个问题,如果有人能够启发我,或者指出我的方向很好,那就太棒了!
谢谢! 马特穆勒
答案 0 :(得分:1)
最简单的方法可能是通过对标记对象数组进行第二次传递,一旦它们全部被实例化,并在每个标记对象上调用一些标准方法(参见模板方法模式,例如http://java.dzone.com/articles/design-patterns-template-method)
$tags = array("A", "B");
foreach ($tags as $tag) {
$TagObj[$tag] = new $tag();
}
foreach (array_keys($TagObj) as $tagName) {
$TagObj[$tagName]->resolveDependencies($TagObj);
}
如何实现resolveDependencies会因类而异。
答案 1 :(得分:1)
A :: construct()中的这个$ B实例来自哪里?它不在范围内。
可能的解决方案:
1)静态值:
class B {
static $width = '500px';
...
class A {
function construct(){
$this->width = B::$width;
}
2)静态功能:
class B {
static function width(){
return '500px';
...
class A {
function construct(){
$this->width = B::width();
}
3)及时工厂方法(如果需要,可以是对象),如果需要对象
function getTag($name){
global $TagObj;
if(!isset($TagObj[$name]) && class_exists($name)){
$TagObj[$name] = new $name();
}
return $TagObj[$name];
}
class A {
function construct(){
$this->width = getTag('B')->width();
}
....
$tags = array("A", "B");
foreach ($tags as $tag) {
$TagObj[$tag] = getTag($tag);
}
如果您希望B中的更改反映在A中,您可以始终使用引用而不是分配。所有这些当然要求类定义可用,如果没有,则定义__autoload(),或者事先包含它们。
答案 2 :(得分:0)
您在width()
类B
中调用的A
类中缺少$this->width = $B->width();
方法(并且您应该包含或使用继承来使用B类)一类)
Class B {
private $width;
__construct() {
$this->width = "500px";
}
__tostring() {
return "Hello World!";
}
function width() {
return $this->width;
}
}
至于订购,你应该更具体。