PHP Start Background Scripts in either Linux or Windows without waiting for completion

How do I start a PHP script to run in the background so my foreground process in a web browser doesn't freeze waiting for it to end.

Secnario:
User uploads a file
After saving the file, I kick off a background PHP script to process it
When the background script ends, it sends the user an email to notify them.

I've seen similar questions, but no answers or sample code to make these calls.
mamusciaAsked:
Who is Participating?
 
Ray PaseurConnect With a Mentor Commented:
You can start the script with a POST-method request. I don't know if this is limited to *nix systems (I do not use Windows servers) but I find that it works well and enables me to deal with things like external web services that are balky and inconsistent in response time.  

For example, I use the geoio.com service to geo-locate my clients.  It requires a GET request to start it, and sometimes it hangs which makes the elegant simplicity of file_get_contents() useless.  So to solve the problem of the external hang, I make a POST request to my interface script, and then forget about the success or failure of the interface.  The interface makes the GET request to geoio and updates my data base if it succeeds.  And if it fails, I can live with the partially incomplete data, since it is just mapping data for "amusement" purposes, showing here:
http://www.landonbaseball.com/site_visitors.php

The code snippet is a teaching example of how to use cURL for POST requests.

<?php // RAY_curl_post_example.php
error_reporting(E_ALL);


// DEMONSTRATE HOW TO USE CURL POST TO START AN ASYNCHRONOUS PROCESS


function curl_post($url, $post_array=array(), $timeout=2, $error_report=FALSE)
{
    // PREPARE THE POST STRING
    $post_string = NULL;
    foreach ($post_array as $key => $val)
    {
        $post_string .= $key . '=' . urlencode($val) . '&';
    }
    $post_string = rtrim($post_string, '&');

    // PREPARE THE CURL CALL
    $curl = curl_init();
    curl_setopt( $curl, CURLOPT_URL,            $url         );
    curl_setopt( $curl, CURLOPT_HEADER,         FALSE        );
    curl_setopt( $curl, CURLOPT_POST,           TRUE         );
    curl_setopt( $curl, CURLOPT_POSTFIELDS,     $post_string );
    curl_setopt( $curl, CURLOPT_TIMEOUT,        $timeout     );
    curl_setopt( $curl, CURLOPT_RETURNTRANSFER, TRUE         );

    // EXECUTE THE CURL CALL
    $htm = curl_exec($curl);
    $err = curl_errno($curl);
    $inf = curl_getinfo($curl);

    // ON FAILURE
    if (!$htm)
    {
        // PROCESS ERRORS HERE
        if ($error_report)
        {
            echo "CURL FAIL: $url TIMEOUT=$timeout, CURL_ERRNO=$err";
            echo "<pre>\n";
            var_dump($inf);
            echo "</pre>\n";
        }
        curl_close($curl);
        return FALSE;
    }

    // ON SUCCESS
    curl_close($curl);
    return $htm;
}


// USAGE EXAMPLE CREATES ASSOCIATIVE ARRAY OF KEY=>VALUE PAIRS
$args["name"]  = 'Ray';
$args["email"] = 'Ray.Paseur@Gmail.com';

// ACTIVATE THIS TO SEE THE ARRAY OF ARGS
// var_dump($args);

// SET THE URL
$url = "http://LAPRBass.com/RAY_bounce_post.php";

// CALL CURL TO POST THE DATA
$htm = curl_post($url, $args, 3, TRUE);

// SHOW WHAT CAME BACK, IF ANYTHING
if ($htm)
{
    echo "<pre>";
    echo htmlentities($htm);
}
else
{
    echo "NO RESPONSE YET FROM $url -- MAYBE BECAUSE IT IS RUNNING ASYNCHRONOUSLY";
}

Open in new window

0
 
ahoffmannCommented:
on *ix it's as simple as
  exec("whatever &");
( also possible system(), passthru(), shell_exec() ...)
or more elegant using pcntl_fork(), see http://php.net/manual/en/function.pcntl-fork.php
or probably simply using fork()

on windows ... have fun :-/  (example never tested):
pclose(popen("start whatever", "r"));
0
 
mamusciaAuthor Commented:
Ray,
Not sure how this is working, but it does. My calling script continues without holding up the user and the script I call with CURL completes.  I know this is not asynchronous really, but it is doing what I want in both Windows and Linux environments.  Thanks for the technique.
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
Ray PaseurCommented:
What was wrong with the answer?
0
 
mamusciaAuthor Commented:
Nothing wrong per say, but it's not really starting a parallel asynch task as I wanted. It works, but that's because we don't care what the output is and don't do anything if we don't get it.
0
 
Ray PaseurCommented:
OK, then tell me what this means:  this is not asynchronous really.  Perhaps you and I have different definitions of "asynchronous."

As I understand the issue, your file upload completes very fast, but the processing of the file takes a very long time, so much so, that the client is made to wait much longer for the processing than for the upload.  So you want to decouple the upload from the long, slow processing step.  In that sense it's not a description of an asynchronous task - it's a description of a sequential process involving two tasks.  There is nothing at all standing in the way of sending an email from the second script when it is completed.  You would want to be very careful about debugging this script because the client cannot see any browser output, but it's certainly not a case of "don't care."  In MY application, I don't care.  But that is not the same as saying the process is flawed in some way.
0
 
mamusciaAuthor Commented:
Well, you are correct. I apologize if it sounded like I didn't think the solution was good.  I do and I'm using it.  I understand what you're saying about sequential versus asynch processing. I just really wanted to understand how I start a PHP script from either LAMP or WAMP environment by calling PHP and passing it the script to run.  Kind of like we run CRON jobs. It starts a PHP instance and passes it the script name.  It runs completely standalone from any other script.  From what I understand of your solution, it essentially does the same thing and won't tie anything to the users login session, so that's really the equivalent of what I'm after.  Thanks for your knowledge, I've been trying all kinds of things to get it to work in Windows to no avail. The solution hoffmann gave about works for Linux.  Your solution works in both.
0
 
Ray PaseurCommented:
OK, good.  I thought maybe something was wrong because of the marked-down grade.  Glad it's OK, ~Ray
0
 
ahoffmannCommented:
ok, it works, but not as you asked for (and not as a computer should do it, IMHO;-)
0
All Courses

From novice to tech pro — start learning today.