Php 未捕获错误:在不在对象上下文中时使用$this,在使用_callStatic时使用$this
我正在尝试使用uu callStatic静态调用一个非静态方法,但是我一直遇到这个错误。我知道这是可能的,因为一些框架(比如Laravel)可以做到这一点,但我自己似乎无法做到 致命错误:未捕获错误:不在对象上下文中时使用$this 在Output.php:18堆栈跟踪中: php(4):输出::prepare() 在第14行的Output.php中抛出1{main} index.phpPhp 未捕获错误:在不在对象上下文中时使用$this,在使用_callStatic时使用$this,php,laravel,class,Php,Laravel,Class,我正在尝试使用uu callStatic静态调用一个非静态方法,但是我一直遇到这个错误。我知道这是可能的,因为一些框架(比如Laravel)可以做到这一点,但我自己似乎无法做到 致命错误:未捕获错误:不在对象上下文中时使用$this 在Output.php:18堆栈跟踪中: php(4):输出::prepare() 在第14行的Output.php中抛出1{main} index.php $output = Output::prepare(); class Output { publi
$output = Output::prepare();
class Output
{
public static function __callStatic($method, $args)
{
if ($method == 'prepare') {
$obj = new static();
return $obj->$method(...$args);
}
}
public function prepare()
{
// (!) Uncaught Error: Using $this when not in object context
if ($this->hasItems()) {
return print_r($_POST, true);
}
}
public function hasItems()
{
return true;
}
}
Output.php
$output = Output::prepare();
class Output
{
public static function __callStatic($method, $args)
{
if ($method == 'prepare') {
$obj = new static();
return $obj->$method(...$args);
}
}
public function prepare()
{
// (!) Uncaught Error: Using $this when not in object context
if ($this->hasItems()) {
return print_r($_POST, true);
}
}
public function hasItems()
{
return true;
}
}
“\uuu callStatic()
在静态上下文中调用不可访问的方法时被触发。”
您的方法prepare
可以通过其可见性进行访问。如果希望使用\uu callStatic
,则需要调整prepare
方法的可见性:
protected function prepare()
您的错误听起来更像是将prepare
声明为静态函数:
public static function prepare()
而不是非静态方法,如:
public function prepare()
如果您的方法是非静态的,那么您将收到如下内容:
不应静态调用非静态方法输出::prepare()
“\uuu callStatic()
在静态上下文中调用不可访问的方法时被触发。”
您的方法prepare
可以通过其可见性进行访问。如果希望使用\uu callStatic
,则需要调整prepare
方法的可见性:
protected function prepare()
您的错误听起来更像是将prepare
声明为静态函数:
public static function prepare()
而不是非静态方法,如:
public function prepare()
如果您的方法是非静态的,那么您将收到如下内容:
不应静态调用非静态方法输出::prepare()
输出类中的方法
prepare
不是静态的
。这是您可以使用$this->
调用的唯一非静态方法。在您的情况下,要调用prepare
您应该使用输出
类使用输出
,然后您可以说$Output=newoutput
,然后说$Output->prepare()
。如果要将其用作Output::prepare()
必须将Output
类中的方法更改为public static function prepare()
希望对您有所帮助您的输出类中的
准备方法不是静态的。这是您可以使用$this->
调用的唯一非静态方法。在您的情况下,要调用prepare
您应该使用输出
类使用输出
,然后您可以说$Output=newoutput
,然后说$Output->prepare()
。如果要将其用作Output::prepare()
必须将Output
类中的方法更改为public static function prepare()
希望这会有所帮助,除非你像@lagbox所说的那样移除方法的可见性,否则你不能在同一个类上使用这个技巧。否则,PHP将直接调用prepare()
方法,而不经过\uu callStatic()
(在您的情况下,它会导致$this
错误,并警告静态使用公共方法)
类输出
{
公共静态函数\uuu callStatic($method,$args)
{
如果($method=='prepare'){
$obj=新的static();
返回$obj->$method(…$args);
}
}
私有函数prepare()//或protected以删除可见性并强制调用uu callStatic()
{
如果($this->hasItems()){
返回打印结果($\u POST,true);
}
}
公共功能项目()
{
返回true;
}
}
如果您想使用Facade技巧,您需要将静态调用转发到另一个类(您可以向第二个类发送一些上下文,使其对输出
类是唯一的)
类输出
{
公共静态函数\uuu callStatic($method,$args)
{
如果(!方法_存在(self::class$method)){
返回(新转发('output'))->$method(…$args);
}
}
}
班级前进
{
私人背景;
公共函数构造($context=null)
{
$this->context=$context;
}
公共职能准备()
{
如果($this->hasItems()){
返回打印结果($\u POST,true);
}
}
公共功能项目()
{
返回true;
}
}
PS:laravel使用此特性在型号Lightning\Support\Traits\ForwardScals
上完成此操作
受保护函数forwardCallTo($object、$method、$parameters)
{
试一试{
返回$object->{$method}(…$parameters);
}捕获(错误| BadMethodCallException$e){
$pattern='~^调用未定义的方法(?P[^:]+)::(?P[^\(]+)\(\)$~;
如果(!preg_match($pattern,$e->getMessage(),$matches)){
扔$e;
}
如果($matches['class']!=get_class($object)||
$matches['method']!=$method){
扔$e;
}
静态::throwBadMethodCallException($method);
}
}
除非像@lagbox所说的那样移除方法的可见性,否则不能在同一个类上使用该技巧。否则,PHP将直接调用prepare()
方法,而不经过\uu callStatic()
(在您的情况下,它会导致$此
错误,并警告静态使用公共方法)
类输出
{
公共静态函数\uuu callStatic($method,$args)
{
如果($method=='prepare'){
$obj=新的static();
返回$obj->$method(…$args);
}
}
私有函数prepare()//或protected以删除可见性并强制调用uu callStatic()
{
如果($this->hasItems()){
返回打印结果($\u POST,true);