PHP:从另一个对象调用对象方法的最佳方法?

时间:2013-05-28 16:43:19

标签: php oop

我正在寻找从另一个类调用类方法的最佳方法,而不必使用Global来获取类实例,因为我现在理解“全局是邪恶的”!

以下是一些代码来解释它:

class Assets{
 public $assets = array();
 public function add($asset){
  $this->assets[] = $asset;
 }
}

现在我想在这里调用Assets / call方法..

$assets = new Assets;
class Form{
 public function __construct(){
  global $assets;
  $assets->add('Form');
 }
}

在这种情况下使用Global是不是很糟糕?如果是这样,其他什么方式被认为是最好的?

PS:我只需要使用该类的一个实例;意味着我不想在第二个类中创建一个新实例。

6 个答案:

答案 0 :(得分:7)

如果您只想拥有1个资产实例,则需要使用某种形式的依赖注入。

在这种情况下最明显的是将它传递给构造函数:

class Form{
 public function __construct(Assets $assets){
  $assets->add('Form');
 }
}

使用全局变量 确实是一个坏主意。

答案 1 :(得分:2)

如果资产在您的上下文中有意义,您也可以将资产设为singleton

class Assets
{
    /////////////////////
    // Your stuff      //
    /////////////////////

    private $assets = array();
    public function add($asset)
    {
        $this->assets[] = $asset;
    }

    /////////////////////
    // Singleton stuff //
    /////////////////////

    static private $instance = null;
    static public function getInstance()
    {
        if(self::$instance == null)
            self::$instance = new self;
        return self::$instance;
    }

    // To restrict construction of this class outside of this class definition
    private function __construct() {}

    // To restrict cloning of this class outside of this class definition
    private function __clone() {}
}

在你的其他代码中,你会使用这样的单身:

class Form
{
    public function __construct()
    {
        Assets::getInstance()->add('Form');
    }
}

答案 2 :(得分:1)

你可以试试这个,

class Form{
 public function __construct(Assets $assets){
  //$assets = new Assets;
  $assets->add('Form');
 }
}

答案 3 :(得分:1)

我没有直接用提供的元素回答这个问题,我只是展示了一种在不使用全局变量的情况下在对象之间共享数据的方法。

class A {

    private $v;

    function __construct ($value)
    {
        $this->v = $value;
    }

    function set_v ($value)
    {
        $this->v = $value;
    }

    function print_v ()
    {
        echo $this->v;
    }

}

class B {

    private $a;

    function __construct (&$tha)
    {
        if ($tha) {
          $this->a = $tha;
        }
    }

    function print_a ()
    {
        echo $this->a->print_v();
    }
}

$mya = new A(12);
$mya->print_v(); // echo 12
$myb = new B($mya);
$mya->set_v(13); 
$myb->print_a(); // echo 13

您可以在另一个对象中保留一个对象的跟踪,并尊重对象的封装。 但是,如果A的实例被删除,则B的实例可能变得不可靠。然后,您应该确保数据在存储它的对象中始终可靠(例如,创建一个验证内部数据是否正常的方法)。

同样由tereško注意到,应该避免明确等待参考的论据。事实上,自从PHP 5.0以来,一种称为类型提示的语言引入了一项新功能。这可以防止程序出现意外的内存行为,以及可以在编译级别监视任何错误匹配的事实(更多细节见Type Hinting (PHP official documentation)

因此

function __construct (&$tha) ...

必须重新定义为

function __construct (A $tha) ..

在示例中。

答案 4 :(得分:1)

依赖注入是最佳选择。我将使用此Factory机制将对象实例传递给另一个对象。如(只是一个样本,没有测试它):

class UI{

public $somthing = 'Cool';

public function newComponent($name){
    return new $name($this);
}

}

$ui = new UI;
class Form{
    public $ui;

    public function __construct(UI $ui){
        $this->ui = $ui;
    }

    public function say(){
        print $this->ui->somthing;
    }
}

$form = $ui->newComponent('Form');

$form->say(); // print 'Cool'.

答案 5 :(得分:-1)

怎么样?
<?php
class Assets
{
    protected static $assets = array();

    protected function add($el)
    {
        self::$assets[] = $el;
    }

    public function getAssets()
    {
        return self::$assets;
    }
}

class Form extends Assets
{
    public function __construct()
    {
        parent::add('Form');
    }
}

class Css extends Assets
{
    public function __construct()
    {
        parent::add('Style');
    }
}

$assets = new Assets;
new Form;
new Css;
var_dump($assets->getAssets()); // Prints: array(2) { [0]=> string(4) "Form" [1]=> string(5) "Style" }
相关问题