我在下面的应用程序中使用了
create_function()
。
$callbacks[$delimiter] = create_function('$matches', "return '$delimiter' . strtolower(\$matches[1]);");
但对于 PHP 7.2.0,
create_function()
已弃用。
如何为 PHP 7.2.0 重写上面的代码?
您应该能够使用匿名函数(又名闭包)来调用父作用域
$delimiter
变量,如下所示:
$callbacks[$delimiter] = function($matches) use ($delimiter) {
return $delimiter . strtolower($matches[1]);
};
我想贡献一个我在 WordPress 主题中发现的非常简单的案例,并且似乎工作正常:
具有以下 add_filter 语句:
add_filter(
'option_page_capability_' . ot_options_id(),
create_function( '$caps', "return '$caps';" ),
999
);
替换为:
add_filter(
'option_page_capability_' . ot_options_id(),
function($caps) {return $caps;},
999
);
我们可以看到
function()
的用法,这是非常典型的函数创建,而不是使用已弃用的create_function()
来创建函数。
如果有人需要将代码中的数十个
create_function()
案例升级为匿名函数,我会开发一个名为 Rector 的工具。
它遍历代码并用匿名函数 1:1 替换
create_function
。经过30种不同情况测试。
安装
composer require rector/rector --dev
设置
假设您要升级
/src
目录中的代码。
# rector.php
<?php
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Rector\Php72\Rector\FuncCall\CreateFunctionToAnonymousFunctionRector;
return static function (ContainerConfigurator $containerConfigurator) {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [
__DIR__ . '/src',
]);
$services = $containerConfigurator->services();
$services->set(CreateFunctionToAnonymousFunctionRector::class);
};
运行您的代码
# this is set run, it only report what it would change
vendor/bin/rector process --config rector.php --dry-run
# this actually changes the code
vendor/bin/rector process --config rector.php
# the "rector.php" config is loaded by default, so we can drop it
vendor/bin/rector process
编辑: 使用 PHP Rector 0.8.x 语法更新了 2020 年 10 月 31 日
从 PHP 7.4 开始,您可以使用 箭头函数:
$callbacks[$delimiter] = fn($matches) => $delimiter . strtolower($matches[1]);
箭头函数比匿名函数短,并且使用父作用域 - 因此您可以引用 $delimiter 而无需传入它。
这个匿名函数数组对我有用,请参阅下面的代码:
// This will be a dynamic name that could
// be used as a function like "namespace".
$dynamic_name = 'my_dynamic_name';
// Here's some variables that you could use in the scope of
// your dynamic anonymous functions.
$outerVariable = 'If I need this varible, I can use it';
$outerVariableTwo = 'If I need this varible, I can use it too!';
// Create an array that we can later use and turn into
// and associative array with our new dynamic anonymous functions.
$dynamicAnonFunctions = [];
// Create the first dynamic function.
$dynamicAnonFunctions[($dynamic_name."_func_one")] = function () use ($outerVariable, $dynamic_name) {
echo 'Running: function <b>'.$dynamic_name .'_func_one()</b>';
echo '<br><br>';
echo $outerVariable;
echo '<br><br>';
echo 'This works :)';
echo '<br><br>';
};
// Create the second dynamic function
$dynamicAnonFunctions[($dynamic_name."_func_two")] = function () use ($outerVariableTwo, $dynamic_name) {
echo '- - - - - - - - - - - - - - - - - - - ';
echo '<br><br>';
echo 'Running: function <b>'.$dynamic_name .'_func_two()</b>';
echo '<br><br>';
echo $outerVariableTwo;
echo '<br><br>';
echo 'This also works :)!';
echo '<br><br>';
};
// Call the functions.
$dynamicAnonFunctions[($dynamic_name."_func_one")]();
$dynamicAnonFunctions[($dynamic_name."_func_two")]();
// Halt execution.
exit();
只需将其复制到脚本文件中,您就会看到
echo
语句的输出,然后只需将函数重新映射到您自己的意愿即可!
快乐编码=)
匿名函数解决方案有效,但如果要返回的表达式位于字符串中,我认为应该使用
eval
。
$callbacks[$delimiter] = eval('return function($matches){return '.$delimiter.' . strtolower($matches[1]);};');