【问题标题】:PHP 7.2 Function create_function() is deprecatedPHP 7.2 函数 create_function() 已弃用
【发布时间】:2018-01-09 04:39:25
【问题描述】:

我在下面的应用程序中使用了create_function

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

但对于 PHP 7.2.0,create_function() 已弃用。

如何在 PHP 7.2.0 上修复我上面的代码。

【问题讨论】:

  • 如果可以解决问题,您可以创建一个匿名函数
  • 我们可以看看你更大的preg_ 代码块吗?

标签: php


【解决方案1】:

您应该能够使用Anonymous Function(又名闭包)调用父级范围$delimiter 变量,如下所示:

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

【讨论】:

    【解决方案2】:

    我想贡献一个我在 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() 来创建函数。希望对您有所帮助。

    【讨论】:

    • 实际上是一个匿名函数(闭包)并且已经由@e_i_pi 发布:)
    • @Dwza 是的,我只是想多扩展一点这个话题。仅此而已。
    • 看到一个例子对我很有帮助。谢谢@Joanmacat!
    • 因为我一直在寻找特定于 WordPress 的修复程序,所以我喜欢您的示例。有其他用例总是好的,即使已经有一个批准的答案......
    【解决方案3】:

    自动升级

    如果有人需要将代码中的数十个 create_function() 案例升级为匿名函数,我会开发一个名为 Rector 的工具。

    它遍历代码并用匿名函数 1:1 替换 create_function。它已在 30 various cases 上进行了测试。

    安装

    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
    

    编辑: 2020 年 10 月 31 日更新为 PHP Rector 0.8.x 语法

    【讨论】:

    • 不知道为什么这不起作用。它可能需要更多信息,或者发生了变化。我创建了 yml 文件,但它总是说无法加载资源。当我使用 php 文件时,一切正常。
    • 哦,yml 文件已被弃用数月之久。我会更新这篇文章,谢谢你告诉我!
    • 最好澄清一下命令行中的“src”,需要更改文件中的“/src”以匹配用户的路径。这也是文档中缺少的东西。它只是假设人们知道如何处理它,或者首先要对其进行更改。
    • 好点。我会在这里更新答案。你能帮我把 PR 发送到 GitHub 上的文档 README 吗?
    【解决方案4】:

    这个匿名函数数组对我有用,见下面的代码:

    // 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 语句的输出,然后只需将函数重新映射到您自己的意愿!

    快乐编码 =)

    【讨论】:

      【解决方案5】:

      从 PHP 7.4 开始,您可以使用 Arrow function:

      $callbacks[$delimiter] = fn($matches) => $delimiter . strtolower($matches[1]);
      

      箭头函数比匿名函数短,并且使用父作用域 - 所以你可以引用 $delimiter 而无需传入它。

      【讨论】:

      • 顺便说一句,我在 MachForm 使用的 Braintree 库中看到了这行确切的代码,在一个 sn-p 中,IMO 无论如何都不应该使用 create_function(出于垃圾收集的原因)。巧合?
      【解决方案6】:

      接受的答案是正确的方法。 但是,在某些情况下您不能更改代码(遗留代码、复杂环境)。对于这种情况,我写了一个包:

      https://github.com/lombax85/create_function

      composer require lombax85/create_function安装它

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-03
        • 2020-05-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多