如果PHP脚本包含shell_exec,它会运行多次.怎么可能呢


PHP script runs multiple times if it contains shell_exec. How could it be?

我有一个非常简单的PHP脚本,它调用shell_exec来启动第三方应用程序。

无论我尝试运行什么应用程序(包括notepad.exe),

如果脚本包含对shell_exec的调用,则会多次调用该脚本,

如果脚本不包含此调用,则只运行一次

我可以提供任何需要的源代码,让我知道你想看什么,我只是绝对不知道该去哪里看。

Windows 2008 R2,PHP 5.5.1,IIS 7.5,Amazon EC2服务器

不,脚本中没有任何循环,因为我已经放置了

file_put_contents('log.txt', $_SERVER['REQUEST_URI'], FILE_APPEND);

作为第一个脚本行,我可以在日志中看到它被多次写入。

编辑:这不会发生在我的本地主机上。这种情况也发生在exec身上。

PHP脚本精简到最低限度:

<?php
//Report any errors
ini_set("MAX_EXECUTION_TIME", "-1");
ini_set('max_input_time', -1);
ini_set ("display_errors", "1");
error_reporting(E_ALL);
require_once('PhpConsole.php');
PhpConsole::start(true, true, dirname(__FILE__));
function writeLog($content, $logname)
{
    $temp = $content ." at " .date("D M j G:i:s T Y") ."'r'n";
    $f = fopen($logname, 'a+');
    fwrite($f,$temp,strlen($temp));
    fclose($f);
}
function createBackground()
{
    //Set the correct content type
    header('content-type: image/png');
    //Create our basic image stream 225px width, 225px height
    $image1 = imagecreate(1362, 762);
    // Set the background color
    $white = imagecolorallocate($image1, 255, 255, 255);
    // Save the image as a png and output
    imagepng($image1, "saves/back.png");
    // Clear up memory used
    imagedestroy($image1);
}
function buildFramesSequence()
{
    array_map('unlink', glob("saves/*"));
    array_map('unlink', glob("*.mp4"));
    unlink("list.txt");

    $url = realpath('') ."/" .$_GET["jfile"] ;
    $contents = file_get_contents($url);
    $results = json_decode($contents, true);
    $noOfFrames =  count( $results['ani']);
    $lastframe = "saves/back.png";
    createBackground();
    $elements = createElements($results['pre']);
    $frame_elements = array();
    $prev_element = null;
    for ($i = 0; $i <$noOfFrames; $i++)
    {
            $format = 'image%1$05d.png';
            $imgname = sprintf($format, $i);
            copy($lastframe, "saves/" .$imgname);
   }
}
function createVideo()
{
    writeLog("before build", "log.txt");
        buildFramesSequence();
    writeLog("after build", "log.txt");
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        $localpath1 = realpath('') ."/ffmpeg/ffmpeg.exe";
    } else {
        $localpath1 = "ffmpeg";
    }
    $localpath2 = realpath('') ."/saves/image%05d.png";
    $mp3name = $_GET["mfile"];
    $localpath3 = realpath('') ."/" .$mp3name;
    $temp = substr($mp3name, 0, -1);
    $localpath4 = realpath('') ."/" .$temp ."4";
    writeLog(" before ffmpeg", "log.txt");
    $output =  shell_exec("notepad.exe");
    // $output =  shell_exec("ffmpeg $localpath1 .' -f image2 -r 20 -i ' .$localpath2 .' -i ' .$localpath3  .' -force_fps ' .$localpath4. ' 2>&1 &');
    // exec("notepad.exe", $output = array());
    //   debug($output);
    writeLog($localpath4, "list.txt");
    return $output;
}
file_put_contents('log.txt', $_SERVER['REQUEST_URI'], FILE_APPEND);
    set_time_limit(0);
    $output = createVideo();
    echo $output;
?>

这是一个非常奇怪的问题,至今仍会发生在exec() system() shell_exec()等中。如果您的命令创建了一个文件,最快的解决方案是检查该文件是否存在,如下所示:

[ -f path/file.mp4 ] || #Your command here#

这将检查文件path/file.mp4是否存在,如果不存在,则运行第二个条件,即您的命令。要检查相反的情况,请使用"与"符号,如下所示:

[ -f path/file.mp3 ] && #Command here#

我不确定是否还有人对此有问题,但也许你的问题与我刚才的问题相同。我用exec创建了一个文件,并在其中添加了一个日期时间戳

我最终得到了5个文件。事实证明,因为我通过htaccess将所有调用重定向到我的index.php,所以当我有一些图像指向相对路径assets/images/image.jpg时,它会通过我的索引页面重定向,并多次调用我的脚本。我不得不在图像路径上添加一个斜线:/assets/images/image.jpg。

希望这能帮助到别人。