简体   繁体   English

PHP找不到动态生成的函数

[英]PHP can't find dynamically generated function

Note: While the issue occurred trying to solve a WordPress problem, the problem being faced right now (see "Current Approach", below) is clearly a PHP issue, which is why it's been posted here.注意:虽然该问题是在试图解决 WordPress 问题时发生的,但现在面临的问题(请参阅下面的“当前方法”)显然是 PHP 问题,这就是将其发布在这里的原因。

TL;DR:特尔;博士:

I'm dynamically generating PHP code in a file and including that file after it's finished being written to, however PHP cannot call functions from inside the file—even when including it directly without making any changes.我在文件中动态生成 PHP 代码并在完成写入后包含该文件,但是 PHP 无法从文件内部调用函数 - 即使直接包含它而不进行任何更改。

Preface前言

I've been working on a system for dynamically generating shortcodes in WordPress, and have been running into one serious roadblock along the way: Registering the functions for the shortcodes.我一直在研究一种在 WordPress 中动态生成短代码的系统,并且在此过程中遇到了一个严重的障碍:注册短代码的功能。

Long story short is that we've got a list of options stored in an array similar to the following:长话短说,我们有一个存储在数组中的选项列表,类似于以下内容:

$array = array(
    0 => array(
        'code' => 'my-shortcode',
        'replacement' => 'replacement_directives_here'
    )
);

I've already got a system that processes the codes and sends generates the proper output based on the directives.我已经有了一个处理代码并发送的系统,它会根据指令生成正确的输出。 It's getting the call to add_shortcode($shortcode, $callback) to work.它正在调用add_shortcode($shortcode, $callback)工作。

My first strategy was to use anonymous functions in a manner similar to the following:我的第一个策略是以类似于以下的方式使用匿名函数:

foreach ($array as $code => $directions) {
    $GLOBALS['my_shortcode_output'] = my_shortcode_process($directions);

    add_shortcode($code, function() { return $GLOBALS['my_shortcode_output']; });
}

However this ended up with successive directives overwriting each other due to the fluctuating content of the global, so I decided to try something different...然而,由于全局内容的波动,这最终导致连续的指令相互覆盖,所以我决定尝试一些不同的......

Current Approach当前方法

As a workaround to having the information I need constantly slipping just out of reach, I decided to try something different:为了让我需要的信息不断地滑落到够不到的地方,我决定尝试一些不同的方法:

  • Create a file within my plugin在我的插件中创建一个文件
  • Write out the PHP code for the functions I wanted to include so that they were guaranteed to generate the right output写出我想要包含的函数的 PHP 代码,以便保证它们生成正确的输出
  • Include the file after the fclose() callfclose()调用之后包含文件
  • Register the shortcodes, referencing the functions in the new file注册短代码,引用新文件中的函数

The code for generating the file looks something like the following:生成文件的代码如下所示:

$file = fopen(PATH_TO_FILE, 'w'); // Open for writing only, truncate file on opening
fwrite($file, "<?php\n\n"); // Using double quotes so newlines and escapes don't get counted as literals

// foreach through list
foreach ($shortcode_list as $shortcode) {
    if ($shortcode['code'] != '') {
        // Append new function with a dynamic name (e.g. $shortcode[code]._sc') to dynamic_shortcodes.php
        // Function should consist of: return my_shortcode_process($shortcode['replacement']);
        // Hard-coding so we don't get frozen if information gets changed
        $new_function = "\tfunction str_replace('-', '_', $shortcode['code'])."_sc() {\n\t\treturn my_shortcode_process('".$shortcode['replacement']."');\n\t}\n\n";

        fwrite($file, $new_function);

        // Add function name to $shortcode_functions array, keyed on the shortcode
        $shortcode_functions[$shortcode['code']] = str_replace('-', '_', $shortcode['code']).'_sc';
    }
}

fclose($file); // Close the file, since we are done writing to it
touch(PATH_TO_FILE); // Ensure the file's modification time is updated

After that it's just a simple loop to register them:之后,它只是一个简单的循环来注册它们:

foreach ($shortcode_functions as $shortcode => $callback) {
    add_shortcode($shortcode, $callback);
}

When I reload and run everything, however, I get the following:但是,当我重新加载并运行所有内容时,我得到以下信息:

Notice: do_shortcode_tag was called incorrectly.注意: do_shortcode_tag 被错误调用。 Attempting to parse a shortcode without a valid callback: [SHORTCODE HERE] .尝试在没有有效回调的情况下解析短代码: [SHORTCODE HERE] Please see Debugging in WordPress for more information.有关更多信息,请参阅在 WordPress 中调试。

I've downloaded the file and verified its contents—everything checks out in PHPstorm.我已经下载了文件并验证了它的内容——一切都在 PHPstorm 中检查出来了。 It's properly formatted, there are no syntax errors, and the functions it depends upon are already loaded and working fine.它的格式正确,没有语法错误,它所依赖的函数已经加载并且工作正常。

Even skipping the whole process and just directly including the file and then calling one of the functions inside it isn't working.即使跳过整个过程并直接包含文件,然后调用其中的一个函数也不起作用。 It's like the file has been blackballed.就像文件被黑了一样。 At the same time, however, neither include() nor require() produce any errors.然而,同时,include() 和 require() 都不会产生任何错误。

Is this a caching issue, perhaps?这可能是缓存问题吗?

Honestly, I'm totally unable to understand what you're trying to do (or even why) but PHP doesn't have any problem with dynamically generated includes.老实说,我完全无法理解您要做什么(甚至为什么),但 PHP 对动态生成的包含没有任何问题。 This works fine:这工作正常:

<?php

$file = __DIR__ . '/foo-' . mt_rand(0, PHP_INT_MAX) . '.php';
$code = '<?php

function foo() {
    echo "Hello, World!";
};
';
file_put_contents($file, $code);

require $file;
foo();

However, you're apparently trying to execute something like this:但是,您显然正在尝试执行以下操作:

function str_replace('-', '_', $shortcode['code'])."_sc(){
}

That's a blatant syntax error either in included files on in the main script.这是一个明显的语法错误,无论是在主脚本中的包含文件中。 If you follow the Please see Debugging in WordPress for more information instructions you'll possibly find something similar to this:如果您按照请参阅在 WordPress 中调试以获取更多信息说明,您可能会找到类似的内容:

Parse error: syntax error, unexpected ''-'' (T_CONSTANT_ENCAPSED_STRING), expecting variable (T_VARIABLE)解析错误:语法错误,意外的“-”(T_CONSTANT_ENCAPSED_STRING),需要变量(T_VARIABLE)

A syntax for variable functions that works could be:有效的变量函数的语法可能是:

$name = str_replace('-', '_', $shortcode['code']) . '_sc';
$name = function (){
};

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

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