如何在当前类中使用另一个类的函数


How to use a function of another class in the current class

我在adminitems.class.php中有一个名为adminItems的类。我正在尝试将此类的功能之一包含在xmlParser.class.php中的xmlParser::someName()中。

喜欢这个:

require_once("adminitems.class.php");
$obj = new adminitems();
class xmlParser
{
    function someName()
    {
        $obj->addAds(); // addAds is within adminItems object
    }
}
`

这是一种正确的做法吗?

不要仅仅为了获得额外的功能而使用扩展。这是一种代码气味,暗示xmlParser是 - 一个显然不是的adminItems。此外,您将来无法再次扩展,因为 PHP 没有多重继承。选择组合而不是继承,如以下示例所示。

使用依赖关系注入。反转对象的控制,使它们不相互依赖:请参阅控制反转。

class xmlParser
{
    /**
     * @var adminItems
     */
    protected $adminItems;
    /**
     * @constructor
     * 
     * @param adminItems $adminItems
     */
    public function __construct(adminItems $adminItems)
    {
        $this->adminItems = $adminItems;
    }
    /**
     * Whatever this does...
     */
    function someName()
    {
        $this->adminItems->addAds();
    }
}
`

您需要在您创建的类之外,像这样将它们连接在一起。您将adminItems传递xmlParser中,然后根据需要使用它。这称为依赖注入,您可以在所有面向对象的语言中执行,而不仅仅是 php。

您将像这样使用上面的对象 API:

$adminItems = new adminItems;
$xmlParser  = new xmlParser($adminItems);
$xmlParser->somName();

真的很简单。您的对象(将它们视为可重用的库(不应依赖于其他对象,除非通过构造函数或方法注入 - 因此您可以替换它们,从而生成可测试且本质上干净的代码。

另外,我敦促您查看以下有用的链接:

  • 用于命名约定的 PSR-2:
    • 使用XmlParser而不是xmlParser作为类名
  • 用于自动加载的 PSR-4:
    • 了解如何使用作曲家为您生成自动加载文件
    • 了解文件如何与目录结构进行 1:1 映射
    • 了解如何在项目中只需使用一次包含

如果一个类B需要类A的函数,你在PHP中有很多解决方案:

1. 继承

使用类B扩展类A。类B将能够访问类A的公共和受保护方法。

class B extends A {
}

我不推荐这个。在 OOP 中,仅使用继承来使用具有不同职责的类的一个函数是一种非常糟糕的做法。

2. 特质

使用特征(从 PHP5.4.0 开始(:

trait factoredMethods {
    function getX() { /*...*/ }
    function setY() { /*...*/ }
}
class A {
    use factoredMethods;
}
class B {
    use factoredMethods;
}

在某些情况下,这可能是一个有趣的解决方案,但它通常是对不良概念的补丁。

3. 组成

最好的选择是使用合成。 B用途A

class A {
}
class B {
    private $a;
    public function __construct(A $a) {
        $this->a = $a;
    }
}
$a = new A();
$b = new B($a);

当然,您要在A中使用的方法必须是公开的。我强烈建议在AB之间使用接口,以便具有低耦合。

几乎是正确的方法 - 但$obj不在范围内。一个丑陋的解决方案是在全球范围内关注它......

require_once("adminitems.class.php");
global $obj;
$obj = new adminitems();
class xmlParser
{
function someName()
{
   global $obj;
   $obj->addAds();
}

您可以使用命名空间来优化此方法,但正确的答案可能是将引用传递到范围内,例如

function someName($obj)
{
   $obj->addAds();
}

您可以通过扩展父类来使用其他类函数

class xmlParser extends adminitems{ 
    function someName(){ 
       $obj->addAds(); 
 } 
}