• Resolved Dekadinious

    (@dekadinious)


    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.

    • This topic was modified 2 years, 11 months ago by Jan Dembowski. Reason: Moved to Fixing WordPress, this is not an Developing with WordPress topic
Viewing 5 replies - 1 through 5 (of 5 total)
  • Set the WP CLI to run by actual Cron.

    If you need it triggered by user / admin rather than fixed time, then write a little script that checks for a trigger file every few minutes, then write the trigger file from PHP. If trigger exists, run the cli and delete the trigger.

    Thread Starter Dekadinious

    (@dekadinious)

    Wouldn’t that still run into timeout issues?

    Thread Starter Dekadinious

    (@dekadinious)

    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 &");
            }

    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 & in your production environment if that is running on Linux.

    • This reply was modified 2 years, 11 months ago by Dekadinious.

    I have to ask why use XAMMP on Windows to test something that is likely to be on Linux / Apache ( or another webserver ), as what ever you test will not map well.

    You can run Docker on windows instead and run a container that matches your target environment.

    Also BTW if you have control over your server have you tried just removing the timeout in PHP?

    set_time_limit(0);

    https://www.php.net/manual/en/function.set-time-limit.php

    Thread Starter Dekadinious

    (@dekadinious)

    Removing the time limit and triggering using a file checked for by Cron is one way to go. But it’s better to go via CLI IMHO. Then I can also trigger this manually from the terminal when needed and have better control over all ??

    The testing on XAMPP is just because of my lack of knowledge in the matter. I thought everything on XAMPP ran in a sort of Unix based VM, and that exec would work just like I was expecting. I have since learned that this is not the case, and that testing such operations in an environment matching production is prudent ??

    By the way, > /dev/null 2>&1 & was what was needed to get it to work in the end in production ?? It now works as a charm!

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘How to run WP-CLI command in the background from PHP?’ is closed to new replies.