Search code examples
phpwgetfile-put-contents

PHP: Save the file returned by wget with file_put_content


I'm replacing a function that downloads a file with cURL and returns its content in a variable, then outside the function the code writes this variable to a file with file_put_content. Because of requirements of the system I have to use wget now, so I'm using something like this:

function GetData($strdata,$wwwurl){
    $content = exec("wget --post-data '".$strdata."' -qO- ".$wwwurl);
    return $content;
}

But when I later use file_put_content to save the content of $content, the size of the file is way smaller than it should be (1kb when it should be around 480kb). I can't remove file_put_content as it's used in several places of the code (that would take us a very long time) and all I can edit must be into that function. If I launch wget with "-O test.zip" instead of "-O-" the file is downloaded and saved fine, the same happens if I launch the command from command line. Any ideas?


Solution

  • Its because exec doesn't return the whole data. Take a look at the documentation https://www.php.net/manual/en/function.exec.php :

    Return Values: The last line from the result of the command.

    But shell_exec (or just backticks) returns whole data: https://www.php.net/manual/en/function.shell-exec.php .

    Example:

    <?php
    
    $url = 'https://file-examples-com.github.io/uploads/2017/02/zip_5MB.zip';
    
    $content = exec("wget -qO- $url");
    
    var_dump(strlen($content));
    
    $content2 = shell_exec("wget -qO- $url");
    
    var_dump(strlen($content2));
    
    
    file_put_contents('1.zip', $content);
    file_put_contents('2.zip', $content2);
    

    Output:

    int(208)
    int(5452018)
    

    2.zip works (all 5MB data), 1.zip obviously not (just some bytes from the end).

    So don't treat exec's return value as the whole output of the command.