PHP

Add CSV examples. Flesh out OOP section.

PHP offers so many file functions, the challenge is finding the ones that match your goals.

TuxRadar provides a gentle introduction with good advice, and W3schools provides a handy summary. They might be good to look over before wading through the filesystem functions on php.net.

basics

fopen( )

Create / overwrite a file line-by-line

$fh = fopen( 'myfile.txt' , 'wb' ); // open for write access, binary safe, RETURNS file handle
fwrite( $fh , "Here's the first line.\n" ); // write a string, terminate with newline
fwrite( $fh , "Here's the second line.\n" ); // this is appended to the file
fclose( $fh ) // free up resources

Append to a file line-by-line

(Same as above, but change file mode from 'wb' to 'ab'.)

Read a file line-by-line

$fh = fopen( 'myfile.txt' , 'rb' ); // open for read access, binary safe
$line1 = fgets( $fh ); // read a line into a string (\n is included)
$line2 = fgets( $fh ); // read the next line
fclose( $fh ) // free up resources

Read an entire file

$fh = fopen( 'myfile.txt' , 'rb' ); // open for read access, binary safe
$data = fread( $fh , filesize( 'myfile.txt' ) ); // a smaller number reads part of the file
fclose( $fh ) // free up resources

fwrite() and fgets() would normally be inside a while, foreach, or for loop.
Use them when you need to parse or manipulate individual lines.

fopen() requires a filespec and a mode.

mode description
r read only — file pointer at file start
r+ read/write
w write only — create (or truncate) file
w+ write/read
a append — create (or put pointer at end of) file
a+ write/read
x create for writing — E_WARNING error if file exists
x+ read/write
c write only — file pointer at file start, does NOT truncate, create if needed
c+ read/write

Append "b" to the mode to keep the data "binary safe" on Window's servers.

file_put_contents( )   file_get_contents( )   file( )

Create or overwrite an entire file

file_put_contents( $filename , $data ); // create or overwrite file ($data can be string or array)

Append to a file

file_put_contents( $filename , $data, FILE_APPEND ); // append (or create if needed)

Read a file into a string

$s = file_get_contents( $filename ); // read entire file into $s 

Read a file into an array

$a = file( $filename ); // $a[0] = line 1, $a[1] = line2 (includes \n)

The examples above need error checking. And sometimes you need to examine a file line-by-line so data can be translated from one form to another.

create, append, read, edit — an INI file example

The following code shows one way to deal with an INI file.
(PHP provides parse_ini_file() to handle this situation, and it can parse multi-dimensional arrays.
But just for kicks.)

Assume MYFILE.INI stores information as: item = value.

First, we need some error checking. We need to make sure fopen() can succeed.

create function to check for fopen() errors

function create_file_handle( $filespec, $mode ) {
	if ( substr( $mode, -1, 1 ) != 'b' ) $mode .= 'b'; // make mode binary safe, in case it's forgotten
	if ( $mode == 'rb' && !is_readable( $filespec ) ) { // make sure you can read 
		throw new Exception( "Can't read file.");
	} else {
		if ( file_exists( $filespec ) ) {
			if ( !is_writeable( $filespec ) ) { // make sure you can write
				throw new Exception( "Can't write to file." );
			}
		}
	}
	if ( !$fh = @fopen( $filespec , $mode ) ) { // '@' suppresses warning so you can trap for it
		throw new Exception( "Problem creating file handle." );
	}
	return $fh; // return file handle
}

create functions to convert to / from INI string format

function array_to_ini_string( $a , $delimiter ) {
	$s = ""; // create empty string
	foreach( $a as $k=>$v ) $s .= "$k $delimiter $v\n"; // key = value, append newline
	return $s;
}

function ini_file_to_array( $filename , $delimiter ) {
	$fh = create_file_handle( $filename, 'rb' ); // read-only
	while ( $line = fgets( $fh ) ) {// get 1 line (includes newline code)
		$tmparray = explode( $delimiter , $line ); // separate line into 2 array elements
		$newarray[ trim( $tmparray[0] ) ] = trim( $tmparray[1] ); // create key:value pair
	} // note: trim() removes extra spaces, tabs, and \n
	fclose( $fh );
	return $newarray;
}

function dump_file( $title , $filename, $destination = 'web' ) { // simple way to test results
	$s = "\n----- $title " . strtoupper( $filename ) . " -----\n";
	$s .= file_get_contents( $filename );
	if ( $destination == 'web' ) { // uses arg w/default value
		echo nl2br( $s ); // convert \n to breaks
	} else {
		echo $s; 
	}
}

create some variables

$filename = 'myfile.ini';
$delimiter = '=';
$settings = array( // usually this would be a cleaned $_POST array or parsed INI file
	'director_title' => "Advising Coordinator", 
	'director_name' => "Jim O'Rourke",
	'director_uwnetid' => 'jor'
	);
$mystring = array_to_ini_string( $settings , $delimiter ); // create string from array so it can be written

The next 2 examples accomplish the same thing, using fwrite() and file_put_contents().

create and append — fwrite()

Without error checking

$fh = create_file_handle( $filename, 'wb' ); // open to create or overwrite 
fwrite( $fh, $mystring ); // write it
fclose( $fh ); // free up resources

$mystring = "hours = 8:00 - 5:00\n"; // create new setting
$fh = create_file_handle( $filename, 'ab' ); // open to append
fwrite( $fh, $mystring ) ; // append it
fclose( $fh );

create and append — file_put_contents()

Without error checking

file_put_contents( $filename , $mystring ); { // create or overwrite
$mystring = "hours = 8:00 - 5:00\n"; // create new setting
file_put_contents( $filename , $mystring, FILE_APPEND ); { // append it

With error checking and display of results

try {
	if ( !file_put_contents( $filename , $mystring ) ) { // create or overwrite
		throw new Exception( 'Write failed.' );
	}
	dump_file( 'CREATED' , $filename ); // add 3rd arg , 'shell' to leave \n unconverted
	
	$mystring = "hours = 8:00 - 5:00\n"; // create new setting
	if ( !file_put_contents( $filename , $mystring, FILE_APPEND ) ) { // append it
		throw new Exception( 'Append failed.' );
	}
	dump_file( 'APPENDED' , $filename );
}
catch( Exception $e ) {
	echo "\n{$e->getMessage()}\n\n";
}

get file, create array, alter settings, and rewrite it

try {
	$settings = ini_file_to_array( $filename , $delimiter ); // create associative array from file

	$settings['director_name'] = "John Williams"; // alter some settings 
	$settings['director_uwnetid'] = 'jw2';
	$settings['hours'] = "7:30 - 4:30";
	
	$mystring = array_to_ini_string( $settings , $delimiter ); // create string from array

	if ( !file_put_contents( $filename , $mystring ) ) { // overwrite
		throw new Exception( 'Update failed.' );
	}

	dump_file( 'UPDATED' , $filename );
}
catch( Exception $e ) {
	echo "\n{$e->getMessage()}\n\n";
}

Try it out.

a CSV example

from CSV to MySQL

from MySQL to CSV

A quick summary of useful functions follows:

deleting

delete a file

unset( 'filespec' ); // unset() fails if file is open

reading

read and display a file in one fell swoop

readfile( 'filespec' ); // get and show file (can't alter content)

read a file into a string

$fstring = file_get_contents( 'filespec' );
echo $fstring; // display in a command shell
echo nl2br( $fstring ); // display in a web page

read a file into an array

$farray = file( 'filespec' ); // each element contains 1 line (including newline code)

create array from file string and visa versa

$farray = explode( "\n" , $fstring ); 
$fstring = implode( "" , $farray ); // if array contains newline codes
$fstring = implode( "\n" , $farray ); // if array lacks newline codes 

display lines from a file array

foreach( $farray as $v ) {
	echo $v; // command shell
	echo nl2br($v); // web
}

To add line numbers to display (a variation of TuxRadar's example, see below)

foreach( $farray as $k=>$v ) { // keys will be 0..n
	echo $k+1 . " : $v" . // command shell
	echo '<code>' . ($k+1) . '</code> : ' . htmlspecialchars(trim($v)) . "<br />\n"; // web	
}

Above, ($k+1) forces PHP to create a number before concatenating it with <code>.
htmlspecialchars() prevents a browser from interpreting HTML tags the file might contain.
trim() strips leading / trailing spaces, including newline code at end of each line.
The final \n is optional. It makes the source easier to view with Ctrl-U.

Try it on 'phpinaction.html'.

For functions that get parts of a file, each read advances the file pointer until the end of file is reached.

get one line from file

$line = fgets( $fh ); // get 1 line, including newline code
$line = fgetss( $fh ); // strip all HTML tags & PHP code
$line = fgetss( $fh , , "<b>,<strong>" ); // strip tags, but allow B and STRONG

get 1 line from CSV file

$csv_array = fgetcsv( $fh ); // parses fields into array
$csv_array[] = fgetcsv( $fh ); // append to 2-dimensional array, good in a loop

read n bytes from file

$bitofit = fread( $fh, 1024 ); // read 1024 bytes from file
$allofit = fread( $fh, filesize( 'filespec' ) ); // read entire file

reposition file pointer

fseek( $fh , 0 ); // at start of file
fseek( $fh , 2048 ); // 2045 bytes into file
fseek( $fh , -1024 ); // 1024 bytes from end of file

get 1 character from file

$char = fgetc( $fh );

writing

create / overwrite file

$fh = fopen( $filename , 'wb' ); // change mode to 'ab' to append instead
fwrite( $fh, 'Hello ' ); // fwrite() expects a string
fwrite( $fh, "World!\n" ); // subsequent fwrite's append
fclose( $fh ); // file now contains "Hello World!\n"

open, write, and close file

file_put_contents( 'filespec' , $data ); // $data can be string or array

open, append, close file

file_put_contents( 'filespec' , $data, FILE_APPEND ); 

selected functions

functions that rely on fopen()

functions that open and close file automatically

functions that get information about files

information about current script : c:\dev\www\dir1\dir2\myscript.php

$_SERVER['SCRIPT_NAME']
/dir1/dir2/myscript.php   // if "www" is web server's root
__FILE__
c:\dev\www\dir1\dir2\myscript.php
__DIR__
c:\dev\www\dir1\dir2 // or: dirname(__FILE__)
dirname( __DIR__ )
c:\dev\www\dir1
basename( __FILE__ )
myscript.php // or: basename($_SERVER['SCRIPT_NAME'])
realpath( __FILE__ )
get absolute path (e.g.: an "included" file's real location)
pathinfo( )
create array with parts of path as keys (example)

filespec (file specification)

NOTE: PHP allows \\ or // on Windows. Might as well use Unix convention.

Other supported protocols and wrappers.

OOP

SplFileObject — massive class for OOP file manipulation

$file = new SplFileObject( 'filespec'); // constructor embeds file handle in object
while ( $line = $file->fgets() ) { // hence, don't list it in method, $file already has it
	echo $line;
}