/// 问题看如下代码
<?php
class A
{
function A()

$this->nNum = 1024;
}
function SelfClass()
{
echo "class A<br>";
}
}class B extends A
{
function SelfClass()
{
echo "class B<br>";
}
}
?><?php
$obj = new B();
$obj->SelfClass(); // 调用B类的函数SelfClass()函数
/* 如何能使用对象obj的基类的SelfClass()函数?
C++下可以写类似的代码$obj->A::SelfClass(),那么PHP可以如何实现呢?*/
?>

解决方案 »

  1.   

    我所求的并非类似这种答案
    class B extends A
    {
    function SelfClass()
    {
    echo "class B<br>";
    }

    function SelfClassX()
    {
    parent::SelfClass();
    }
    }
      

  2.   

    php没有提供这样的语法,不过可以模拟一下,但是不是很推荐这样用
    <?php
    class A
    {
    function A()

    $this->nNum = 1024;
    }
    function SelfClass()
    {
    echo "class A<br>" . $this->nNum . "<br>";
    } function __call($name, $arguments) {
    list($class_name, $function_name) = explode('_', $name);

    if(is_subclass_of($this, $class_name))
    {
    if ($class_name == __CLASS__)
    {
    self::$function_name();

    else 
    {
    $class_name::$function_name();
    }
    }
    }
    }class B extends A
    {
    function B()
    {
    $this->nNum = 2048;
    }
    function SelfClass()
    {
    echo "class B<br>" . $this->nNum . "<br>";
    }
    }class C extends B
    {
    function C()
    {
    $this->nNum = 4096;
    }
    function SelfClass()
    {
    echo "class C<br>" . $this->nNum . "<br>";
    }
    }$obj = new B();
    $obj->SelfClass(); // 调用B类的函数SelfClass()函数$obj->A_SelfClass();$obj = new C();
    $obj->SelfClass(); // 调用C类的函数SelfClass()函数$obj->A_SelfClass();
    $obj->B_SelfClass();
      

  3.   

    这种语法$class_name::$function_name();编不过。
    而且self::$function_name();的使用前提是$function_name()是静态函数。
      

  4.   

    <?php
    /// 折中地写了个实现,不完善,因为当C类继承B类时无法动态实现类的判断,语法不允许只能写硬代码类似于(A::$function_name(),B::$function_name())。
    class A
    {
        function A()
        { 
            $this->nNum = 1024;
        }
        function SelfClass()
        {
            echo "class A<br>" . $this->nNum . "<br>";
        }
     
        function __call($name, $arguments)
    {
            list($class_name, $function_name) = explode('_', $name);
    if(method_exists($this, $function_name) && is_a($this, $class_name))
    {
    if(is_subclass_of($this, $class_name))
    {
    A::$function_name();
    }
    else
    {
    $this->$function_name();
    }
    }
        }
    }
     
    class B extends A
    {
        function B()
        {
            $this->nNum = 2048;
        }
        function SelfClass()
        {
            echo "class B<br>" . $this->nNum . "<br>";
        }    
    }$obj = new B();
    $obj->B_SelfClass(); // 调用B类的SelfClass()函数
    $obj->A_SelfClass(); // 调用A类的SelfClass()函数
     
      

  5.   

    不太明白你这么做的意义
    但至少 21 行的 A::$function_name();
    应写作 $class_name::$function_name();
    否则就不具普遍性了
      

  6.   

    $class_name::$function_name();这写法是有语法错误的。你不可以这样子写啊。
    $class_name只能解析为字符串,无法使用这种语法。你想法是美好的但实现不了
      

  7.   

    这可不只是美好的愿望!实测证明写作 $class_name::$function_name() 是正确的(php5.4.12)但需要注意的是:
    无论是写作 $class_name::$function_name()
    还是写作 A::$function_name()
    都是不符合 php 语法的,因为需要 $function_name 是静态方法,而这里的不是
      

  8.   

    而在这里 php 没报错,显然是一个 BUG
      

  9.   

    对你的提出的写法我这边的测试环境没法实现,而且你说不行的,我这边能测试通过。
    我实测过A::$function_name()是可以的,这个调用并不需要 $function_name 是静态方法。
    而且$class_name::$function_name()这种写法我测过是无法把$class_name解析为类来用的
    只能解析为字符串。难道是我的PHP版本太老了!!!
      

  10.   

    A::SelfClass(); //Strict Standards:  Non-static method A::SelfClass() should not be called statically 这是正常的语法错(可屏蔽)
    $function_name = 'SelfClass';
    A::$function_name(); //这里不报语法错是不正常的在一个系统里是不应该存在双重标准的!
      

  11.   

    我在一本书上找到了A::$function_name();类似这个语法的用例
      

  12.   

    这段出自《PHP与MySQL程序设计》第4版
      

  13.   

    类名::方法名 这种写法古来有之,这是到了 php5.3 才开始有了限制
      

  14.   

    我之前用的都是C++,学习PHP时总是惯性认为某些用法应该差不多。
      

  15.   

    C++是编译执行的,所以源码被扫描几遍都无所谓
    php是解释执行的,多扫描一遍都会影响执行效率如果你自己去写解释器,你就会发现有很多二义性问题在二遍扫描中都无法解决
      

  16.   

    版主提到二义性问题确实是重点。想问一下版主,我原来是做C++游戏开发的,想改行做网站
    作为一个PHP程序员的话,需不需要学习javascript,而基础html的话要学习到什么程度。
      

  17.   

    直接使用反射吧,php5.2 php5.3 都可以测试通过
    <?php
    class A
    {
    function A()

    $this->nNum = 1024;
    }
    function SelfClass()
    {
    echo "class A<br>" . $this->nNum . "<br>";
    } function __call($name, $arguments) {
    list($class_name, $function_name) = explode('_', $name);

    if(is_subclass_of($this, $class_name))
    {
    //反射一个方法
    $reflectionMethod = new ReflectionMethod($class_name, $function_name); // 使用当前对象调用
    $reflectionMethod->invoke($this);
    }
    }
    }class B extends A
    {
    function B()
    {
    $this->nNum = 2048;
    }
    function SelfClass()
    {
    echo "class B<br>" . $this->nNum . "<br>";
    }
    }class C extends B
    {
    function C()
    {
    $this->nNum = 4096;
    }
    function SelfClass()
    {
    echo "class C<br>" . $this->nNum . "<br>";
    }
    }$obj = new B();
    $obj->SelfClass(); // 调用B类的函数SelfClass()函数$obj->A_SelfClass();$obj = new C();
    $obj->SelfClass(); // 调用C类的函数SelfClass()函数$obj->A_SelfClass();
    $obj->B_SelfClass();
      

  18.   

    我想大概可以用evla()函数来解决吧
      

  19.   

    写错了,应该为void eval(string code_str);
      

  20.   


    没有那么麻烦
    <?php
    class A
    {
    function A()

    $this->nNum = 1024;
    }
    function SelfClass($a,$b,$c,$d,$e,$f)
    {

    echo "class A<br>" . $this->nNum . "<br>" . "$a,$b,$c,$d,$e,$f". "<br>";
    } function __call($name, $arguments) {
    list($class_name, $function_name) = explode('_', $name);

    if(is_subclass_of($this, $class_name))
    {
    //反射一个方法
    $reflectionMethod = new ReflectionMethod($class_name, $function_name); // 使用当前对象调用
    $reflectionMethod->invokeArgs($this, $arguments);
    }
    }
    }class B extends A
    {
    function B()
    {
    $this->nNum = 2048;
    }
    function SelfClass()
    {
    echo "class B<br>" . $this->nNum . "<br>";
    }
    }class C extends B
    {
    function C()
    {
    $this->nNum = 4096;
    }
    function SelfClass()
    {
    echo "class C<br>" . $this->nNum . "<br>";
    }
    }$obj = new B();
    $obj->SelfClass(); // 调用B类的函数SelfClass()函数$obj->A_SelfClass(1,2,3,4,5,6,7);$obj = new C();
    $obj->SelfClass(); // 调用C类的函数SelfClass()函数$obj->A_SelfClass(1,2,3,4,5,6,7);
    $obj->B_SelfClass();
      

  21.   

    喔,确实是很好地解决了。感谢hnxxwyq