Php 方法链接和类继承

Php 方法链接和类继承,php,oop,inheritance,method-chaining,Php,Oop,Inheritance,Method Chaining,我想我已经或多或少地掌握了OOP/继承,以及我认为我也理解的方法链接的基础知识。然而,我仍然对如何实际使用它感到困惑 我想做一些我以前在与Magento合作时见过的事情: 在Magento中,我看到了在方法链接中使用的某种“选择器函数”。这有点难以用语言表达,但大致如下: $categoryName=Mage::getModel('catalog/category')->load($categoryId)->getName(); 这是我感兴趣的load($categoryId)部分,例如,一个

我想我已经或多或少地掌握了OOP/继承,以及我认为我也理解的方法链接的基础知识。然而,我仍然对如何实际使用它感到困惑

我想做一些我以前在与Magento合作时见过的事情: 在Magento中,我看到了在方法链接中使用的某种“选择器函数”。这有点难以用语言表达,但大致如下:

$categoryName=Mage::getModel('catalog/category')->load($categoryId)->getName();
这是我感兴趣的
load($categoryId)
部分,例如,一个函数,它选择某个对象的某个实例,并允许我在该特定实例上运行函数

现在,我正在编写一个模块,允许我在我们的网站上配置某些促销活动。鉴于我们将有许多不同的促销活动,我希望它们能够轻松配置和修改,我想做一些类似的事情

所以,如果我想做这样的事情:

$obj = new Chain();

$obj->fistChain()->secondChain();
$prm=新促销();
$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');
$prm->getPromo('xmasPromo')->setName('Xmas升级!');
$prm->getPromo('nyPromo')->setName('promotionfornewyears!');
echo$prm->getPromo('xmasPromo')->getName();//退货:圣诞节促销!
echo$prm->getPromo('nyPromo')->getName();//回报:新年促销!
这个类的定义应该是什么样的

这可能比我预期的要简单或复杂得多。不管是哪种情况,都非常感谢


编辑: 所以我用deceze给我的信息做了一些测试,但我仍然感到困惑。 命名错误,将两个类放在一个文件中,下面是我所做的:

类文件:

和运行文件:

这给了我一个致命错误:在第11行的/var/www/test/index.php中对非对象调用成员函数setName()。 但是为什么呢?getPromo()不应该把对象还给我吗? 再次感谢


多亏了这里的大人物,现在一切都好了。如果有人带着相同或类似的问题经过这里,这里是最终的工作代码:

课程:

测试文件:


方法链接非常简单,它所做的只是使用PHP语法的一个特定元素:

当函数返回一个对象时,您可以在该函数之后直接继续执行
->

正手版本可以是:

$bar = $foo->bar();
$baz = $bar->baz();
echo $baz;
$foo->bar()
返回一个对象(
$bar
),该对象有一个方法
baz()
,该方法返回一些值(
$baz
)。这可以用速记方式写,如下所示:

echo $foo->bar()->baz();
$foo->bar()
仍然返回一个对象,该对象具有一个方法
baz()
,因此您可以直接调用它,而无需将其分配给中间变量。也许这会让事情变得更加明显:

echo ( $foo->bar() )->baz();
您正在对
$foo->bar()
返回的任何内容调用
baz()
方法

$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');

因此,在上述情况下,您只需从
getPromo
返回一个具有方法
setName
的对象。我假设
getPromo
应该返回
Promo
类的某个对象。如果
Promo
类有一个方法
setName
,那么您已经设置好了。

如果您想链接方法,您只需要始终像这样返回对象

class Chain {
    public function firstChain() {
         //do something
         return $this;
    }

    public function secondChain() {
          //do some stuff

          return $this;
    }

}
当您有一个类的实例时,您可以这样做:

$obj = new Chain();

$obj->fistChain()->secondChain();

调用的方法的可能副本-so方法将返回自身实例。从某种意义上说,这是一种反模式。实际上,我看到的问题是,您应该从
getPromo
方法返回
PROMO
实例,如
return$this->u arr[$name]deceze比你快了一两分钟。你说得很对,当然,我只是太瞎了,看不见我把它忘了你好谢谢你的回答。拥有“Promotion”类和“Promo”类(具有setName和getName方法)很容易。但是如何使“Promotion”类中的addPromo和getPromo函数分别创建或成为Promo对象的适当实例呢?我不知道,这取决于您。当您调用
addPromo
时,
Promotion
类会创建一个新的
Promo
对象(命名不好),并将其以给定的名称存储在内部某处。当您调用
getPromo
时,它将检索该对象。可以像数组一样简单,也可以像数据库查询一样复杂。你到底想在这里做什么是你自己的决定。我感谢我们的帮助。我用数组试过了,但似乎还是不太懂。请参阅原始帖子。可能是因为您没有返回值?!哎呀。我怎么会如此盲目。还忘了在getName中
$this
。现在工作。这回答了我的问题,我真的帮助我理解了这个概念。非常感谢你!
$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
class Chain {
    public function firstChain() {
         //do something
         return $this;
    }

    public function secondChain() {
          //do some stuff

          return $this;
    }

}
$obj = new Chain();

$obj->fistChain()->secondChain();