1

I have to call a php "build.php" from a button action and the php will call a python script and should return immediately.

The action:

<form method="get" action="build.php">
    <input type="hidden" name="branch" value="master">
    <input type="submit" value="Build Master" id="btnMaster">
</form>

The build.php

<?php
    if(isset($_GET['branch']))
    {
        $output = shell_exec('/usr/bin/python /Users/testuser/gitroot/buildOnGuest.py --dest /Users/testuser/Builds --branch ' . $_GET['branch'] . '  2>&1 &');
    }
    elseif (isset($_GET['tag']))
    {
        $output = shell_exec('/usr/bin/python /Users/testuser/gitroot/buildOnGuest.py --dest /Users/testuser/Builds --tag ' . $_GET['tag'] . '  2>&1 &');
    }
?>

So the python script is executed in the background (&) and the php should return immediately to the main page. Is it possible and how ?

zx81
  • 41,100
  • 9
  • 89
  • 105
marco
  • 1,686
  • 1
  • 25
  • 33
  • what do you mean return immediately.. performance issue? – Drixson Oseña Mar 06 '14 at 08:08
  • if you mean redirect, [check this](http://stackoverflow.com/questions/768431/how-to-make-a-redirect-in-php) – Tommy Mar 06 '14 at 08:09
  • Try redirecting stdout of the command in `shell_exec`. – Barmar Mar 06 '14 at 08:09
  • 1
    possible duplicate of [Asynchronous shell exec in PHP](http://stackoverflow.com/questions/222414/asynchronous-shell-exec-in-php) – Durandal Mar 06 '14 at 08:09
  • No, just that I want to return to the main page and not wait the build (it takes more than 1 hour). The main page should just call the build script not go to the build.php. – marco Mar 06 '14 at 08:11
  • My problem is not how to start a shell in the background but how to not go to the build.php or go and return to the main page. The browser should start the script and stay on the main page. – marco Mar 06 '14 at 08:22
  • Use AJAX. It will call your php and you just return the python output to the main page. No reload, immediate return like you want – user3036342 Mar 06 '14 at 09:53

4 Answers4

2

If you just want redirect throght PHP, add header('Location: /path/to/index.php'); after the if clause and it will return!!!

Logically, this should work like this :

<?php
    if(isset($_GET['branch']))
    {
        $output = shell_exec('/usr/bin/python /Users/testuser/gitroot/buildOnGuest.py --dest /Users/testuser/Builds --branch ' . $_GET['branch'] . '  2>&1 &');
    }
    elseif (isset($_GET['tag']))
    {
        $output = shell_exec('/usr/bin/python /Users/testuser/gitroot/buildOnGuest.py --dest /Users/testuser/Builds --tag ' . $_GET['tag'] . '  2>&1 &');
    }

    /* add here, appending $output value for better understanding */
    header('Location: /path/to/index.php?status=$output'); 
?>
NoobEditor
  • 15,563
  • 19
  • 81
  • 112
1

Try redirecting the output to /dev/null we do something almost identical which works perfectly for what you're trying to do.

<?php
    if(isset($_GET['branch']))
    {
        $output = shell_exec('/usr/bin/python /Users/testuser/gitroot/buildOnGuest.py --dest /Users/testuser/Builds --branch ' . $_GET['branch'] . ' > /dev/null 2>/dev/null &');
    }
    elseif (isset($_GET['tag']))
    {
        $output = shell_exec('/usr/bin/python /Users/testuser/gitroot/buildOnGuest.py --dest /Users/testuser/Builds --tag ' . $_GET['tag'] . ' > /dev/null 2>/dev/null &');
    }
?>
BT643
  • 3,495
  • 5
  • 34
  • 55
  • Somehow it worked before (even thought the main page was locked) but now I cannot make it work again so I will not use this solution, sorry but thanks. – marco Mar 06 '14 at 11:56
0
set_time_limit(0);
ignore_user_abort(true);
header("Connection: close\r\n");
header("Content-Encoding: none\r\n");  
ob_start();          
echo json_encode($response);
$size = ob_get_length();   
header("Content-Length: $size",TRUE);  
ob_end_flush();
ob_flush();
flush();
session_write_close();

$response is the response that you want to send back to the calling script. Do whatever you want to after session_write_close() so that those things don't block the execution of your calling script further

rakeshjain
  • 1,791
  • 11
  • 11
  • Ok, I used your code and written a echo json_encode("started") but not solved: the build script is running and the page shows "started", it didn't return to the main page. – marco Mar 06 '14 at 08:38
  • @marco I used this with calling a page thorugh ajax and that worked. I might need to check the case with ajax – rakeshjain Mar 06 '14 at 09:02
  • Thanks but someone answered to redirect the shell to null and it actually worked but now the answer disappeared (???). – marco Mar 06 '14 at 09:11
  • @marco Sorry, was that mine? I've readded it! Thought I got the wrong end of the stick with the question but obviously not haha. http://stackoverflow.com/a/22219387/332807 – BT643 Mar 06 '14 at 09:56
0

If my other answer doesn't work you can try this:

The quickest/easiest way would probably be to load the script in an iFrame using JavaScript. This will load it without navigating away from the page.

Your page:

<form method="get" action="build.php">
    <input type="hidden" name="branch" value="master">
    <input onclick="runBuild()" type="submit" value="Build Master" id="btnMaster">
</form>

<iframe id="launch_script" name="launch_script" style="display:none"></iframe>

function runBuild(){
    document.getElementById('launch_script').src = 'build.php';
}

Note you'll probably need to pass your GET parameters along with the iFrame src.

BT643
  • 3,495
  • 5
  • 34
  • 55
  • Without passing the GET parameters, it doesn't work but I prefer anyway the solution of NoobEditor, looks cleaner. But thanks :) – marco Mar 06 '14 at 12:08