PHP and Files

Working with files in PHP is painless, with methods that should feel familiar when compared to other languages you have worked with. For example:

<?php
  $fileName = '';
  if (isset($_GET['filename'])) {
    $fileName = $_GET['filename']; //get the file names from params
    $fp = fopen($fileName, 'r');   //open the file for reading 
    if (!$fp) {                    //check that file opened ok
      echo "<p>ERROR! Could not open file $fileName for reading.</p>";
    } else {
      $line = fgets($fp);          // read a line
      while( !feof($fp) ) {        //while end of file not reached
        $content = $content . $line . '<br>';
        $line = fgets($fp);
      }
    }
    fclose($fp);                   //close the file
  }
?>
PHP allows for the following modes when opening a file:

ModeDescription
r Read only, start at beginning of file.
r+Read/Write, start at beginning of file.
w Write only, opens and clears contents of file, or creates one if it does not exist
w+Read/Write, opens and clears contents of file, or creates one if it does not exist
a Write only, opens and writes to end of file, or creates one if it does not exist
a+Read/Write, preserves file contents by writing to end of file.
x Write only, Creates new file, returns false and error if file already exists
x+Read/Write, Creates new file, returns false and error if file already exists

Writing to file


int fwrite(filePointer, string [, length])

Reading from a file

//read one line from file, including the newline character, up to maxLength-1 bytes if that param is provided

string fgets(filePointer, [maxLength])  
//secure read line: read one line from the file, including the newline character, and strip all the HTML tags; if maxLength provided, read up to maxLength-1 bytes from file; if allowableTags provided, do not strip those tags from the string returned
string fgetss(filePointer, [maxLength] [, allowableTags])
//read one line, split it by delimiter (comma by default) into an array and return the array
array fgetcsv(filePointer, [maxLength] [, string delimeter])

Reading the whole file

int readfile(fileName) //open file, echo content, close file
int fpassthru(filePointer) //read file starting with current position, echo content, close file
array file(fileName) //open file, read file content into array, each element being a line (including newline character), close file
string file_get_contents(fileName) //open file, read entire content into string, close file
  

Reading portions of a file


char fgetc(filePointer)  //read one character
string fread(filePointer, nbBytes)  //read up to nbBytes
  

Useful file functions


bool file_exists(filename)  //returns TRUE if file exists, FALSE otherwise
int filesize(filename) //returns the size of file in bytes, or FALSE if error
bool unlink(filename)  //deletes a file
  

Locking a file

$fp = fopen($fileName, 'a');
flock($fp, LOCK_EX); //acquire exclusive lock before write (LOCK_SH before read)
fwrite($fp, $text);
flock($fp, LOCK_UN);  //release lock
fclose($fp);

Debugging

You are expected to debug your code constantly, the best way to do that with PHP is to review the error log from the Apache web server. To review the logs:
  1. Log onto the web server (midn.cs.usna.edu) via ssh

    ssh midn.cs.usna.edu
  2. Tail (a command that allows you to see the last few lines of a file, or continuously watch the file for new additions with the -f flag) the error log via:

    tail -f /var/log/apache2/error.log
    It may be useful, to just focus on your own errors, and that can be done by piping the results of tail through grep to search for your mAlpha

    tail -f /var/log/apache2/error.log | grep mAlpha
  3. If any of the errors are confusing, take a look at the error guide located within the resources page of this class, or online. As with any language, it is recommended that you work on the first error that appeared, then try running your code again as errros may be linked to each other.
  4. Additionally, you can call your web page via the command line to see exactly what was returned, curl is an excellent utility for this, and the -v (verbose option) will show you the back-and-forth traffic with the web server.

    curl -v http://midn.cs.usna.edu/~mAlpha/IT350/test.php
  5. In Chrome, you can press ctrl-shift-j to toggle the debugger, this is useful as you can see exactly what was received by the browser.
Please note: When something is not working (internal server error), check the error log! You should be able to debug on your own, the instructor and/or the submission system can not be your primary method of finding errors in your code.

Practice Problems

  1. Create a text file called php-practice.txt with the following content:

    Navy Spirit Gear Hat,10,5.50
    Navy Birthday T-shirt XL,13,12.95
    Navy Blue Baseball Cap,42,9.95
    Ball Point Pen,31,1.05
    Navy Pride Bumper Sticker,16,4.99
    Write a .php script that will read the contents of this file, and place the results into an associative array in the following format:

    array('Navy Spirit Gear Hat'=>array('quantity'=>10, 'price'=>5.50))
    which will allow you to access the contents via the array in the following way:

    $itemPrice = $myArray['Navy Spirit Gear Hat']['price'];
    This script should read in the name, quantity, price information from the php-practice.txt file and print the final array via the print_r() function. Take a look at PHP's explode function to determine how to split the string based on the comma in the text file.
  2. Continuing... Use the associative array from part 1, to create an HTML table, with HTML output similar to (feel free to make better table code!):

    <table>
      <thead>
        <tr><th>Item</th><th>Quantity</th><th>Price</th></tr>
      </thead>
      <tbody>
        <tr><td>Navy Spirit Gear Hat</td><td>10</td><td>5.50</td></tr>
      </tbody>
    </table>
  3. Continuing... Add to the table an input box to allow a customer to select a quantity for each item (similar to in-class example from the previous lecture). Set up the appropriate <form> and allow the user to submit their selections. Set the form method="POST" action="php-practice.php" (or based on the name of your php script) so the same script handles the requests. What do you plan to name your text box's? You will need to be able to access the information when it is submitted.
  4. Continuing... Check to see if the user submitted an order, if so print out the order (including item, quantity, cost per item, and total cost), otherwise print out the form. Remember the data from the form will be provided in the $_POST variable (which is an associative array)