• No results found

Storing Data in Text Files

In document Web Programming With PHP and MySQL (Page 107-114)

Although the topic of storing information in and retrieving it from a database will be covered in detail in later chapters of this book, the use of plain text fi les on the server to store data of a fairly basic kind is well worth knowing about and for new-comers to PHP has the advantage of avoiding the need to learn another language (mySQL or something similar) at the same time as learning PHP.

7 Using Files

Organising data in plain text fi les is a very basic but often very useful way of storing it. In some cases we will use a PHP script to read a fi le that already exists.

At other times we will use a script to write a new fi le or to add to a fi le that already exists. We will assume that a text fi le is broken up into a number of lines separated by newline characters.

Note that although it is not possible to use a web browser to access fi les such as fi le1.txt and directories such as tmp (both shown in the fi rst fi gure in Sect. 7.1 ) that are not part of the hierarchy starting at directory public_html, it is entirely possible for a PHP script to do so. If the current directory is 'members' we can legitimately refer to fi le "../../etc/fi le1.txt" or directory "../../tmp".

7.3.1 Opening a File

Before we can write to or create a fi le, we fi rst have to open it, i.e. establish a link to the fi le from a PHP script. We do this using the system function fopen , which takes two arguments. The fi rst is the (relative) name of the fi le, the second is a string con-stant called the mode , which indicates how we intend to use the fi le. By the name of the fi le we mean its address relative to the current directory, including the path.

For example fopen("mydir/myfi le.txt","a") indicates that we wish to open (i.e.

use) a fi le with name myfi le.txt in directory mydir relative to the current directory and if the fi le already exists we intend to append to it, i.e. write additional records (lines of text) to it, which are to be placed after those already there. If no fi le of the given name exists, an empty fi le with the specifi ed name but no contents will fi rst be created.

Another possible value for the second parameter is "w" (write), meaning if the fi le exists start by deleting all its contents before anything is written. If not, create an empty fi le.

A third possibility for the second argument is "r", meaning that the fi le should be opened for reading only. The use of the system function 'fi le' described later in this chapter is easier than opening the fi le using the "r" option and we will adopt that approach in this book.

We can also combine the "r" and "w" options to give "w+" or combine "r" and

"a" to give "a+". There are other possible modes but these are the most important ones.

The fopen function returns a value of a special kind known as a resource , which must be assigned to a variable, which is then known as the fi le pointer for the speci-fi ed speci-fi le. The name of a speci-fi le pointer variable can be any valid PHP variable name, but in this book we will generally call it $fp. Thus we can write the statement

98

to open fi le mydir/myfi le.txt for 'appending' with fi le pointer $fp (assuming that directory mydir already exists).

7.3.2 Closing a File

Having opened a fi le for appending or writing, we can then write lines of text to it using the fwrite system function, as will be described below. Once we have fi nished doing this we should 'close' the fi le again, i.e. make it unavailable for use (until and unless it is opened again). We can do this using the fclose function, which takes the fi le pointer as its only argument.

Function fclose returns TRUE for success or FALSE for failure, but is normally used as a 'standalone' function, i.e. its value is not assigned to a variable.

Warning - fi les should always be closed promptly as soon as reading and/or writ-ing operations are concluded. If the PHP script should contain an error leadwrit-ing the PHP interpreter to 'crash' while a fi le is open it is possible that its contents can be corrupted.

7.3.3 Writing to an Open File

Assuming that a fi le with fi le pointer $fp has been opened for appending (or writing) we can write a line of text to it by using the fwrite system function. This takes two arguments: the fi rst is the fi le pointer; the second is the string of characters we wish to write to the fi le, e.g.

We usually want the output string to end with an end of line character or charac-ters. Unfortunately there are two 'standards' for this. For a Windows server we place the two characters 2 denoted by \r\n at the end of the line, e.g.

For all other kinds of server we output the single character denoted by \n.

2 It is important to appreciate that the combination \r\n represents two characters that will be stored in the text fi le and not four. We cannot type these characters directly into a PHP script (or a page of this book) so instead type the characters \r\n which requires four keystrokes.

7 Using Files

The combinations \r and \n are both 'escape sequences'. They cause special char-acters (not the actual letters r and n) to be written to the fi le, corresponding roughly to 'carriage return' and 'newline'. In practice it does little if any harm to standardise on using just one of the newline sequences irrespective of the server. The only (fairly minor) problem that arises is if a fi le written on a server using one operating system is downloaded to a computer that uses the other. If the fi le is displayed on the 'wrong' system it is likely not to look entirely as expected.

As a way round the problem of different end of line sequences, from PHP version 5.0.2 onwards it has been possible to use the PHP constant PHP_EOL which cor-responds to the correct end of line sequence for the server on which the script is run.

So we can write

Note that PHP_EOL is a name and so is not enclosed in quotes and that PHP_

EOL is case-sensitive.

Function fwrite returns the number of bytes written, or FALSE if an error occurs, but is normally used as a standalone function.

7.3.4 Formatted Writing to an Open File

The printf function was introduced in Chap. 6 as a formatted print function. A typi-cal example is the function typi-call

The parts of the fi rst argument (string) beginning with % and ending in a letter are format specifi ers. The specifi er %.2f stands for 'the value of $b rounded to two decimal places'. Specifi er %d stands for 'the value of $c printed as an integer'.

Function printf displays output in the user's web browser. The function fprintf is the equivalent when writing to a text fi le. It has an additional fi rst argument which is the name of a fi le pointer for an open fi le. For example

100

7.3.5 Reading an Open File

The fread function reads a specifi ed number of characters from an open fi le. It takes a fi le pointer and an integer as its arguments and returns a string. For example

reads 30 characters (starting at the beginning of the fi le) or up to the end of the fi le whichever is reached sooner. The 30 characters include the end of line character(s) at the end of each line. A subsequent fread will begin where the last one ended.

The fi lesize function takes a relative fi lename as its argument and returns the size of the corresponding fi le in bytes (i.e. characters) of storage. Thus to read all the characters in a text fi le (including end of line characters) we can use an instruction such as

For reading text fi les it is frequently much more convenient to use the fi le func-tion described below rather than using fopen, fread and fclose.

7.3.6 The File Function

PHP has a very powerful function named fi le which takes the (relative) name of a text fi le as its argument and returns an indexed array with one element for each line of the fi le. Let us assume that fi le1.txt is a text fi le in the same directory as the cur-rent PHP script and has the following contents

(Each line is assumed to end with the appropriate end of line character(s).) Executing the PHP statement

will copy the contents of the fi le into the fi rst six elements of array $arr1.

7 Using Files

• $arr[0] is now "The time has come, the Walrus said,"

• $arr[1] is now "To talk of many things:"

and so on.

Note that there is no need to use fopen and fclose with the fi le function. The fi le is automatically opened and closed.

It is important to remember that there is an 'invisible' end of line character or characters at the end of each line. Because of this, if we have a comparison such as

the test will fail. To avoid this problem it is good practice to trim each line before using it to remove the end of line character(s) at the end of the string. Strictly only rtrim ('right trim') is necessary.

It is also important to realise that the web browser does not display characters such as 'carriage return' and 'newline' on the user's screen. It treats any number of them, together with any number of spaces as equivalent to a single space. So

will print the fi rst and second lines of text as one long line, with a space separating the two parts. To separate them by a line break we must output the HTML tag <br>.

7.3.7 Examples

Given fi le fi le1.txt as before we wish to output its contents line by line. We can do this by this two-line script.

If for some reason we wish to output all the contents of fi le1.txt except the fi rst line to a new fi le fi le2.txt (e.g. to remove a header line) we can do so using the fol-lowing script. In this case we retain the end of line character(s) at the end of each line.

102

7.3.8 Using the Explode and Implode Functions

Text fi les often have a fi xed structure for each line, for example 12 values separated by commas or tab characters. If we want to change them all in a systematic way we can often do so easily using the explode and implode functions.

Suppose we have a club membership fi le named memfi le.txt, with the fi rst three records as follows:

We wish to put the members' full names as the fi rst component of each record, i.e.

We start by converting the text fi le into an array using the fi le statement and then create a loop to process each of the records one by one, create a new record named

$newRecord and write it to a new text fi le memfi le2.txt.

To create $newRecord from $next we fi rst use the explode function to convert string $next into the elements of an array $nextArray. We set the fi rst element of a new array, $secondArray[0], to the full name and then copy elements $nextAr-ray[0], $nextArray[0] etc. into $secondArray[1], $secondArray[2] etc.

All that remains is to 'implode' $secondArray into a string with values separated by commas:

7 Using Files

If we wanted to use a tab character rather than a comma as a separator we would replace "," by "\t".

Putting the fragments together gives the following complete script:

In document Web Programming With PHP and MySQL (Page 107-114)