什么是PHP嵌套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() 

基本上没有,我一直把它当作parsing器的一个副作用。

Eran Galperin错误地认为这些函数在某种程度上是私有的,直到outer()运行时才被声明。 他们也不是私人范围的,他们确实在全球范围内进行监督,尽pipe延迟了。 而作为callback,外部callback仍然只能被调用一次。 我仍然没有看到如何将它应用于一个很可能不止一次调用别名的数组。

我唯一可以挖掘的“真实世界”例子就是只能运行一次,可以重写清洁IMO。

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

 if (!function_exists ('somefunc')) { function somefunc() { } } 

检查。

PHP的面向对象显然是一个更好的select:)

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

 <?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 ?> 

输出:

 test test 

[根据@PierredeLESPINAY的评论重写]

这不仅仅是一个副作用,而且实际上是一个非常有用的function, 可以dynamic修改程序的逻辑。 它来自程序化的PHP时代,但是如果您想以最直接的方式为某些独立function提供替代实现,也可以与OO体系结构一起使用。 (虽然OO在大多数情况下是更好的select,但这是一个选项,而不是一个任务,一些简单的任务不需要额外的东西。)

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

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

在函数中定义的函数我不能看到太多的用途,但条件定义的函数我可以。 例如:

 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 

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

我所有的PHP都是OO,但是我确实看到了嵌套函数的用法,特别是当你的函数是recursion的而不一定是一个对象的时候。 也就是说,它不会在被嵌套的函数之外调用,而是recursion的,随后需要成为一个函数。

为了明确使用其他方法而做出新的方法是没有意义的。 对我来说,这是笨拙的代码和sorting – 不是面向对象。 如果你永远不会在其他任何地方调用这个函数,就把它嵌套。

在web服务调用中,我们发现它dynamic地包括一个嵌套式的内存和速度要低得多的开销(存储器和速度),在满足1000个函数的库上有单独的函数。 典型的调用栈可能在5-10个调用深度之间,只需要dynamic链接一个1-2kb的文件比包括兆字节更好。 这是通过创build一个小的util函数包装需要完成的。 包含的函数嵌套在调用堆栈上方的函数中。 考虑到这一点,而不是每个Web服务调用都需要的100个函数类,而且也可以使用php的内置延迟加载特性。

上面所说的,可以简单地创build一个嵌套函数来replace函数中的一些本地化,重复的代码(只会在父函数中使用)。 有些人可能会说只是创build私有方法(或者更小的代码块),但是当一个超级特定的任务(这是父级专有的)需要模块化,但是不一定对其他人可用时,或程序性程序中的全球空间)。 好消息是,如果事实certificate,你确实需要在其他地方的function,修复是相当初级(移动定义到一个更加中心的位置)。

一般来说,使用JavaScript作为评估其他C语言编程语言的标准是一个坏主意。 与PHP,Python,Perl,C,C ++和Java相比,JavaScript绝对是它自己的动物。 当然,这里有很多相似的地方,但是当注意时,细节(参考JavaScript:权威指南,第6版,第1-12章 )使得核心JavaScript独特,美观,不同,简单,所有在同一时间复杂。 那是我的两分钱

只是要清楚,我不是说嵌套函数是私有的。 只要嵌套可以帮助避免混乱,当一些微不足道的需要模块化(只有父function需要)。

嵌套函数在Memoization(caching函数结果以提高性能)中很有用。

 <?php function foo($arg1, $arg2) { $cacheKey = "foo($arg1, $arg2)"; if (! getCachedValue($cacheKey)) { function _foo($arg1, $arg2) { // whatever return $result; } $result = _foo($arg1, $arg2); setCachedValue($cacheKey, $result); } return getCachedValue($cacheKey); } ?> 

如果要嵌套函数使用在父函数中声明的variables,则嵌套函数非常有用。

 <?php ParentFunc(); function ParentFunc() { $var = 5; function NestedFunc() { global $var; $var = $var + 5; return $var; }; echo NestedFunc()."<br>"; echo NestedFunc()."<br>"; echo NestedFunc()."<br>"; } ?>