Solved

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

Posted on 2013-01-25
9
603 Views
Last Modified: 2013-11-13
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.
0
Comment
Question by:mamuscia
  • 4
  • 3
  • 2
9 Comments
 
LVL 51

Expert Comment

by:ahoffmann
ID: 38821759
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
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 500 total points
ID: 38822186
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
 

Author Closing Comment

by:mamuscia
ID: 38840809
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 38844091
What was wrong with the answer?
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:mamuscia
ID: 38844807
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 38844976
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
 

Author Comment

by:mamuscia
ID: 38845052
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 38845140
OK, good.  I thought maybe something was wrong because of the marked-down grade.  Glad it's OK, ~Ray
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 38845182
ok, it works, but not as you asked for (and not as a computer should do it, IMHO;-)
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This is about my first experience with programming Arduino.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now