0

I have a long running script in WordPress that creates a report and writes it to an Excel-file, before sending it by email to the user. This project is now complicated enough that I run into timeout issues. I have therefore moved the script into WP-CLI.

I have a button in the Wordpress admin panel that fires an AJAX-request to run a function hooked into wp_ajax_{$action}. Then I was planning on running the WP-CLI-command with WP_CLI::runcommand() inside the function called by AJAX. The problem is that WP_CLI is not available at this point. I then tried to use exec and shell_exec:

exec("wp command_name args");

This works as I want it to, but it blocks the script from continuing, and the browser waits for the AJAX-request to finish. Ok, so I thought I would find a way to run this WP-CLI-command in the background somehow. I have tried everything I could find, but I can't get it to work.

This runs the command, but PHP hangs and is blocked until the command finishes:

exec("wp command_name args");
exec("wp command_name args > log.txt &");
exec("wp command_name args > NUL &");
exec("wp command_name args > \$null &");
shell_exec("wp command_name args");
shell_exec("wp command_name args > log.txt &");
shell_exec("wp command_name args > NUL &");
shell_exec("wp command_name args > \$null &");

These work for getting the non-blocking functionality I am after, but the command seem to not run at all (I at least get no error messages in the Apache log, and the file the command is supposed to create is never created):

exec("wp command_name args > /dev/null &");
exec("wp command_name args > /dev/null 2>&1 &");
exec("nohup wp command_name args > log.txt &");
exec("wp command_name args > /dev/null 2>/dev/null &");
exec("wp command_name args &> /dev/null &");
shell_exec("wp command_name args > /dev/null &");
shell_exec("wp command_name args > /dev/null 2>&1 &");
shell_exec("nohup wp command_name args > log.txt &");
shell_exec("wp command_name args > /dev/null 2>/dev/null &");
shell_exec("wp command_name args &> /dev/null &");

I can't for the life of me figure out how to run a WP-CLI command from PHP, but let it run in the background and do its thing without halting PHP execution.

I am on XAMPP for Windows 10 right now for testing, if that matters.

TASan
  • 115
  • 10
  • Duplicate of [Asynchronous shell exec in PHP](https://stackoverflow.com/questions/222414/asynchronous-shell-exec-in-php) – esqew Dec 07 '21 at 11:50
  • @esqew I have tried to make it more clear what exactly I have tried as you suggested. I have also tried what is in the accepted answer of the possible duplicate, and it's not working. I don't consider this a duplicate because of that. – TASan Dec 07 '21 at 12:09
  • The third-rated answer of the linked duplicate shows that there is a specific solution that should be used in Windows execution environments; why stop at the accepted answer when it’s Unix/bash specific…? – esqew Dec 07 '21 at 12:48
  • @esqew Yes, you're right. My knowledge of the subject did not reach to the point where I was able to connect the dots. A little hint could've helped, but it now works ;) – TASan Dec 07 '21 at 13:39

1 Answers1

2

The problem is that XAMPP on Windows won't run these things in the background the way Unix-based systems will. I thought XAMPP running Apache etc. would be enough, but it's not.

    if (substr(php_uname(), 0, 7) == "Windows") {
        pclose(popen("start /B " . $cmd, "r"));
    } else {
        exec($cmd . " > /dev/null 2>&1 &");
    }

The above code will work. You need to use pclose and popen in your local environment if that is on Windows. Then you can use the normal > /dev/null 2>&1 & in your production environment if that is running on Linux.

TASan
  • 115
  • 10