1

To try a background test, I create 3 files:

Index.html (Responsible for calling a php file by ajax)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Background Task Manager</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<body>

Press The Button To execute a Background Task...
<br>
<button id="perform">Perform Task</button>

</body>

<script>

$( document ).ready(function() {

    $( "#perform" ).click(function() {
      submitAjax();
    });

    function submitAjax() {
            $.ajax({
                url: 'test.php',
                type: "post",
                data: '',
                success: function (data) {
                    alert(data);
                }
            });
        }

});

</script>

</html>

Test.php (The file who call another file using a background method)

<?php

//Perform Background Task

exec("C:/wamp/bin/php/php5.6.35/php.exe C:/wamp/www/background/file.php");

echo "Process Started";

?>

File.php (The file that will be executed in background)

<?php

//Create a File

sleep(20);

$content = "My Text File";
$fp = fopen("myText.txt","wb");
fwrite($fp,$content);
fclose($fp);

echo "File Created...";

?>

The idea would be as follows: Once the user clicks the button, a request is made to the test.php file. The test.php will trigger a background request for the file.php, the message ('Process Started') will appear immediately, and 20 seconds after a file would be created in my project folder.

What is happening: When the user clicks the button, I only receive the message 'Process Started' 20 seconds later, ie the request is not being made in background mode.

What I wish to happen: When the user clicks the button, the message 'Process Started' will appear immediately, and 20 seconds later php will create the file in the folder of my project.

How can I solve this problem ?

Lucas Pillote
  • 11
  • 1
  • 3
  • " Note: If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends." http://php.net/manual/en/function.exec.php –  Jun 14 '18 at 22:15
  • I've seen this with WordPress as a some what hilarious/ingenious solution to makeup for a lack of "cron", but the main executing php "thread" triggers a HTTP get with a very short timeout (0.01 seconds) where the php "worker" thread employs `ignore_user_abort()` and does the tasks it needs. see `function spawn_cron()` in `app/wp-includes/cron.php` – Scuzzy Jun 14 '18 at 22:33

2 Answers2

1

try change:

exec("C:/wamp/bin/php/php5.6.35/php.exe C:/wamp/www/background/file.php");
echo "Process Started";

to:

ob_start();
echo "Process Started";
ob_end_flush();
ob_flush();
flush();
exec("C:/wamp/bin/php/php5.6.35/php.exe C:/wamp/www/background/file.php");

related answer for your question: continue processing php after sending http response

and you may also using include instead of using exec() it will be like:

start();
echo "Process Started";
ob_end_flush();
ob_flush();
flush();

include 'background/file.php';

so you can debug file.php more easy

Erlang Parasu
  • 183
  • 2
  • 3
  • 8
0

Why would you call exec from php to run a php shell? It makes no sense. Why not just call file.php directly?

The echo is within the ajax call, so it won't be seen; it will be returned as page output. Typically for something like this, you need to use a field:

<?
    <p class="Message"></p>
    <button onclick="foo()">Click Me</button>
    <script>
        function foo(){
           $('.Message').text('Processing.....');
           $.post('file.php',function(ret){
               // ret should tell us what happened
               if (ret == "ok")
                   $('.Message').text('File Created');
               else
                   $('.Message').text('File Not Created. Something Went Wrong');
           });
         }
     </script>

file.php should create the file, test that the file is created and return a value that can be tested to see if the operation was successful. You can also examine ret in console.log to see if you're getting any syntax errors or exceptions. Anything output on the page will be returned, so you might not get a clean response. Best have file.php echo something:

if ($file_created)
    echo "ok";
else
    echo "failed";
Danial
  • 1,496
  • 14
  • 15