我想使用反射拿到所有类包含的方法,但如果两个modules中含有同名类时,会报错:
Fatal error: Cannot redeclare class DefaultController in 
$path = "/data/www/project1/protected/modules/admin/controllers";
$controller = "DefaultController";
include_once($path.DIRECTORY_SEPARATOR.$controller.'.php');        
$reflection = new ReflectionClass($controller); 
$methods = $reflection->getMethods(); 
var_dump($methods);
$path = "/data/www/project1/protected/modules/customerService/controllers";
include_once($path.DIRECTORY_SEPARATOR.$controller.'.php');        
$refleaction = new ReflectionClass($controller); 
$methods = $refleaction->getMethods(); 
var_dump($methods);exit;
php 反射

解决方案 »

  1.   

    感谢回复 
    还想问一下 因为我们项目里面有好多modules,每个modules下面都有好多controllers,如果都家命名空间的话,代码修改量比较大。。
    能不能反射的时候类似按照controller的路径这种方式来引入呢
      

  2.   

    你并不需要修改你的项目代码,只需要修改你的分析程序就可以了。
    先给个测试例<?php
    namespace my\a;
    class T {
      function foo() {}
    }namespace my\b;
    class T {
      function foo() {}
      function see() {}
    }//
    echo '<pre>';
    $reflection = new \ReflectionClass('my\a\T');
    $methods = $reflection->getMethods(); 
    print_r($methods);$reflection = new \ReflectionClass('my\b\T');
    $methods = $reflection->getMethods(); 
    print_r($methods);结果Array
    (
        [0] => ReflectionMethod Object
            (
                [name] => foo
                [class] => my\a\T
            ))
    Array
    (
        [0] => ReflectionMethod Object
            (
                [name] => foo
                [class] => my\b\T
            )    [1] => ReflectionMethod Object
            (
                [name] => see
                [class] => my\b\T
            ))
    可以看到,和你的分析程序相比,只是增加了命名空间
    你可以把目标程序文件的路径处理成命名空间
      

  3.   

    但是我的类都是在一个个文件中的,需要在这些文件头部都加上namespace吗?
      

  4.   

    不需要,比如namespace data\www\project1\protected\modules\admin\controllers
    $path = "/data/www/project1/protected/modules/admin/controllers";
    $controller = "DefaultController";
    include_once($path.DIRECTORY_SEPARATOR.$controller.'.php');        
    $reflection = new \ReflectionClass($controller); 
    $methods = $reflection->getMethods(); 
    var_dump($methods);
      

  5.   

    那就需要把namespace后面的当成一个变量是吧,每次调用不同目录下的类的时候都需要更改一下namespace吗?据说namespace只能在第一行,那我要是想在一个函数中遍历所有类的所有action是不就不行了
      

  6.   

    命名空间可改,也可不改,只要不发生冲突即可
    不过反射得到的信息中是含有命名空间的,用路径做命名空间,分析起来比较方便namespace 前不能有非 <?php 之外的内容这是正确的,但我 #3 的代码的写法也是正确的。
    也就是说,一个程序文件中可以存在多个命名空间命名空间声明时是不能使用变量的
    所以建议你在批量处理时通过写临时文件,再 include 进来比较好

    $paths = array(
      "/data/www/project1/protected/modules/admin/controllers",
      "/data/www/project1/protected/modules/customerService/controllers",
    );
    $controller = "DefaultController";
    foreach($paths as $path) {
      $ns = str_replace('/', '\\', $path);
      $code =<<< CODE
    <?php
    namespace $ns;
    include_once('$path/$controller.php');        
    $refleaction = new ReflectionClass('$controller'); 
    $methods = $refleaction->getMethods(); 
    var_dump($methods);
    CODE;
      file_put_contents('tmp.php', $code);
      include 'tmp.php';
    }
      

  7.   


    老大,好像在一段代码中通过不同的命名空间来调用不同modules中的同名类,好像不行。。
    我最小话一个实例
    有两个modules,一个叫mya,一个叫myb
    然后利用另一个controller中的一个action来include这两个类,但是include的时候就报错,说不能重定义,我include之前已经按照您的方法切换了命名空间,但还是不行