什么是PHP嵌套函数?

meo*_*ouw 76 php nested-function

在JavaScript中,嵌套函数非常有用:闭包,私有方法以及你有什么...

什么是嵌套的PHP函数?有没有人使用它们,为什么?

这是我做的一个小调查

<?php
function outer( $msg ) {
    function inner( $msg ) {
        echo 'inner: '.$msg.' ';
    }
    echo 'outer: '.$msg.' ';
    inner( $msg );
}

inner( 'test1' );  // Fatal error:  Call to undefined function inner()
outer( 'test2' );  // outer: test2 inner: test2
inner( 'test3' );  // inner: test3
outer( 'test4' );  // Fatal error:  Cannot redeclare inner()
Run Code Online (Sandbox Code Playgroud)

Mar*_*man 85

基本上没有,我一直把它当作解析器的副作用.

Eran Galperin错误地认为这些功能在某种程度上是私密的,outer()在运行之前它们只是未声明.它们也不是私人范围的,它们确实在全球范围内进行了调查,尽管延迟了.作为回调,外部回调仍然只能被调用一次.我仍然没有看到如何将它应用于一个很可能不止一次调用别名的数组.

我能挖出的唯一"现实世界"的例子就是只能运行一次并且可以重写为更清洁的IMO.

我能想到的唯一用途是模块调用[name] _include方法,该方法在全局空间中设置几个嵌套方法

if (!function_exists ('somefunc')) {
  function somefunc() { }
}
Run Code Online (Sandbox Code Playgroud)

检查.

PHP的OOP显然是更好的选择:)

  • 是的,真的.那是非常糟糕的. (9认同)
  • 即使它们不完全是私有函数,除非调用外部函数,否则它们仍然不能被调用,因此这给了它们一种依赖关系,作为与外部函数“结合”运行的函数...... (2认同)
  • 如果没有这种行为,自动加载将无法工作。如果函数内部的声明在某种程度上是私有的,那么由您的自动加载处理程序执行的包含/要求最终将什么也不做。 (2认同)

Gus*_*Gus 83

如果您使用的是PHP 5.3,则可以使用匿名函数获得更多类似Javacript的行为:

<?php
function outer() {
    $inner=function() {
        echo "test\n";
    };

    $inner();
}

outer();
outer();

inner(); //PHP Fatal error:  Call to undefined function inner()
$inner(); //PHP Fatal error:  Function name must be a string
?>
Run Code Online (Sandbox Code Playgroud)

输出:

test
test
Run Code Online (Sandbox Code Playgroud)

  • +1用于实际回答具有功能性答案的(基本上)功能主题,而不是OOP (11认同)

Sz.*_*Sz. 9

[根据@PierredeLESPINAY的评论重写.]

它根本不仅仅是副作用,而且实际上是动态修改程序逻辑的一个非常有用的功能.它来自程序化的PHP时代,但如果您想以最直接的方式为某些独立功能提供替代实现,那么它也可以与OO架构派上用场.(虽然OO在大多数情况下是更好的选择,但它是一种选择,而不是任务,而一些简单的任务不需要额外的任务.)

例如,如果您动态/有条件地从框架加载插件,并希望使插件作者的生活变得非常简单,那么您可以为插件未覆盖的一些关键函数提供默认实现:

<?php // Some framework module

function provide_defaults()
{
    // Make sure a critical function exists:
    if (!function_exists("tedious_plugin_callback"))
    {
        function tedious_plugin_callback()
        {
        // Complex code no plugin author ever bothers to customize... ;)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 但是,根据OP的说法,嵌套函数的作用域似乎不仅限于容器函数... (2认同)

cle*_*tus 7

在函数中定义的函数我看不到很多用于但有条件定义的函数我可以.例如:

if ($language == 'en') {
  function cmp($a, $b) { /* sort by English word order */ }
} else if ($language == 'de') {
  function cmp($a, $b) { /* sort by German word order; yes it's different */ }
} // etc
Run Code Online (Sandbox Code Playgroud)

然后你需要做的就是在usort()调用之类的东西中使用'cmp'函数,这样你就不会在代码中乱丢乱语言.现在我还没有这样做,但我可以看到这样做的论据.

  • 馊主意.更好:使用OO而不是破解脚本引擎细节. (2认同)

Ant*_*dge 7

综上所述,我们可以简单地创建一个嵌套函数来替换函数内的一些本地化的、重复的代码(只会在父函数内使用)。匿名函数就是一个很好的例子。

有些人可能会说只在一个类中创建私有方法(或较小的代码块),但是当一个超特定的任务(父级独有)需要模块化时,这就是一团糟,但不一定对其余部分可用一类。好消息是,如果事实证明您确实需要在其他地方使用该功能,则修复方法相当简单(将定义移至更中心的位置)。

一般来说,使用 JavaScript 作为评估其他基于 C 的编程语言的标准是一个坏主意。与 PHP、Python、Perl、C、C++ 和 Java 相比,JavaScript 绝对是它自己的动物。当然,它们之间有很多普遍的相似之处,但是在细节上(参考JavaScript: The Definitive Guide, 6th Edition, Chapters 1-12),当注意时,使核心 JavaScript 变得独特、美观、不同、简单和同时复杂。那是我的两分钱。

明确地说,我并不是说嵌套函数是私有的。当一些琐碎的事情需要模块化(并且只有父函数需要)时,嵌套可以帮助避免混乱。