0

Hello,
Simple is not so simple i see,
Trying to save file in html-format from server to local disk.

    <?php
    if(isset($_POST['submit'])) {
    $file = $_POST['file'];
    file_get_contents('files/$file');
    file_put_contents('download/$file');
    }
    ?>
    <form method="post" action="">
    <select name="getfile" id="getfile">
    <option value="">Select file...</option>
    <?php
    $dir_open = opendir('files/');
    while(false !== ($filename = readdir($dir_open))){
    if($filename != "." && $filename != ".."){
        echo "<option value='$filename'>$filename</option>";
    }
    }
    closedir($dir_open);
    ?>
    </select>
    <input type="submit" name="submit" value="Get file" class="basebutton" style="width: 55px;">
    </form>

Looks simple, get filename, but writes nothing to download-share in local disk.
Local share is granted to everyone and IIS-users.

4
Contributors
10
Replies
54
Views
1 Year
Discussion Span
Last Post by masimies
1

Firstly, it looks like you need to use double quotes as you're including a variable in the file name name string.
file_put_contents("files/$file");
Single quotes are 'dumb' and don't parse variables to strings.

Secondly, file_put_contents uses a second parameter which is the data to put in the file.
file_put_contents("files/$file", $someData);
Without that it doesn't do anything (apart from logging an error).

0

Hi,
Yes, there is examples of these strings, and using quotes differences by case. In this case, double quotes didn't make difference.
I think that in this case, issue is writing to local disk, because in other similar script, i can write to server-folder. That script uses ob_get_contents.
How to tell server, that do not try to find "download"-folder in server share. It is in local disk!

0

As per your code(line 4-5), after getting the content from file_get_contents(), the content of the file is not stored.
It should be a variable declared to store the content, then parsed the data into file_put_contents ().

Is there any error/warnings displayed after the process? As if it is permission issue, there will be errors/warnings displaying.

Edited by lps

0

There is no warnings at all. Just a submit flash, when selectin filename from dropdown. Selected filename is displayed, but nothing else happen.
How to store contents? Tried to put it as variable, but no luck.

0

There is no updates. Did'n get how to put filename as variable,as it is already variable???

0

@masimies Hericles suggested you add the second argument to the file_put_contents() function:

the first argument define the path in which the file will be saved and the filename, the second argument is the data you want to copy into that file. From your replies I don't understand if you have changed line 5, to reflect the suggestion. As example:

<?php

# source path
$source = 'https://upload.wikimedia.org/wikipedia/commons/5/56/Answer_to_Life.png';

# read the data
$data = file_get_contents($source);

# define destination path & filename
$path = 'download/the_answer.png';

# save it
file_put_contents($path, $data);

Once this is assumed you have to check the paths, for example on line 3 and 4 you set:

$file = $_POST['file'];
file_get_contents('files/$file');

Which:

  1. is unsafe because, if not sanitized, it allows a directory traversal attack which allows a user to copy an arbitrary file from the serving file system
  2. if the script is not in the parent directory of files/, then it can fail, here you should define an absolute path or relative to the script

For example:

/form/script.php
/files/
/download/

Then the relative path would be ../files/ and ../download/. To simplify the debugging enable the error reporting, set this command at the very top of your script:

error_reporting(E_ALL);

And, in case you still have doubts, paste the errors here.

0

Hi,
No luck still.
With this version part of script. It writes the filename to web-root folder, but nowhere else in local "laptop" shares. And the written file doesn't have nothing inside. It's empty. As this test is done in my laptop's web-environment, target is to put script to real web-site, and get files from it to local machine. Yes, there is another ways to do this, like ftp classes. But i try hard to avoid numbers of classes implemented on my site.

    <?php
    if(isset($_POST['submit'])) {
    $file = $_POST['file'];
    $source=$file;
    $data=file_get_contents("$source");
    $path="$file";
    file_put_contents($path, $data);
    }
    ?>
0

the written file doesn't have nothing inside

it happens because the source is not found, so even if a new file is created it will be empty, you could try:

if(file_exists($source))
{
    # execute copy code here
}

Consider also that your forms sends getfile and then you search for file.

target is to put script to real web-site, and get files from it to local machine

If you run the script from local, and the source path is remote (an URL not an internal path) then it can work, as in my previous example. But file_put_contents() executed on remote server cannot copy the file to local. Here you can use FTP as already noted by you, but you can also force a download:

<?php

    # check if file index exists in $_POST array
    # and if is not empty
    if(array_key_exists('file', $_POST) && ! empty($_POST['file']))
    {

        # file position: 'http://www.domain.tld/files/hello.gif'
        # $_POST['file'] value: 'hello.gif'
        $file = pathinfo($_POST['file'])['basename'];

        # internal path: /var/www/domain.tld/files/hello.gif
        $path = $_SERVER['DOCUMENT_ROOT'] . '/files/';
        $filepath = $path . $file;

        if(file_exists($filepath))
        {
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
            header('Expires: 0');
            header('Cache-Control: must-revalidate');
            header('Pragma: public');
            header('Content-Length: ' . filesize($filepath));
            readfile($filepath);
            exit;
        }

        else
            error_log('ERROR: file not found');
}

else
    error_log('ERROR: "file" index not set in POST array.');

# in case of error redirect to form
  header('Location: ' . $_SERVER['HTTP_REFERER']);

The example source: http://php.net/manual/en/function.readfile.php
Check also: http://php.net/pathinfo

Live example: http://code.runnable.com/VwjTLtHI25Me5nn4/testing-download

0

Thanks for info. I test that forced download script later on.
I modify the script with these suggestions, and was able to copy file. But only inside webroot.
Added also some echoes for file not found and file copied to target location, under banner. Here is the working code for it:

<div class="banner"><h5>
    <form method="post" action="">
    <select name="htmlfile" id="htmlfile">
    <option value="">Valitse...</option>
    <?php
    $dir_open = opendir("htmlinvoices/");
    while(false !== ($filename = readdir($dir_open))){
    if($filename != "." && $filename != ".."){
    echo "<option value='$filename'>$filename</option>";
    }
    }
    closedir($dir_open);
    ?>
    </select>
    <input type="submit" name="submit" value="Hae" class="basebutton" style="width: 55px;"></form></h5><br/>
    <?php
    if(isset($_POST['submit'])) {
    $htmlfile = $_POST['htmlfile'];
    $source="htmlinvoices/$htmlfile";
    if(file_exists($source))
    {
    $data=file_get_contents("$source");
    $path="download/$htmlfile";
    file_put_contents($path, $data);
    echo"Tiedosto kopioitu $path";
    }
    else {
    echo"Haettua tiedostoa ei löydy";
    }
    }
    ?>
</div>

Im fetching invoices, what are in html-format. For real, i need to fetch all invoices between whole month. That needs some extra functions, but due that i like to learn this coding from beginning, i test these with one function at time. I go blind, if i see 500-rows code from start, and try to figure out, how it is working :-D

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.