简体   繁体   English

PHP 7.2 Function create_function() 已弃用

[英]PHP 7.2 Function create_function() is deprecated

I have used create_function() in my application below.我在下面的应用程序中使用了create_function()

$callbacks[$delimiter] = create_function('$matches', "return '$delimiter' . strtolower(\$matches[1]);");

But for PHP 7.2.0, create_function() is deprecated.但是对于 PHP 7.2.0,不推荐使用create_function()

How do I rewrite my code above for PHP 7.2.0?如何为 PHP 7.2.0 重写上面的代码?

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() 来创建函数。 Hope it helps.希望能帮助到你。

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 .如果有人需要将其代码中的数十个create_function()案例升级为匿名函数,我将使用一个名为Rector的工具。

It goes through the code and replaces the create_function with anonymous functions 1:1.它遍历代码并将create_function替换为匿名函数 1:1。 It's tested on 30 various cases .它在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

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 =)快乐编码 =)

Since PHP 7.4 you can use an Arrow function :自 PHP 7.4 起,您可以使用箭头函数

$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 的情况下引用它。

匿名函数解决方案有效,但如果要返回的表达式在字符串中,我认为应该使用eval

$callbacks[$delimiter] = eval('return function($matches){return '.$delimiter.' . strtolower($matches[1]);};');

The accepted answer is the right way.接受的答案是正确的方法。 However, there are cases where you CANNOT change the code (legacy code, complex environment).但是,在某些情况下您不能更改代码(遗留代码、复杂环境)。 For that case I wrote a package:对于那种情况,我写了一个包:

https://github.com/lombax85/create_function https://github.com/lombax85/create_function

install it with composer require lombax85/create_function使用composer require lombax85/create_function安装它composer require lombax85/create_function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM