Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/298.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关键字在使用static时出现致命错误,但(new self)工作正常_Php - Fatal编程技术网

Php 为什么$this关键字在使用static时出现致命错误,但(new self)工作正常

Php 为什么$this关键字在使用static时出现致命错误,但(new self)工作正常,php,Php,如果我将fun2更改为返回static::fun1,则会出现“致命错误:在不在对象上下文中时使用$this” 但是如果我改变fun1去回应新的自我->a;那就好了。 有人能解释为什么静态::讨厌$this而不是new self。 PS:请考虑我通过下面这些给定的问答部分和更多的文章,但不能准确地把握这一具体情景。 PPS:除了同一条错误信息,这个问答与我无关。这是完全不同的背景。在这个问题上,他只是静态地调用一个非静态方法。同时,对于后期静态绑定和关键字newself,我的问题更加复杂。在上面

如果我将fun2更改为返回static::fun1,则会出现“致命错误:在不在对象上下文中时使用$this” 但是如果我改变fun1去回应新的自我->a;那就好了。 有人能解释为什么静态::讨厌$this而不是new self。 PS:请考虑我通过下面这些给定的问答部分和更多的文章,但不能准确地把握这一具体情景。


PPS:除了同一条错误信息,这个问答与我无关。这是完全不同的背景。在这个问题上,他只是静态地调用一个非静态方法。同时,对于后期静态绑定和关键字newself,我的问题更加复杂。在上面提到的问答中,根本不可能理解我对答案的问题,因此请在标记为重复之前,仔细阅读这两个问答。谢谢。

这个问题涉及到类和实例之间的区别

我将简化您的示例并一步一步地进行

class A {
    public $a = "BooMBa";

    public function fun1() {
        echo $this->a; 
     // echo (new self)->a;
    }
}

class B extends A {

    public static function fun2() {
        return (new self)->fun1();
     // return static::fun1();
    }
}

B::fun2();  // returns BooMBa
A::func2-对A::func2的静态调用 新建self->fun1-创建实例并调用该实例的fun1 echo$this->a-echo在步骤2实例中创建的CurrentOf的内容 在步骤2中,对A::func2的每次调用都会创建A的新实例

A::func2-对A::func2的静态调用 static::fun1-对A::func1的静态调用,没有实例。AFAIK这应该会生成警告,因为您对实例方法进行了静态调用 echo$this->a;-回显当前实例的内容,但并没有实例,因为我们来自静态调用,我们在类范围内。错误 A::func2-对A::func2的静态调用 static::fun1-对A::func1的静态调用,没有实例 echo new self->a-创建a的新实例,并回显刚创建实例的变量a的内容 在步骤3中,对A::func2的每次调用都会创建A的新实例

$a=新a-创建新的a实例 $a->fun2-调用实例$a的方法fun2 $this->fun1-调用当前实例$a的方法fun1 echo$this->a-echo当前实例$a的内容 $this引用类的当前实例,但如果静态调用,则不存在实例。 new self创建类的新实例,该实例允许您使用$this,因为您有实例要引用

让我们以猫为例。猫的例子是站在你面前的一只$Cat。您可以让$cat调用purrr,因为您引用了cat的具体实例,所以在该cat的方法purrr中,您可以引用$this并调用echo$this->purrsound。 当您进行静态调用时,您将调用Cat的抽象概念,并没有Cat的特定实例,也并没有要引用的$this

class A {
    public $a = "BooMBa";
    public function fun1() {
        echo $this->a; 
    }
    public function fun2() {
        return $this->fun1();
    }
}
$a = new A();
$a->fun2();  // returns BooMBa
静态上下文 在PHP中,您可以使用作用域解析运算符静态调用方法::。所以,这个表达式只是一个静态调用:

返回静态::fun1

当您在静态调用$之后处于静态上下文中时,这不起作用-这是一种语言断言。即使在静态上下文中,此表达式仍然有效:

新自我->a

仅仅因为您正在创建一个对象的新实例,然后获取它的公共属性

不推荐的注释: 注意:在PHP5中,静态调用非静态方法会生成 E_严格级别警告

PHP7中的警告,不推荐静态调用非静态方法, 并将生成一个E_弃用警告。支持呼叫 将来可能会删除静态的非静态方法

请考虑:


考虑不要使用静态方法,因为它是其他类的耦合,通常只是静态方法中的过程代码。例如,在一个新类中实现此函数,并在需要时使用依赖项注入。

fun1是静态函数吗?提示:我不相信。不,fun1不是一个静态方法。这是因为fun1不是一个静态方法。您只能使用也在静态上下文中的工具在静态上下文中调用某些内容。这就是fun1无法执行,fun2执行时没有问题的原因。因此,当您调用B::fun1时,您可以将方法fun1作为静态方法调用,而不实例化对象$此关键字仅用于实例化对象。要使用当前代码调用fun1,必须首先创建一个对象$a=newa,然后调用方法$a->fun1Read this。你会发现更好的解释哪一个是好的实践?第一步还是第三步?我从一个复杂的例子简化了这个例子,为了充分利用OOP,我尝试了这个方法,而不是在B类的fun2中使用“global$a”。@JeevaRaam在这种情况下没有什么好处。它们只是不同而已,它们都有各自的用途。我不知道你们的具体情况是什么,但看看我刚才添加的第四个例子,这可能正是你们需要的
class A {
    public $a = "BooMBa";
    public function fun1() {
        echo $this->a; 
    }
    public static function fun2() {
        return static::fun1();
    }
}
A::fun2();  // fails
class A {
    public $a = "BooMBa";
    public function fun1() {
        echo (new self)->a;
    }
    public static function fun2() {
        return static::fun1();
    }
}
A::fun2();  // returns BooMBa
class A {
    public $a = "BooMBa";
    public function fun1() {
        echo $this->a; 
    }
    public function fun2() {
        return $this->fun1();
    }
}
$a = new A();
$a->fun2();  // returns BooMBa
class Cat {
    public $purrrSound = "purrrrr...";
    public function purrr() {
        echo $this->purrrSound;
    }
}
$cat = new Cat();
$cat->purrr(); // kittty purrrr, please?
// Cat::purrr(); // all the Cats in the universe, purrr now?