使用eval()和include()的命名空间不能按预期工作

Mon*_*eus 5 php scope namespaces function

我只是搞乱了,我遇到了这个:


不行

<?php
namespace first{
    include 'data:text/plain, <?php function a_func(){echo "hi";}';
    a_func();
}
namespace second{
    include 'data:text/plain, <?php function a_func(){echo "bye";}';
    a_func();
}
Run Code Online (Sandbox Code Playgroud)

[29-Apr-2016 14:12:42 America/New_York] PHP致命错误:无法重新声明a_func()(之前在数据中声明:text/plain,<?php function a_func(){echo"hi";}:1 )数据:text/plain,<?php function a_func(){echo"bye";}在第1行

不行

<?php
namespace first{
    eval('function a_func(){echo "hi";}');
    a_func();
}
namespace second{
    eval('function a_func(){echo "bye";}');
    a_func();
}
Run Code Online (Sandbox Code Playgroud)

[2016年4月29日14:19:21 America/New_York] PHP致命错误:无法重新声明a_func()(之前在C:\ path\test.php(3)声明:eval()'代码:1)in C:\ path\test.php(7):第1行的eval()代码

作品

<?php
namespace first{
    function a_func(){echo "hi";}
    a_func();
}
namespace second{
    function a_func(){echo "bye";}
    a_func();
}
Run Code Online (Sandbox Code Playgroud)

在PHP 5.6.20和7.0.5中测试


这是一个错误吗?特征?有目的地实施?


额外的功劳:我如何制作include()eval()工作?

Jon*_*Jon 7

include并且eval使编译器来处理他们的意见,就好像它是在这两种情况下一个单独的文件来.

这意味着设置代码中的命名空间声明不会传输到来自include/ 的代码eval,并且在那里定义的函数在全局命名空间中定义.您可以轻松验证这一点

<?php
namespace outer;

eval('function func(){}');
var_dump(function_exists('\outer\func'));    // false
var_dump(function_exists('\func'));          // true
Run Code Online (Sandbox Code Playgroud)

要获得预期的行为,您必须在所引入的代码中包含命名空间声明:

<?php
namespace first{
    include 'data:text/plain,<?php namespace first; function a_func(){echo "hi";}';
    a_func();
}
namespace second{
    include 'data:text/plain,<?php namespace second; function a_func(){echo "bye";}';
    a_func();
}
Run Code Online (Sandbox Code Playgroud)

<?php
namespace first{
    eval('namespace first; function a_func(){echo "hi";}');
    a_func();
}
namespace second{
    eval('namespace second; function a_func(){echo "bye";}');
    a_func();
}
Run Code Online (Sandbox Code Playgroud)