调用php中类中创建的类的函数

时间:2012-02-17 18:06:11

标签: php oop

这是3个文件和类的

中所有很好地布局的代码布局大纲
$aa = new className();
class className {
    /**
    * Constructor
    */
    function className() {
        $this->init_SubClass();
    }

    function init_SubClass() {
        require_once('sub_class.class.php');
        $sub_class = new sub_class();
    }
}

sub_class.class.php

   class sub_class {
    /**
    * Constructor
    */
    function sub_class() {
        $this->init_Sub_Sub_Class();
    }

    function init_Sub_Sub_Class() {
        require_once('Sub_Sub_Class.class.php');
        $Sub_Sub_Class = new Sub_Sub_Class();
    }
}

sub_sub_class.class.php

class Sub_Sub_Class {
    public function function_I_to_call() {
        echo ' show this text'
    }
}

如何调用function_I_to_call()

到目前为止这是最好的猜测

$aa->className->sub_class->function_I_to_call()

不确定如何执行此操作或是否可以执行此操作。

非常感谢

1 个答案:

答案 0 :(得分:5)

您没有将新创建的对象分配给实例。你需要使用

$this->sub_class = new Subclass;

这将使他们成为public属性,然后您可以使用

$aa = new className;
$aa->sub_class->function_I_to_call();

但是,整个方法都存在缺陷:

替代方法

class Foo
{
    protected $bar;
    public function __construct(Bar $bar)
    {
        $this->bar = $bar;
    }
    public function getBar()
    {
        return $this->bar;
    }
}

然后Bar

class Bar
{
    protected $baz;
    public function __construct(Baz $baz)
    {
        $this->baz = $baz;
    }
    public function getBaz()
    {
        return $this->baz;
    }
}    

Baz

class Baz
{
    public function fn()
    {
        return 'called';
    }
}

然后通过以下方式组装:

$foo = new Foo(new Bar(new Baz));

或将该代码移至工厂:

class FooFactory
{
    public function create()
    {
        return new Foo(new Bar(new Baz));
    }
}

最后,Autoloader(简化):

spl_autoload_register(function($className) {
    $classMap = array(
        'Foo' => '/path/to/Foo.php',
        'Bar' => '/path/to/Bar.php',
        'Baz' => '/path/to/Baz.php',
    );
    require $classMap[$className];
});

然后你可以调用(demo

$fooFactory = new FooFactory;
$foo = $fooFactory->create();
echo $foo->getBar()->getBaz()->fn();

但你不应该(除非它是某种DSL),因为这违反了Law of Demeter,因为你正在深入挖掘合作者。