//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命名空间似乎很糟糕。我不希望插件编辑者必须创建命名空间。
答案 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)
我制定了相当费力的手工方式来做到这一点。
如上所述,过程本身很简单:
我在这里得到了一些例子......可能效率不高但是有效。
<?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
}
}
?>