限制PHP中包含的函数的范围

我想从一个方法中包含/要求一个包含多个功能的文件。我的目标是使如此包含的函数仅在相应方法的范围内可用,而在调用范围内不可用。这在PHP中可行吗?

例如在下面的最小示例中,我希望foo()仅在方法buzz()中可用,而不能从周围的范围中使用(不幸的是)。

// foo.php

<?php
function foo()
{
    return "foo";
}
// bar.php

<?php
class Bar 
{
    public function buzz()
    {
         require_once("foo.php");
         return foo();
    }
}

$bar = new Bar();

// should work
echo $bar->buzz();

// should not work
echo foo();

常规任务是将旧代码库中的功能包装到Symfony服务的方法中。只有通过调用相应的方法才能访问旧功能。因此,旧功能不应在全局范围内。

一个主要限制是foo.php中的功能是我无法修改的旧版代码库的一部分。

ysh851216 回答:限制PHP中包含的函数的范围

  

我的目标是使如此包含的功能仅在   各自方法的范围,不在调用范围之内。这是   可能在PHP中使用?

不直接。不是类方法的未命名函数始终是全局范围。如果您只是不希望它们在全局范围内,则只需在名称空间中声明它们即可。但是,它们仍然可以在任何范围内调用。

如果那还不够,那么有(相当丑陋)的选择。由于在函数中定义的变量仅对该函数可用,因此您可以通过使用分配给变量的匿名函数来近似尝试执行的操作。这些将在功能结束时有效消失。

foo.php

$function = function()
{
    return "foo";
};

bar.php

class Bar 
{
    public function buzz()
    {
        require_once 'foo.php';
        $function();
    }
}
,

如果想发挥创意,可以在需要之前重写文件以包含名称空间声明。这可能看起来像这样:

function wrapInNamespace(string $req): string
{
    // Namespaces have to start with a letter,unique IDs might not
    $tempNamespace = 'a' . uniqid();
    $namespaceDeclaration = sprintf("namespace %s;\r\n",$tempNamespace);

    $lines = file($req);

    array_splice($lines,1,null,$namespaceDeclaration);

    $temp = tmpfile();
    fwrite($temp,implode('',$lines));
    require_once(stream_get_meta_data($temp)['uri']);
    fclose($temp);

    return $tempNamespace;
}

array_splice行在文件的第二行添加了动态生成的名称空间声明,然后我们将其返回,以便您以后可以引用这些函数。这是通过临时文件完成的。

丑陋的部分是,在实际调用它们时,您需要分配一个命名空间标识符,因为据我所知,不可能在一行上的动态命名空间中调用函数(我很高兴被告知不同):

class Bar
    public function buzz()
    {
        $tempNamespace = wrapInNamespace('foo.php');
        $func = "\\$tempNamespace\\foo";
        $func();
    }
}

所有内容放在一起,这意味着您可以执行以下操作:

echo (new Bar)->buzz();
# foo

foo();
# PHP Fatal error:  Uncaught Error: Call to undefined function foo() ...

这全部要求您的文件在第一行以<?php开头,并且不包含任何其他名称空间声明。使用同一文件两次调用wrapInNamespace将为您提供文件的两个完全不同的版本-只要您不将命名空间从buzz方法中泄漏出去,就不能从其他任何地方调用它。这是否有用将取决于您要包括的源文件的确切范围。如果它们只是其他全局函数的集合,则可以很好地完成工作。如果它们还包含过程代码,它将没有太大用处。

本文链接:https://www.f2er.com/3035212.html

大家都在问