【问题标题】:Call a php and return immediately调用一个php并立即返回
【发布时间】:2014-04-08 17:44:09
【问题描述】:

我必须通过按钮操作调用 php“build.php”,然后 php 将调用 python 脚本并应立即返回。

动作:

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

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

所以python脚本在后台(&)执行,php应该立即返回到主页面。有可能吗?如何实现?

【问题讨论】:

  • 什么意思是立即返回.. 性能问题?
  • 如果你的意思是重定向,check this
  • 尝试重定向shell_exec中命令的标准输出。
  • 不,只是我想返回主页而不是等待构建(需要1个多小时)。主页应该只调用构建脚本而不是去 build.php。

标签: php html web


【解决方案1】:

如果你只是想通过 PHP 重定向,在 if 子句之后添加 header('Location: /path/to/index.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 &');
    }

    /* add here, appending $output value for better understanding */
    header('Location: /path/to/index.php?status=$output'); 
?>

【讨论】:

    【解决方案2】:

    尝试将输出重定向到/dev/null,我们会做一些几乎相同的事情,这非常适合您尝试做的事情。

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

    【讨论】:

    • 之前它以某种方式工作(甚至认为主页被锁定)但现在我无法让它再次工作,所以我不会使用这个解决方案,对不起,但谢谢。
    【解决方案3】:
    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 是您要发送回调用脚本的响应。在 session_write_close() 之后做任何你想做的事情,这样这些事情就不会进一步阻止你的调用脚本的执行

    【讨论】:

    • 好的,我用你的代码写了一个echo json_encode("started") 但没有解决:构建脚本正在运行,页面显示“started”,它没有返回主页面.
    • @marco 我用它来调用一个页面 thorugh ajax 并且有效。我可能需要用 ajax 检查案例
    • 谢谢,但有人回答将 shell 重定向到 null,它确实有效,但现在答案消失了 (???)。
    • @marco 抱歉,那是我的吗?我已经读过了!以为我的问题是错误的,但显然不是哈哈。 stackoverflow.com/a/22219387/332807
    【解决方案4】:

    如果我的其他答案不起作用,您可以试试这个:

    最快/最简单的方法可能是使用 JavaScript 在 iF​​rame 中加载脚本。这将在不离开页面的情况下加载它。

    您的页面:

    <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';
    }
    

    请注意,您可能需要将 GET 参数与 iFrame src 一起传递。

    【讨论】:

    • 不传递 GET 参数,它不起作用,但我更喜欢 NoobEditor 的解决方案,看起来更干净。但是谢谢:)
    猜你喜欢
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多