You should be able to use an Anonymous Function (aka Closure) with a call to the parent scoped $delimiter
variable, like so:
您应该能够通过调用父范围的$DELIMITER变量来使用匿名函数(也称为闭包),如下所示:
$callbacks[$delimiter] = function($matches) use ($delimiter) {
return $delimiter . strtolower($matches[1]);
};
I would like to contribute with a very simple case I found in a Wordpress Theme and seems to work properly:
我想用我在WordPress主题中找到的一个非常简单的案例来贡献自己的力量,这个案例似乎工作正常:
Having the following add_filter statement:
具有以下ADD_FILTER语句:
add_filter( 'option_page_capability_' . ot_options_id(), create_function( '$caps', "return '$caps';" ), 999 );
Replace it for:
将其替换为:
add_filter( 'option_page_capability_' . ot_options_id(), function($caps) {return $caps;},999);
We can see the usage of function(), very typical function creation instead of a deprecated create_function() to create functions.
我们可以看到Function()的用法,这是非常典型的函数创建,而不是不建议使用的Create_Function()来创建函数。
Automated Upgrade
If anyone needs to upgrade dozens of create_function()
cases in their code to anonymous functions, I work on a tool called Rector.
如果任何人需要将代码中的数十个createFunction()用例升级为匿名函数,我使用的是一个名为Rector的工具。
It goes through the code and replaces the create_function
with anonymous functions 1:1. It's tested on 30 various cases.
它遍历代码并用匿名函数1:1替换CREATE_Function。它在30种不同的情况下进行了测试。
Install
安装
composer require rector/rector --dev
Setup
布设
Let's say you want to upgrade code in the /src
directory.
假设您想要升级/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);
};
Run on your code
在您的代码上运行
# 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
EDIT: Updated 2020-10-31 with PHP Rector 0.8.x syntax
编辑:使用PHP Rector 0.8.x语法更新2020-10-31
Since PHP 7.4 you can use an Arrow function:
从PHP 7.4开始,您可以使用Arrow函数:
$callbacks[$delimiter] = fn($matches) => $delimiter . strtolower($matches[1]);
Arrow functions are shorter than anonymous functions, and use the parent scope - so you can refer to $delimiter without passing it in.
箭头函数比匿名函数短,并且使用父作用域,因此您可以引用$delimiter而无需传递它。
This Array of Anonymous functions worked for me, see code below:
这个匿名函数数组适用于我,请参阅下面的代码:
// 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();
Just copy this into your script file and you will see the output from the echo
statements, then simply remap the function to your own will!
只需将它复制到您的脚本文件中,您就会看到ECHO语句的输出,然后只需将函数重新映射到您自己的意愿!
Happy coding =)
快乐编码=)
The anonymous function solution works, but if the expression to be returned is in a string I think eval
should be used.
匿名函数解决方案是有效的,但如果要返回的表达式是字符串,我认为应该使用val。
$callbacks[$delimiter] = eval('return function($matches){return '.$delimiter.' . strtolower($matches[1]);};');
更多回答
what actually is a anonymos function (closure) and was already posted by @e_i_pi :)
什么是匿名函数(闭包),@e_i_pi已经发布了:)
@Dwza Yep, only I was to extend a bit more this topic. Nothing more.
@Dwza是的,只是我在这个话题上做了更多的扩展。仅此而已。
I was very helpful to see an example. Thanks @Joanmacat!
看到这样一个例子,我很有帮助。谢谢@Joanmacat!
Because I was looking for a WordPress-specific fix, I liked your example. It's always good to have additional use-cases, even if there already was an approved answer...
因为我正在寻找特定于WordPress的修复程序,所以我喜欢您的例子。有更多的用例总是好的,即使已经有了批准的答案……
Not sure why this isn't working. It may need more information, or there has been a change. I created the yml file, but it always says cannot load resource. When I use the php file, things work fine though.
不知道为什么这不管用。它可能需要更多信息,或者已经发生了变化。我创建了YML文件,但它总是显示无法加载资源。不过,当我使用php文件时,一切工作正常。
Oh, the yml file is deprecated for coupled of months. I'll update this post, thanks for letting me know!
哦,YML文件已经被弃用了好几个月了。我会更新这个帖子,谢谢你让我知道!
It may be good to clarify that "src" on the command line, and '/src' in the file need to be changed to match the user's path. That is something lacking in the documentation too. It just assumes that people know what to do with it, or that it's there to be changed in the first place.
澄清命令行中的“src”和文件中的‘/src’需要更改以匹配用户的路径可能是很好的做法。这也是文档中缺少的东西。它只是假设人们知道如何处理它,或者它一开始就会被改变。
Good point. I'll update the answer here. Could you help me and send send PR to documentation README on GitHub?
说得好。我会在这里更新答案。你能帮我把PR发送到GitHub上的文档自述文件中吗?
I tested this out on a some old WordPress plugins that are going to die when PHP is upgraded to 8.x. It totally worked! Here's a link to the repo with the latest code: github.com/rectorphp/rector
我在一些旧的WordPress插件上测试了这一点,当PHP升级到8.x时,这些插件将会消亡。它完全成功了!以下是带有最新代码的repo的链接:githeb.com/rectorphp/rector
As an aside, I see this exact line of code in the Braintree lib used by MachForm, in a snippet that IMO should not be using create_function anyways (for garbage-collection reasons). Coincidence?
顺便说一句,我在MachForm使用的Braintree库中看到了这行代码,其中包含IMO无论如何都不应该使用CREATE_Function的代码片段(出于垃圾收集的原因)。巧合?
我是一名优秀的程序员,十分优秀!