Writing to a text file outside the webroot directory

I am trying to use PHP to read and write from a text file. The file is read using a button on the html page. The file is written using a button on the html page that takes a parameter from a text box. I was able to write a text file when the text file is in the webroot directory. I want to be able to read / write from a text file that lives outside of the webroot directory.

I am using lighttpd with PHP on Beaglebone. The webroot directory is in /var/www

. The text file that I want to change will be located at /var/textFiles

. I've looked everywhere for solutions but none seem to work.

The following is the most promising solution I've found, but it doesn't work. When I click the read or write button, the page seems to be stuck in an infinite loop. I was wondering if anyone knows why this doesn't work, or if they can suggest a better solution.

This is what I have so far:

index.php

<?php 
echo '<script language="javascript" type="text/javascript" src="jquery-1.9.0.min.js"></script>';
echo "<form name='write' action='writeFunctionCaller.php' method='post'>Input text to 
write to text file: <input type='text' name='input'>
<input type='submit' value='Write' ></form>
<form name = 'read' action='readFunctionCaller.php' method='get'>
<input type='submit' value='Read'></form><br><div id='fileContent'></div>";

class readWriteModel {

   function readFile() {
        $file_handle = fopen("secure.php?file=phpRead.txt", "r");
        while (!feof($file_handle)) {
            $line = fgets($file_handle);
            echo $line;
            echo '<br>';
        }
        fclose($file_handle); 
    }

    function writeFile($text) {
        echo ("Write Success! ");
        $filename = "secure.php?file=phpRead.txt";
        file_put_contents($filename, $text, FILE_APPEND | LOCK_EX);
    }
}
?>

      

secure.php

<?php
//validate that the user should have access to the file here

//Make sure it exists
$folder = realpath('/var/textFiles');
if(!$file = realpath($folder.'/'.$_GET['file']))
    error(404);
if(!is_file($file))
    error(404);

//Check for cheaters
if(substr($file,0,strlen($folder)) !== $folder)
    error(401);

header(sprintf("Content-type: %s;",getMimeType($file)));
readfile($file);
exit;

function error ( $code = 401, $msg = null ) {
    $msgs = array(
      400 => 'Bad Request',
      401 => 'Unauthorized',
      402 => 'Payment Required',
      403 => 'Forbidden',
      404 => 'Not Found',
    );
    if(!$msg) $msg = $msgs[$code];
    header(sprintf('HTTP/1.0 %s %s',$code,$msg));
    printf('<html><head><title>%s %s</title></head><body><h1>%s</h1></body> 
    </html>',$code,$msg,$msg);
    exit;
}

function getMimeType ( $filename ) {
    //MIME MAP
    $mime_extension_map = array(
    'txt'           => 'text/plain',
    );
    //Get Extension
    $ext = strtolower(substr($filename,strrpos($filename,'.') + 1));
    if(empty($ext))
      return 'application/octet-stream';
    elseif(isset($mime_extension_map[$ext]))
      return $mime_extension_map[$ext];
    return 'x-extension/' . $ext;
}
?>

      

writeFunctionCaller.php

<?php 
include_once('index.php');
$text = $_POST['input'];
$model = new readWriteModel();
$model->writeFile($text);
?>

      

readFunctionCaller.php

<?php 
include_once('index.php');
$model = new readWriteModel();
$model->readFile();
?>

      

+3


source to share


2 answers


I was able to read and write from a text file outside the root directory. Just to make sure this works, I set a directory above /var

the webroot directory /var

and phpRead.txt

in 777

and referenced the file using an absolute path /var/textFiles/phpRead.txt

. This is definitely not the safest way to do it, so if you read and write files outside of the webroot directory see the following stackoverflow answer: https://stackoverflow.com/a/3012330/2047335 for more details. PHP security information.

Below are the files I used to read / write to a text file above the webroot directory:

index.php:

<?php 
echo '<script language="javascript" type="text/javascript" src="jquery-1.9.0.min.js"></script>';

echo "<form name='write' action='writeFunctionCaller.php' method='post'>";
echo    "Input text to write to text file: <input type='text' name='input'><input type='submit' value='Write' >";
echo "</form>";

echo "<form name = 'read' action='readFunctionCaller.php' method='get'>";
echo    "<input type='submit' value='Read'>";
echo "</form>";
echo "<br>";
echo "<div id='fileContent'></div>";

class readWriteModel{
  function readFile() {
  $file_handle = fopen("/var/textFiles/phpRead.txt", "r");
  while (!feof($file_handle)) {
   $line = fgets($file_handle);
   echo $line;
   echo '<br>';
   }
  fclose($file_handle); 
  }
  function writeFile($text) {
   echo ("Write Success! ");
   $filename = "/var/textFiles/phpRead.txt";
   file_put_contents($filename, $text, FILE_APPEND | LOCK_EX);
   }
}

?>

      

readFunctionCaller.php:

<?php 
include_once('index.php');
$model = new readWriteModel();
$model->readFile();
?>

      



writeFunctionCaller.php:

<?php
include_once('index.php');
$text = $_POST['input'];
$model = new readWriteModel();
$model->writeFile($text);
?>

      

UI image:

User Interface for PHP read / write to text file outside of webroot

Thanks everyone for your help!

+1


source


Writing to a file outside the web directory is no different than writing to inside the web directory, it is good practice to use absolute paths when writing to files, this will help you deal with a lot of problems and of course, make sure apache has the correct permission to do the desired action above the file.



0


source







All Articles