Home >Backend Development >PHP Tutorial >Correct way to read files with PHP
Learn how to use PHP’s various file functions. Review basic file functions such as fopen, fclose, and feof; learn about read functions such as fgets, fgetss, and fscanf. And found functions that process entire files in one or two lines of code.
Let’s count how many ways there are
One of the joys of working with a modern programming language like PHP is the sheer number of options available. PHP easily wins Perl's motto "There's more than one way to do it" (not just one way to do it), especially when it comes to file handling. But with so many options available, which one is the best tool for the job? Of course, the actual answer depends on your goals for parsing the file, so it's worth taking the time to explore all options.
The traditional fopen method
The fopen method is probably the most familiar to former C and C++ programmers, because if you've used those languages, they're more or less tools you've had at your disposal for years. For either of these methods, the file is opened by the standard method of using fopen (the function used to read data), and then closed using fclose, as shown in Listing 1.
Listing 1. Open and read files with fgets
$file_handle = fopen("myfile", "r");
while (!feof($file_handle)) {
$line = fgets($file_handle);
echo $line;
}
fclose($file_handle);
While most programmers with years of programming experience are familiar with these functions, let me break them down. Effectively follow these steps:
Open the file. $file_handle stores a reference to the file itself.
Check if you have reached the end of the file.
Continue reading the file until the end of the file is reached, printing each line as it is read.
Close the file.
With these steps in mind, I will review every file function used here.
fopen
fopen function will create a connection to a file. I say "create a connection" because in addition to opening a file, fopen can also open a URL:
$fh = fopen("http://127.0.0.1/", "r");
This line of code will create a connection to the page above and allow you to start reading it like a local file.
Note: The "r" used in fopen will instruct the file to be opened read-only. Since writing data to a file is outside the scope of this article, I won't list all other options. However, if reading from a binary file for cross-platform compatibility, "r" should be changed to "rb". You'll see an example of this later.
feof
feof command will detect if you have reached the end of the file and return True or False. The loop in Listing 1 continues until you reach the end of the file "myfile". Note: feof will also return False if a URL is being read and the socket times out because there is no more data to read.
fclose
Skipping forward to the end of Listing 1, fclose will do the opposite of fopen: it will close the connection to a file or URL. After executing this function, you will no longer be able to read any information from the file or socket.
fgets
Jump back a few lines in Listing 1 and you get to the heart of file processing: actually reading the file. The fgets function is the weapon of choice for the first example. It will extract a row of data from the file and return it as a string. After that, you can print or otherwise manipulate the data. The example in Listing 1 will print the entire file fine.
If you decide to limit the size of the processing data chunks, you can add a parameter to fgets to limit the maximum row length. For example, use the following code to limit the line length to 80 characters:
$string = fgets($file_handle, 81);
Recall "
Note: The examples for this function already use slightly different parameters than fopen. When working with binary data, always remember to include the b option to fopen. If you skip this point, Microsoft® Windows® systems may not handle the file correctly because they handle new lines differently. If you're dealing with a Linux® system (or some other UNIX® variant), this may not seem to matter. But even if you're not developing for Windows, doing so will result in good cross-platform maintainability and is a good practice to follow.
The above code will read 4,096 bytes (4 KB) of data. Note: No matter how many bytes are specified, fread will never read more than 8,192 bytes (8 KB).
Assuming the file size is no more than 8 KB, the following code should be able to read the entire file into a string.
$fh = fopen("myfile", "rb");
$data = fread($fh, filesize("myfile"));
fclose($fh);
If the file length is greater than this value , you can only use a loop to read in the rest.
fscanf
Back to string processing, fscanf also follows the traditional C file library function. If you're not familiar with it, fscanf reads field data from a file into variables.
list ($field1, $field2, $field3) = fscanf($fh, "%s %s %s");
The format string used by this function is described in many places (such as PHP. net), so I won’t go into details here. Suffice to say, string formatting is extremely flexible. It is worth noting that all fields are placed in the return value of the function. (In C, they are all passed as arguments.)
fgetss
fgetss functions differ from traditional file functions and give you a better understanding of the power of PHP. This function functions like the fgets function, but will strip any HTML or PHP tags found, leaving only plain text. View the HTML file shown below.
Listing 2. Sample HTML file
If you understand what "Cause there ain't no one for to give you no pain"
means then you listen to too much of the band America
then pass fgetss function to filter it.
Listing 3. Using fgetss
$file_handle = fopen("myfile", "r");
while (!feof($file_handle)) {
echo = fgetss($file_handle);
}
fclose($ file_handle);
The following is the output:
My title
If you understand what "Cause there ain't no one for to give you no pain"
means then you listen to too much of the band America
fpassthru function
No matter how you read the file, you can use fpassthru to dump the rest of the data to the standard output channel.
fpassthru($fh);
Also, this function will print the data, so there is no need to use variables to get the data.
Nonlinear file processing: skip access
Of course, the above function only allows sequential reading of files. More complex files may require you to jump back and forth to different parts of the file. This is where fseek comes in handy.
fseek($fh, 0);
The above example will jump back to the beginning of the file. If you don't need to return exactly - we can specify to return kilobytes - then you can write:
fseek($fh, 1024);
Starting with PHP V4.0, you have a few other options. For example, if you need to jump forward 100 bytes from the current position, you can try using:
fseek($fh, 100, SEEK_CUR);
Similarly, you can use the following code to jump backward 100 Bytes:
fseek($fh, -100, SEEK_CUR);
If you need to jump backward to 100 bytes before the end of the file, you should use SEEK_END.
fseek($fh, -100, SEEK_END);
After reaching the new location, you can use fgets, fscanf or any other method to read the data.
Note: fseek cannot be used for file processing that refers to URLs.
Extract an entire file
Now, we’ll touch on some of PHP’s more unique file-handling features: processing large chunks of data in a line or two. For example, how to extract a file and display its entire contents on a web page? Okay, you saw an example of fgets using a loop. But how can this process be made easier? The process is super easy with fgetcontents, which puts the entire file into a string.
$my_file = file_get_contents("myfilename");
echo $my_file;
Although it is not the best practice, this command can be written more concisely as:
echo file_get_contents("myfilename");
This article mainly introduces how to process local files, but it is worth noting that you can also use these functions to extract, echo and parse other web pages.
echo file_get_contents("http://127.0.0.1/");
This command is equivalent to:
$fh = fopen("http://127.0.0.1/", "r");
fpassthru($fh);
You will definitely look at this command and think: "That's still too much effort". PHP developers agree with you. So the above command can be shortened to:
readfile("http://127.0.0.1/"); The
readfile function will dump the entire contents of the file or web page to the default output buffer. By default, this command will print an error message if it fails. To avoid this behavior (if needed), try:
@readfile("http://127.0.0.1/");
Of course, if you do need to parse the file, the single string returned by file_get_contents may be somewhat It's too much to bear. Your first instinct might be to break it up using the split() function.
$array = split("n", file_get_contents("myfile"));
But why go to all this trouble when there is already a great function that does this for you? PHP's file() function does this in one step: it returns an array of strings divided into lines.
$array = file("myfile");
It should be noted that there is a slight difference between the above two examples. Although the split command will remove new lines, when using the file command (as with the fgets command), new lines will still be appended to the strings in the array.
However, the power of PHP goes far beyond that. You can use parse_ini_file to parse an entire PHP-style .ini file in a single command. The parse_ini_file command accepts a file similar to the one shown in Listing 4.
Listing 4. Sample .ini file
; Comment
[personal information]
name = "King Arthur"
quest = To seek the holy grail
favorite color = Blue
[more stuff]
Samuel Clemens = Mark Twain
Caryn Johnson = Whoopi Goldberg
The following command will dump this file into an array and then print the array:
$file_array = parse_ini_file("holy_grail.ini");
print_r $file_array;
The following output is the result:
Listing 5. Output
Array
(
[name] => King Arthur
[quest] => To seek the Holy Grail
[favorite color] => Blue
[Samuel Clemens] => Mark Twain
[Caryn Johnson] => Whoopi Goldberg
)
Of course, you may notice that this command merges the parts. This is the default behavior, but you can easily fix it by passing the second argument to parse_ini_file: process_sections, which is a boolean variable. Set process_sections to True.
$file_array = parse_ini_file("holy_grail.ini", true);
print_r $file_array;
and you will get the following output:
Listing 6. Output
Array
(
[personal information] = > Array
(
[name] => King Arthur
[quest] => To seek the Holy Grail
[favorite color] => Blue
)
[more stuff] => Array
(
[Samuel Clemens] => Mark Twain
[Caryn Johnson] => Whoopi Goldberg
)
)
PHP will put the data into a multi-dimensional array that can be easily parsed.
This is just the tip of the iceberg when it comes to PHP file processing. More complex functions such as tidy_parse_file and xml_parse can help you process HTML and XML documents respectively. See Resources for details on the use of these special functions. Those references are worth a look if you're dealing with those types of files, but without overthinking every file type you might encounter that's been talked about in this article, here are some good ones for working with the functions covered so far general rules.
Best Practices
Never assume that everything in a program will run as planned. For example, what if the file you're looking for has been moved? What if the permissions have been changed and its contents cannot be read? You can check for these issues beforehand by using file_exists and is_readable.
Listing 7. Using file_exists and is_readable
$filename = "myfile";
if (file_exists($filename) && is_readable ($filename)) {
$fh = fopen($filename, "r");
# Processing
fclose($fh);
}
However, in practice, using such code may be too cumbersome. Handling fopen's return value is simpler and more accurate.
if ($fh = fopen($filename, "r")) {
# Processing
fclose($fh);
}
Since fopen will return False on failure, this will ensure that the file is only opened successfully File processing is then performed. Of course, you can expect a negative return value if the file does not exist or is not readable. This will allow the inspection to check for all problems that may be encountered. Additionally, if the opening fails, you can exit the program or have the program display an error message.
Like the fopen function, the file_get_contents, file and readfile functions all return False when opening fails or when processing the file fails. The fgets, fgetss, fread, fscanf, and fclose functions also return False on error. Of course, you may have handled the return values of all of these functions except fclose. When using fclose, nothing is done even if file handling is not closed gracefully, so it is usually not necessary to check the return value of fclose.
The choice is yours
PHP has no shortage of efficient ways to read and parse files. A typical function like fread may be the best choice most of the time, or you may find yourself more attracted to the simplicity of readfile when readfile is just right for the task. It really depends on what is being done.
If you have a lot of data to process, fscanf will prove its worth and be more efficient than using file with the split and sprintf commands. Conversely, if you want to echo a large amount of text with only minor modifications, it may be more appropriate to use file, file_get_contents, or readfile. This may be the case when using PHP for caching or creating a stopgap proxy server.
PHP provides you with a large number of tools for processing files. Learn more about these tools and see which ones are best suited for the project you're working on. You already have a lot of options, so take advantage of them and enjoy working with files in PHP.