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.
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.
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.
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.
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
}
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;
}
}
$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().
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 );
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";
}
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";
}
A quick summary of useful functions follows:
unlink( 'filespec' ); // unlink() fails if file is open
readfile( 'filespec' ); // get and show file (can't alter content)
$fstring = file_get_contents( 'filespec' ); echo $fstring; // display in a command shell echo nl2br( $fstring ); // display in a web page
$farray = file( 'filespec' ); // each element contains 1 line (including newline code)
$farray = explode( "\n" , $fstring ); $fstring = implode( "" , $farray ); // if array contains newline codes $fstring = implode( "\n" , $farray ); // if array lacks newline codes
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.
$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
$csv_array = fgetcsv( $fh ); // parses fields into array $csv_array[] = fgetcsv( $fh ); // append to 2-dimensional array, good in a loop
$bitofit = fread( $fh, 1024 ); // read 1024 bytes from file $allofit = fread( $fh, filesize( 'filespec' ) ); // read entire file
fseek( $fh , 0 ); // at start of file fseek( $fh , 2048 ); // 2045 bytes into file fseek( $fh , -1024 ); // 1024 bytes from end of file
$char = fgetc( $fh );
$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"
file_put_contents( 'filespec' , $data ); // $data can be string or array
file_put_contents( 'filespec' , $data, FILE_APPEND );
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
pathinfo() parses a string into smaller strings.
pathinfo( __FILE__ ) the underlying OS's absolute path to the script.
pathinfo( $_SERVER['SCRIPT_NAME'] ) the web server's path to the script.
Assume this as the current script: c:\dev\www\dir1\dir2\myscript.php
$pathparts = pathinfo( __FILE__ ); // create array, values shown below $pathparts['dirname'] // C:\dev\www\dir1\dir2 $pathparts['basename'] // myscript.php $pathparts['extension'] // php $pathparts['filename'] // myscript
NOTE: PHP allows \\ or // on Windows. Might as well use Unix convention.
Other supported protocols and wrappers.
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; }