18. php file operations opening a file use fopen() to open a file 2 required parameters 1 st...
TRANSCRIPT
18. PHP File OperationsOpening a File Use fopen() to open a file
2 required parameters
1st parameter is the full pathname of the file
Can use the PHP built-in variable
$_SERVER['DOCUMENT_ROOT'] Points to the base of the document root (www for
Apache2)
We store the value in a scalar variable:
$DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
As there are 3 ways to access form data, there are 3 ways to access predefined server variables
The above way is preferred
Also old-fashioned way, using $DOCUMENT_ROOT directly
And the deprecated, longer form
$HTTP_SERVER_VARS['DOCUMENT_ROOT']
Which forms we can use depends on our server setup
So 1st parameter to fopen() can be something like
$_SERVER[DOCUMENT_ROOT].'/../phpData/orders.txt'
Can also use an absolute path, e.g.,
'C:/wamp/phpData/orders.txt'
Use forward slashes (/) even though they’re executed on Windows
On Windows, can also use backslashes (\) But must be doubled (backslash is the escape character)
"C:\\wamp\\phpData\\orders.txt"
2nd parameter to fopen() is the file mode
It’s a string telling the system how to handle access requests
'r': read only, beginning at the start of the file
'w': write only, beginning at the start of the file
If file exists, system deletes its contents
Otherwise, system tries to create it
'a': appending new content after existing content
If file doesn’t exist, system tries to create it
Variants of these modes where the character is followed by a + All indicate read/write
'r+': read/write, starting at beginning of file Preserve content if the content is only read Overwrite content with writes
'w+': read/write, System clears the content, or creates a new file if specified
file doesn’t exist
'a+': read/append, preserving content by writing to end of file
'x': “cautious” write Causes fopen() to fail and return false if the file exists
'x+': cautious read/write
Windows, unlike Unix, distinguishes between binary and text files
For portability, should also specify binary content, appending 'b' to the mode
For the example given later, append orders to an order file, so use 'ab':
fopen($_SERVER[DOCUMENT_ROOT].'/../phpData/orders.txt', 'ab')
If fopen() succeeds, returns a “resource”, or file pointer, which we store in a variable:
$fp =
fopen($_SERVER[DOCUMENT_ROOT]. '/../phpData/orders.txt', 'ab');
Used with all further operations on the file
To close this file, use
fclose( $fp );
Returns true if it succeeds and false otherwise
Very unlikely that anything’s amiss with closing a file So we don’t test for this case
If fopen() fails, PHP adds warnings to the HTML
But should handle failure gracefully
Use the error suppression operator, @: $fp =
@ fopen($_SERVER[DOCUMENT_ROOT].'/../phpData/orders.txt', 'ab');
If fopen() fails, $fp is set to false—test for that
Can write this as@ $fp =
fopen($_SERVER[DOCUMENT_ROOT].'/../phpData/orders.txt', 'ab');
Preferred since @ stands out
If fopen() fails, exit from the script after outputting a paragraph and closing tags:
if ( ! $fp ) {
echo "<p>Your order cannot be processed now.</p>\n"
."</body>\n<html>";
exit;
}
Can exploit short-circuit evaluation of or so that exit() with a message is executed if fopen() fails and so returns false: @ $fp =
fopen($_SERVER[DOCUMENT_ROOT].'/../phpData/orders.txt',
'ab');
or exit("<p>Your order cannot be processed now.</p>"
."</body></html>");
Writing to a File Most common way to write to a file:
fwrite( File, Data, Length )
File is a file pointer
Data is string to be written to end of file
Length is max number of bytes to write
1st 2 parameters required, 3rd optional
If Length is supplied, Data is written to file until its end or Length bytes output
Usually include 3rd parameter when writing in binary mode
Helps avoid cross-platform compatibility issues
Can use built-in function strlen() to get length (in bytes) of a string
To output $outstring to $fp, can use
fwrite( $fp, $outstring, strlen( $outstring ) );
Function fputs() is an alias of fwrite()
An alternative to fwrite() is
file_put_contents( Path , Data )
Path is full pathname of the file
Data is as before
Invoking this function is equivalent to invoking
$fp = fopen( FileName, 'w' );
fwrite( $fp, Data );
fclose( $fp );
To get effect of 'a' instead of 'w', include as a 3rd parameter constant FILE_APPEND
This returns number of bytes written to file or false if it fails
Example Take 1st example from last section of previous part
Have the form include text box for client’s name
For each order, client’s name date the order was placed number of each item ordered amount due (including tax)
are written as a line to a file orders.txt
For security reasons, it’s in a folder not under document root:
$DOCUMENT_ROOT/../phpData/orders.txt
Recall:
Name of the text box for number of quarts of milk is milkqty
Name of the text box for number of bottles of beer is beerqty
Corresponding program variables are $milkqty and $beerqty
Name of the new text box is name
Corresponding program variable is $name
Add in 1st block of code the statement
$name = $_POST['name'];
No change to HTML output by the PHP script
Just add required file processing at the end
Format of the line written to file:
It must terminate it with a \n
Generally separate fields with tabs, \t Normally doesn’t occur in input Using a special field separator lets us split the data back
into separate variables See later, arrays and string processing
The output string:
$name."\t"
.$date."\t"
.$milkqty." quarts of milk\t"
.$beerqty." bottles of beer\t\$"
.$totalamount."\n";
Listing of the new code:
$outstring = $name."\t" .$date."\t" .$milkqty." quarts of milk\t" .$beerqty." bottles of beer\t\$" .$totalamount."\n";
@ $fp = fopen($_SERVER[DOCUMENT_ROOT].'/../phpData/orders.txt',
'ab');
if ( ! $fp ) { echo "<p>Your order cannot be processed now.</p>\n" ."</body>\n<html>"; exit;}
fwrite( $fp, $outstring, strlen($outstring) );fclose( $fp );
To confirm that order has been recorded, add a paragraph just before end of the body.
<p>Order written.</p>
If we exit because the file can’t be opened, this won’t be part of the HTML
After a couple of orders, orders.txt file isAl 17:49, 21st October 1 quarts of milk 6 bottles of beer $20.08
Ed 17:50, 21st October 6 quarts of milk 1 bottles of beer $24.20
Reading from a File Open same file again, now for reading
Invoke fopen() with mode 'rb':
@ $fp = fopen($_SERVER[DOCUMENT_ROOT]. '/../phpData/orders.txt',
'rb');
Trying to open a non-existent file not a problem for writing
System should create the file
But is a problem if the system can’t create the file
E.g., don’t have the required permissions
File has one order per line
Want to look at the orders one by one
Use function specifically designed for reading a line at a time:
fgets( File, Bytes )
Reads from the file associated with file pointer File until it
encounters a newline \n,
reaches the end of file (EOF),
or has read Bytes – 1 bytes
System maintains a current position pointer into a file where next read or write operation will happen
A read or write advances this pointer
fgets() advances the current position pointer to the position after the last character read (or to EOF)
Returns the string read or, if it fails, false
To use fgets(), put it in a loop that repeats as long as we haven’t reached EOF
feof( File ) returns true if the file associated with file pointer File is at EOF
To output contents of the orders file a line at a time in an HTML document, use a loop like
while ( ! feof( $fp ) ) {
$order = fgets( $fp, 999 );
echo $order.'<br>';
}
Next slide is a listing of entire PHP file for producing an HTML document listing the orders
For file contents shown above, the browser rendering is:
<?php $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];?>
<html>
<head>
<title>Al's Grocery - Customer Orders</title>
</head>
<body>
<h1>Al's Grocery</h1>
<h2>Customer Orders</h2>
<?php
@ $fp = fopen($_SERVER[DOCUMENT_ROOT]. '/../phpData/orders.txt', 'rb');
if ( ! $fp ) {
echo "<p>No pending orders.</p>\n</body>\n</html>";
exit; }
Continued
while ( ! feof( $fp ) ) {
$order = fgets( $fp, 999 );
echo $order.'<br>';
}
fclose( $fp );
?>
</body>
</html>
Rather than reading the file a line at a time, can read it all at once
Reading and writing a character at a time not covered
Reading arrays and fields within lines—later
Function
readfile( Path )
opens file with path Path,
echoes its content to the HTML document,
closes the file
Returns number of bytes read or, if it fails, false.
If we don’t care about running lines together when the HTML document is rendered,
could replace all the above code (except error-handling) with
readfile( "$_SERVER[DOCUMENT_ROOT].'/../phpData/orders.txt' );
Other functions for reading entire file at once
Function
fpassthru( File )
takes a file pointer File (unlike with readfile(), must have already opened the file)
dumps to standard output the file’s content from current position to the end,
closes the file
Returns true if successful and otherwise false
Function
file_get_contents( Path )
is like readfile()
But returns file contents as a string
PHP read functions are generally binary-safe
Treat their input as a raw stream of data with no specific format
Should work with all 256 possible character values
In contrast, most functions that recognize special characters (e.g., escape codes) or expect null-terminated strings
aren’t binary safe
Binary safe functions required when working with data of unknown format
E.g., arbitrary files and encrypted data
Other File Functions Function
file_exists( Path )
given the path for a file,
returns true if the file exists and false if not
E.g., used to avoid trying to open non-existent file
Function
nl2br()
Really a string function
Takes a string argument
Returns a string with \n characters replaced by <br> tags
Can replace all code producing HTML that lists the orders withecho nl2br( file_get_contents(
$_SERVER[DOCUMENT_ROOT].'/../phpData/orders.txt' ) );
Each order is on a separate, as in the original
To delete a file:
unlink( Path )
where Path is the path to the file
Returns true if successful, false otherwise
Fails if, e.g., wrong permissions or file doesn’t exist
PHP has several functions to position the current position pointer in a file Allows random access Not covered
Uploading Files Value "file" for the type attribute of an input form element is for
uploading files to the server
Rendered, it provides a ‘Browse’ button
When clicked, opens a window to browse the files on the client’s system to select the file to upload
This input type
requires that the POST method be used and
requires some accompanying information in the form
The accompanying info in the form:
The form element must have the attribute-value pair
enctype="multipart/form-data"
Before the input element with type="file", need
<input type="hidden" name="MAX_FILE_SIZE" value="1000000">
The name value is mandatory
The value value (in bytes) can be anything reasonable
Example HTML Document<html>
<head>
<title>Upload New Files</title>
</head>
<body>
<h1>Upload new news files</h1>
<form enctype="multipart/form-data" action="upload.php" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="1000000">
Upload this file: <input name="userfile" type="file">
<input type="submit" value="Send File">
</form>
</body>
</html>
Rendered as
PHP to Handle a File Upload The PHP script fielding this request accesses the global $_FILES
Contains all the info on the uploaded file
Assume the value of the name attribute of the file input element is "userfile" (as above), we have
$_FILES['userfile']['name']
the original name of the file on the client machine
$_FILES['userfile']['type']
the mime type of the file (e.g., "text/plain" for a .txt file)
$_FILES['userfile']['size']
the size, in bytes, of the uploaded file
$_FILES['userfile']['tmp_name']
temporary filename for where uploaded file stored on the server
$_FILES['userfile']['error']
the error code associated with this file upload.
By default, uploaded files are stored in the server's default temporary directory
unless another location given with the upload_tmp_dir directive in php.ini
The server’s default directory can be changed by setting environment variable TMPDIR
The default temporary folder for my WampServer is C:\wamp\tmp\
File upload.php (below) echoes the info in $_FILES['userfile']
Main thing it does: copy the uploaded file
from the temporary folder
to its intended location Intended folder is C:\uploads\ We retain the name of the file itself
The PHP code sets variable $upfile to the full pathname for the file in its intended location
$upfile = '/uploads/'.$_FILES['userfile']['name'];
"C:" can be omitted—my document root is on that disk
To move the file from the temporary folder to the new location, use
move_uploaded_file( filename, destination )
Copies uploaded file with name filename to destination, a full pathname
In our example, filename is
$_FILES['userfile']['tmp_name']
Before moving the file, checks that the file named filename is a valid upload file (uploaded via POST)
Returns True on successfully moving the file
File upload.php<html>
<head>
<title>Uploading ...</title>
</head>
<body>
<h3>Uploading the file</h3>
<?php
// Put the file where we'd like it
$upfile = '/uploads/'.$_FILES['userfile']['name'];
if ( ! move_uploaded_file( $_FILES['userfile']['tmp_name'], $upfile ) ) {
echo 'Problem: Could not move file to desitination folder';
exit;
}
echo "<p>";
echo "Temporary name: {$_FILES['userfile']['tmp_name']}<br />";
echo "Name: {$_FILES['userfile']['name']}<br />";
echo "Size: {$_FILES['userfile']['size']}<br />";
echo "Type: {$_FILES['userfile']['type']}<br />";
echo "Error: {$_FILES['userfile']['error']}<br />";
echo "</p>";
?>
</body>
</html>
For more information on uploading files with PHP, see the PHP Manual, “Handling file uploads”:
http://us3.php.net/manual/en/features.file-upload.php