//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; }
И вы не будете сдерживать возврат чего-либо в конце файла, который может быть взломан с выхода или других инструкций возврата.
Я разработал довольно трудоемкий ручной способ сделать это.
Как обсуждалось выше, сам процесс прост:
У меня есть пример с некоторыми 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 } } ?>