PHP处理不正确的我的静态调用 [英] PHP is handling incorrectly my static call

查看:124
本文介绍了PHP处理不正确的我的静态调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在PHP 5.3中遇到了问题。我需要通过使用 __ callStatic 调用一个方法,但是如果我在一个实例对象中使用它,PHP调用 __ call



在现实生活范例之上:

 <?php 

class A {
function __call($ method,$ args){
//注意:$ this是定义的!
echoOps!Do not works。{$ this-> c};
}

静态函数__callStatic($ method,$ args){
echo'Fine!';
}
}

B类扩展A {
public $ c ='Real Ops!';

function useCallStatic(){
static :: foo();
// === A :: foo();
// === B :: foo();
}
}

$ foo = new B();
$ foo-> useCallStatic();

//这样工作:
// B :: foo();

?>

打印:Ops!不工作。请注意,我从新B()调用 useCallStatic



。如果我调用直接工作好像 B :: foo()



解决方案

在思考之后,这不是一个bug。但它绝对是不直观的。

 <?php 
class A
{
public function foo()
{
static :: bar();
}

public function bar()
{
echobar()\\\
;
}
}

$ a = new A();
$ a-> foo();

这是有效的,并调用bar()。这不意味着静态调用栏。这意味着查找当前类名和调用函数 bar 如果它存在,无论它是否是一个静态函数。



更清楚一点:你认为 parent :: bar()表示调用 bar()?不,它意味着调用任何名为 bar()的函数。



请考虑:

 <?php 
A
{
function __call($ name,$ args)
{
echo__call()\\\
;
}

静态函数__callStatic($ name,$ ags)
{
echo__callStatic()\\\
;
}

function regularMethod()
{
echoregularMethod()\\\
;
}

static function staticMethod()
{
echostaticMethod()\\\
;
}

}

B类扩展A
{
函数foo()
{
父: :nonExistant();
static :: nonExistant();
parent :: regularMethod();
parent :: staticMethod();
}
}

$ b = new B();
$ b-> foo();

parent :: nonExistant()方法调用 A :: __ call() static :: nonExistant()。为调用调用 A :: __ callStatic()将同样有效! PHP没有办法知道你想要调用哪个。然而,根据设计,当从这种上下文调用时,PHP给予 __ call 优先级。



parent :: regularMethod()调用非静态函数 regularMethod()。 ( :: 运算符并不意味着调用此静态函数。)同样 parent :: staticMethod()调用 A :: staticMethod()



要解决你的问题:



您可以在继承的类中手动调用 self :: __ callStatic('foo')



或者在A类的 __调用方法中过滤已知列表并调用 self :: __ callStatic

  function __call($ f,$ a)
{
if($ f = ='foo')
return self :: __ callStatic($ f,$ a);
else
{
}
}

丑陋,但至少延伸这个类的人不需要做任何特别的事情。


I'm havinh a problem on PHP 5.3. I need to call a method by using __callStatic, but if I use it in a instancied object, PHP call __call instead.

Above a real life example:

<?php

    class A {
        function __call($method, $args){
            // Note: $this is defined!
            echo "Ops! Don't works. {$this->c}";
        }

        static function __callStatic($method, $args){
            echo 'Fine!';
        }
    }

    class B extends A {
        public $c = 'Real Ops!';

        function useCallStatic(){
            static::foo();
            // === A::foo();
            // === B::foo();
        }
    }

    $foo = new B();
    $foo->useCallStatic();

    // This works:
    // B::foo();

?>

Prints: Ops! Don't works. Real Ops!

Note that I call useCallStatic from a new B(). If I call directly works fine like B::foo().

What I can do to it works fine?

解决方案

After thinking about it, it's not really a bug. But it's definitely unintuitive.

<?php
class A
{
  public function foo()
  {
    static::bar();
  }

  public function bar()
  {
    echo "bar()\n";
  }
}

$a = new A();
$a->foo();

This is valid, and calls bar(). It does not mean call bar statically. It means to look up the current class name and call function bar if it exists, whether or not it's a static function.

To clarify a bit more: do you think parent::bar() means to call a static function called bar()? No, it means call whatever function is named bar().

Consider:

<?php
class A
{
  function __call($name, $args)
  {
    echo "__call()\n";
  }

  static function __callStatic($name, $ags)
  {
    echo "__callStatic()\n";
  }

  function regularMethod()
  {
    echo "regularMethod()\n";
  }

  static function staticMethod()
  {
    echo "staticMethod()\n";
  }

}

class B extends A
{
  function foo()
  {
    parent::nonExistant();   
    static::nonExistant();
    parent::regularMethod();
    parent::staticMethod(); 
  }
}

$b = new B();
$b->foo();

The parent::nonExistant() method invokes A::__call(), as does static::nonExistant(). Invoking A::__callStatic() for either call would be equally as valid! There is no way for PHP to know which one you want to be called. However, by design, PHP gives __call the priority when invoked from this sort of context.

parent::regularMethod() invokes the non static function regularMethod(). (Again, the :: operator does not mean "call this static function.") Likewise parent::staticMethod() invokes A::staticMethod() as one might expect.

To solve your problem:

You could manually call self::__callStatic('foo') in the inherited class.

Or within the __call method of class A filter against a known list and call self::__callStatic.

function __call($f, $a)
{
  if ($f == 'foo')
    return self::__callStatic($f, $a); 
  else
  {
  }
}

It's ugly, but at least people who extend the class won't need to do anything special.

这篇关于PHP处理不正确的我的静态调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆