php получить пространство имен включенного файла

//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 не читает содержимое файла и не делает регулярное выражение на нем? Это просто похоже на накладные расходы.

///РЕДАКТИРОВАТЬ

Мне бы очень хотелось иметь возможность динамически добавлять пространство имен к включенному файлу.

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

Я хочу разрешить сторонние плагины, но пространство имен php кажется ужасным. Я не хочу, чтобы редактора плагинов создавали пространство имен.

Нет. Но ты мог бы обмануть его так:

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

И для его прочтения:

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

Ну, вы можете сканировать пространство имен классов. Он содержит пространства имен. Это способ PHPUnit делать вещи. Итак, т.е.:

 $namespaces = get_current_namespaces(); include 'plugin/main.php'; $newNamespaces = get_current_namespaces(); array_diff($namespaces, $newNamespaces) 

Вот как вы можете реализовать get_current_namespaces() : возможно ли получить список определенных пространств имен

Если вы знаете файл, вы можете просто извлечь форму пространства имен :).

 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; } 

И вы не будете сдерживать возврат чего-либо в конце файла, который может быть взломан с выхода или других инструкций возврата.

Я разработал довольно трудоемкий ручной способ сделать это.

Как обсуждалось выше, сам процесс прост:

  1. получите список файлов для каждого файла. Теперь для каждого файла:
  2. создать случайный идентификатор пространства имен
  3. обрезать файл и заменить первый начальный тег
  4. добавить идентификатор пространства имен и запустить тег в файл
  5. написать в файл temp
  6. файл импорта temp
  7. требуется любое отражение, необходимое для очистки

У меня есть пример с некоторыми zend здесь … вероятно, не самый эффективный, но он работает.

 <?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 } } ?>