Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 有没有办法重新分配$this?_Php_Oop_Composition - Fatal编程技术网

Php 有没有办法重新分配$this?

Php 有没有办法重新分配$this?,php,oop,composition,Php,Oop,Composition,首先,我不想扩展一个类。我很想这样做 public function __construct() { /* Set Framework Variable */ global $Five; $this =& $Five; } 我有一个系统,其中变量$5是一个包含其他库的容器类。我可以把这个赋值给一个5的局部变量。。。i、 e public function __construct() { /* Set Framework Variable */ global $Five; $

首先,我不想扩展一个类。我很想这样做

public function __construct() {
 /* Set Framework Variable */
 global $Five;
 $this =& $Five;
}
我有一个系统,其中变量$5是一个包含其他库的容器类。我可以把这个赋值给一个5的局部变量。。。i、 e

public function __construct() {
 /* Set Framework Variable */
 global $Five;
 $this->Five = $Five;
}
然而,我试图避免这种情况的原因是函数调用会变得有点长

$this->Five->load->library('library_name');
有点难看。那就更好了

$this->load->library('library_name');

最好的解决方案是什么?

$这是对正在定义的类的当前实例的引用。我不相信你能分配给它。如果“五”是一个全球性项目,您应该能够做到这一点:

$Five->load->library('library_name');
我认为

$this->Five->load->library('library_name');
将是您的最佳选择,除非您决定让类扩展helper类。阿卡

class Something extends Helper_Class
但是,这意味着每次实例化一个类时,
Helper\u Class
都会被实例化


另一种方法是使用伪静态类,将所有帮助器类分配给类成员

public function setGlobals($five)
{
    $this->loader = $five->loader;
}
那就叫它吧

public function __construct($five)
{
    someClass::setGlobals($five);
}

如果
global$Five
是一个全局函数,那么每次你想使用它的时候,你都可以使用它,但是把它放在每个函数的顶部似乎是不好的编码


另外,我想做我的公共服务声明,全局变量通常是个坏主意,您可能希望搜索“依赖注入”或全局变量的替代方案。阿卡

public function __construct($five);
而不是

global $five;
Globals依赖于外部变量的存在和已设置,而依赖项注入请求一个它假定为五类实例的变量

如果您正在运行PHP5.1(感谢Gordon),您可以通过以下操作确保变量是
FiveClass
的实例:

public function__construct(FiveClass $five);

您可能希望使用依赖项注入模式的某种实现:

计算机中的依赖注入(DI) 编程是指编程的过程 将外部依赖项提供给 软件组件。这是一个具体的问题 控制权倒置的形式 担心被颠倒是一个过程 获得所需的依赖关系

另见。如果您想改进处理“全局”的方式,我可以强烈推荐这种DI容器实现


您还可以阅读“访问全局对象的最佳方式”。

我很确定您不能重新分配
$this
,因为它是一种特殊的东西,在PHP中看起来像一个变量,但在幕后的处理方式略有不同

如果您担心的是方法调用的语义太长,我会将
load
设置为方法调用,而不是对象属性

$this->load()->library('library_name');

public function load()
{
    return $this->Five;
}

如何制作五个静态类成员的相关数据成员和方法?这个

$this->Five->load->library('library_name');
会变成这样吗

Five::load->library('library_name');

您不必到处传递&$5。

您不能覆盖$this(例如在C++中),但您可以轻松构建一个用于方法调用的using,以及用于属性的uu get(),u set(),u isset()

调用()的示例:

打印调用的
Five::bar


在我看来,最大的缺点是很难“从外部”看到对象的功能。

使用PHP魔术方法可能会更好?

重新分配
这个
对我来说就像是一种代码味道……呃,是全球性的。请不要用那个。糟糕的OO设计。全局变量也困扰着我,这就是我来这里的原因:)引用手册:注意:$这是一个无法赋值的特殊变量。请看@JasonS:如果可能的话,你会如何调用你的应用程序对象?在我看来,这是一种黑客行为,但如果你用这种方式,你可能会想看看一个辅助类,这个主类进行逻辑扩展。是的,OP给一个内部属性分配了一个全局属性,所以整个事情在没有完全重组的情况下都有黑客的味道,这超出了问题的范围。不,你必须将对5的调用硬编码到你的类中。最好是聚合而不是组合,并注入依赖项,而不是在类中创建对象或硬编码静态调用。这使您可以更轻松地交换它们,例如,在单元测试中使用mock。现在的情况是,它没有明确的标识。假设Foo是Log,您将其传递给用户对象,因为您可以。您希望$log->delete做什么?您可以通过对接口进行编码来解决这个问题,并限制Foo作为对象接受的内容。也可以是一个接口。基本理念不变。啊。。。我不确定它是哪个版本,所以我假设它是5.3。为您找到它:类型提示只能是object和array(因为PHP5.1)类型。看见
class Five {
  public function bar() {
    echo __METHOD__, " invoked\n";
  }
}

class Foo {
  protected $Five = null;

  public function __construct(Five $five=null) {
     if ( is_object($five) ) {
       $this->Five = $five;
     }
   }

  public function __call($name, $args) {
    // there's no accessible method {$name} in the call context
    // let's see if there is one for the object stored in $five
    // and if there is, call it.
    $ctx = array($this->Five, $name);
    if ( !is_null($this->Five) && is_callable($ctx) ) {
      return call_user_func_array($ctx, $args);
    }
    else {
      // ....
    }
  }
}

$foo = new Foo(new Five);
$foo->bar();