PHP查找当前对象($ this)和方法的祖先

时间:2015-06-02 13:43:12

标签: php class oop

在OOP的任何给定上下文中,$this指的是当前类。但是,如果当前类扩展了前一个类,而后一个类又扩展了前一个类等,则可能会有一点难以跟踪。我这样说是因为我正在使用Magento而且它是一个脑部担架。

我的目标是追踪这些信息,然后希望得到 a)系统中每个父类的位置和 b)每个班级的方法

我该怎么做?我的想法是我也可以使用get_included_files()并在核心类中创建一个方法,如果被调用,它将告诉我任何给定方法的位置 - 权威 - 在哪个文件中,以及相对于“最后一个方法实例” “那扩展了它。

我很乐意发布在此主题上创建的工具

所以如果你有这个代码

function myFirstMethod(){
    //call this tool
    Mage::log($tools->trace('someOtherMethod'));
    //this was already here
    $this->someOtherMethod();  //where is it? has it been extended? That's what I want to determine
}

2 个答案:

答案 0 :(得分:1)

以下代码段使用get_classget_parent_class来升级实例的继承树:

<?php

class A {}
class B extends A {}
class C extends B {
  function trace() {
    $cls = get_class($this);

    while ($cls !== FALSE) {
      echo $cls. "\n\t with methods: " . implode(', ', get_class_methods($cls))  . "\n";
      $reflectionClass = new ReflectionClass($cls);
      echo "\t" . $reflectionClass->getFileName() . "\n";

      $cls = get_parent_class($cls);
    }
  }
}

(new C())->trace();

在我的机器上输出以下输出:

C
 with methods: trace
/tmp/stuff.php
B
 with methods: 
 /tmp/stuff.php
A
 with methods: 
 /tmp/stuff.php

答案 1 :(得分:0)

感谢所有参与者,我希望这能为种子提供良好的追踪工具(如果它还没有开发):

function trace() {
    //you can modify this, this is hard coded
    $this->_root='/home/vagrant/commoncart/';

    $cls = get_class($this);
    $i=0;
    $methodMap=array();
    $classMap=array();
    //we are ascending UPwards
    while ($cls !== FALSE) {

        $i++;
        $reflectionClass = new ReflectionClass($cls);
        $file=$reflectionClass->getFileName();

        $classMap[$cls]=$file;

        if($a=get_class_methods($cls)) foreach($a as $method){
            if(!empty($methodMap[$method])){
                $methodMap[$method]['override']=true;
                $methodMap[$method]['overridden'][]=$cls; //
            }else{
                $methodMap[$method]=array(
                    'class'=>$cls,
                    'file'=>str_replace($this->_root,'',$file),
                    'line'=>'undefined', //this would be great to have, probably need to read the file and parse it once..
                );
            }
        }

        $cls = get_parent_class($cls);
        if($i>5)break;
    }
    echo '<pre>';
    print_r($classMap);
    print_r($methodMap);
    exit('done');
}