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

时间:2016-04-29 18:36:39

标签: php function scope namespaces

我只是搞乱了,我已经碰到了这个:

不能工作

<?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();
}
  

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

不能工作

<?php
namespace first{
    eval('function a_func(){echo "hi";}');
    a_func();
}
namespace second{
    eval('function a_func(){echo "bye";}');
    a_func();
}
  

[29-Apr-2016 14:19:21 America / New_York] PHP致命错误:无法重新声明a_func()(之前在C:\ path \ test.php(3)中声明:eval()&#39; d代码:1)在C:\ path \ test.php(7):eval()&#39; d代码在第1行

作品

<?php
namespace first{
    function a_func(){echo "hi";}
    a_func();
}
namespace second{
    function a_func(){echo "bye";}
    a_func();
}

在PHP 5.6.20和7.0.5中测试

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

额外信用:如何制作include()eval()

1 个答案:

答案 0 :(得分:7)

includeeval会导致编译器处理输入,就好像它来自两个文件中的单独文件一样。

这意味着设置代码中的命名空间声明不会转移到来自include / eval的代码,并且在那里定义的函数在全局命名空间中定义。您可以使用

轻松验证
<?php
namespace outer;

eval('function func(){}');
var_dump(function_exists('\outer\func'));    // false
var_dump(function_exists('\func'));          // true

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

<?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();
}

<?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();
}