php获取包含文件的命名空间

时间:2010-12-22 18:30:35

标签: php namespaces

//file foo.php
<?php
namespace foo;
class foo{
    function __construct(){
        echo "hello";
    }
}
?>

//file index.php
<?php
require_once("foo.php");
echo __NAMESPACE__;
?>

我的问题是,从我的index.php文件中,是否可以知道foo.php的命名空间而不读取文件内容并在其上执行正则表达式?这似乎是很多开销。

/// EDIT

我真的希望能够将命名空间动态添加到包含的文件中。

<?php
namespace dynamic;
require_once("foo.php");
echo __NAMESPACE__;
?>

我想允许第三方插件,但php命名空间似乎很糟糕。我不希望插件编辑者必须创建命名空间。

4 个答案:

答案 0 :(得分:15)

没有。但你可以这样欺骗它:

//file foo.php
<?php
  namespace foo;
  //...
  return __NAMESPACE__;  // must be last line
?>

阅读它:

//file index.php
<?php
  $ns = require_once("foo.php");

答案 1 :(得分:5)

好吧,你可以扫描类名称空间。它包含名称空间。这是PHPUnit的做事方式。那就是:

$namespaces = get_current_namespaces();

include 'plugin/main.php';

$newNamespaces = get_current_namespaces(); 
array_diff($namespaces, $newNamespaces)

以下是您实施get_current_namespaces()is it possible to get list of defined namespaces

的方法

答案 2 :(得分:4)

如果您知道该文件,您只需从中提取名称空间:)。

function extract_namespace($file) {
    $ns = NULL;
    $handle = fopen($file, "r");
    if ($handle) {
        while (($line = fgets($handle)) !== false) {
            if (strpos($line, 'namespace') === 0) {
                $parts = explode(' ', $line);
                $ns = rtrim(trim($parts[1]), ';');
                break;
            }
        }
        fclose($handle);
    }
    return $ns;
}

并且您不会限制在文件末尾返回可能从退出或其他返回指令中断的内容。

答案 3 :(得分:0)

我制定了相当费力的手工方式来做到这一点。

如上所述,过程本身很简单:

  1. 获取每个文件的文件列表。现在为每个文件:
  2. 创建随机命名空间ID
  3. 修剪文件并替换第一个开始标记
  4. 添加名称空间ID并将标记添加到文件
  5. 写入临时文件
  6. 导入临时文件
  7. 做任何需要的反思然后清理
  8. 我在这里得到了一些例子......可能效率不高但是有效。

    <?php
    //first setup zend
    set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__)."/../zend/library/");
    require_once 'Zend/Loader/Autoloader.php';
    $loader = Zend_Loader_Autoloader::getInstance();
    $loader->registerNamespace(dirname(__FILE__)."/../zend/library/");
    
    //include my extender class
    class Zend_Reflection_File_WithNamespace extends Zend_Reflection_File {
        public function getFunctionsWithNamespace($namespace = '', $reflectionClass = 'Zend_Reflection_Function')
        {
            $functions = array();
            foreach ($this->_functions as $function) {
                $newName = $namespace . "\\" . $function;
                $instance = new $reflectionClass($newName);
                if (!$instance instanceof Zend_Reflection_Function) {
                    require_once 'Zend/Reflection/Exception.php';
                    throw new Zend_Reflection_Exception('Invalid reflection class provided; must extend Zend_Reflection_Function');
                }
                $functions[] = $instance;
            }
            return $functions;
        }
    }
    
    //find file(s)
    $startDir = 'hello/';
    //$tempDir = 'php://temp/resource=';
    $tempDir = 'temp/';
    $fileList = scandir($startDir);
    
    function ppPrintR($data) {
        echo "<pre>";
        print_r($data);
        echo "</pre>";
    }
    
    //Now loop through each file, first writing to temp, including and then testing
    foreach ($fileList as $key => &$fileItem) {
        if (is_file($startDir . $fileItem)) {
            //Take file and convert it
            $findDir = $startDir . $fileItem;
            echo $startDir . $fileItem;
    
            $inContents = file_get_contents($findDir); 
            $randIden = 'm' . preg_replace('/\.|\s/', '', microtime());
    
            //Replace the <?[php] at the start of the file with <? namespace xyz;
            $inContents = trim($inContents);
            $addString = 'namespace ' . $randIden . '; ';
    
            $longTagPos = strpos($inContents,'<?php');
            $shortTagPos = strpos($inContents,'<?');
    
            if ($longTagPos !== false && $longTagPos < 10) {
                $inContents = str_replace('<?php', '', $inContents);
                $addString = '<?php ' . $addString;
            }
            else if ($shortTagPage !== false && $longTagPos < 10) {
                $inContents = str_replace('<?', '', $inContents);
                $addString = '<? ' . $addString;
            }
            $outContents = $addString . $inContents;
    
            //Now write and require new temp file
            $tempItem = $tempDir . $fileItem;
            file_put_contents($tempItem, $outContents);
            require($tempItem);
    
            //Now do normal things
            $reflectedFile = new Zend_Reflection_File_WithNamespace($tempItem);
            echo 'Before<br/>';
            $functions = $reflectedFile->getFunctionsWithNamespace($randIden);
            echo 'After<br/>';
    
            //Now foreach function, read params and consider execution
            foreach($functions as &$functionItem) {
                echo $functionItem->name . "<br/>";
                $functionParams = $functionItem->getParameters();
                ppPrintR($functionParams);
            }
    
            //FIXME should clean here
        }
    }
    ?>