- Opening with 'r+' will fail, if the file is not writable, even if you just want to read and not write to it.
- Both 'w' and 'w+' will completely delete the contents of an existing file as soon as you open it. If you intend to add data, you need to use 'a' or 'a+'.
- If you want to create new files, and also prevent accidentally overwriting and existing file, use 'x' or 'x+'.
- When working with binary files, such as images, add the letter 'b' after the mode. For example: 'rb' or 'r+b'
An In-Depth Overview of File Operations in PHP
13-02-2016 01:38:31
PHP / File Handling
0 Bookmark(s)
920 View(s)
There is no such function as
Now it is time to start dealing with some file pointers. There is more than one way of reading the contents of a file in PHP, but we are going to start with the most basic method first. Later in the article we will learn about the alternative methods. There are three file functions we will use here:
Since we started working with file pointers, let's take a moment and try to understand them better. A file pointer, also known as a file "handle", is a variable that refers to a file. The exact value of this variable is unimportant; all we need to know is that it points to a specific file. The pointer is usually obtained by opening a file. In PHP we use the
The file pointer actually does more than just pointing to a file. It also points to a specific position inside that file. In most cases, when you open a file, the file pointer points to the beginning (or position 0) in that file. We will cover this concept in more detail when we talk about
Just like reading files, there is more than one way of writing to a file. First we will see the basic way, and later in the article we will look at alternatives. The following code writes the contents of the $data variable into the test.txt file.
Creating a New File
The examples above also work for creating new files. If the file test.txt does not exist, it will be created automatically, just by the
The act of moving the file pointers location is called "seeking". To seek we can use the function
The file pointer position can move by operations other than
By looking at these, you can see that we have more options than we talked about so far. Here are some important factors to consider about picking the right option:
* On Windows this will always be 0.
** Only valid on systems supporting the st_blksize type - other systems (e.g. Windows) return -1.
In case of error, stat() returns FALSE.
This function returns the entire contents of a given file. Also you do not need to deal with file pointers at all.
Yes, this function is simply named file, and it again returns the entire contents of a file. But this time, the contents are split into an array, by the newline character. Let's create a file with the following contents:
Again, there is no need to use file pointers. This function simply writes the given data to the given file:
These are alternatives to the stat function for getting file information.
Checking for Permissions
Your script may or may not have read and/or write access to a file due to various reasons. Before attempting to open a file for reading or writing, it is wise to check if you have permission to do so:
To set the permissions of a file, we use the chmod function:
In this tutorial we will learn how to work with file operations using PHP. This is one of the most fundamental subjects of server side programming in general. Files are used in web applications of all sizes. So let's learn how to read, write, create, move, copy, delete files and more.
Copying, Moving and Deleting Files
We are going to start learning with these operations first, because they are very simple one liners, and they do not involve dealing with file pointers. Copying a fileMoving a File$file = "test.txt"; $new_file = "test_copy.txt"; copy($file, $newfile);
Note that the function is called$file = "test.txt"; $new_file = "test_copy.txt"; rename($file, $newfile);
"rename" and not "move". Internally, renaming a file is the same as moving it to a new location.
Same code works when changing the directory of the file:
Deleting a File$file = "test.txt"; $new_file = "different/folder/test_copy.txt"; rename($file, $newfile);
There is no such function as
"delete". Here we call the "unlink" function.
Opening and Reading a File$file = "test.txt"; unlink($file, $newfile);
Now it is time to start dealing with some file pointers. There is more than one way of reading the contents of a file in PHP, but we are going to start with the most basic method first. Later in the article we will learn about the alternative methods. There are three file functions we will use here:
fopen, fread and fclose.
When opening the file, we include a second parameter, which determines the type of access. In this case$file = "test.txt"; // open the file $fp = fopen($file, "r"); // read 5k data from the file $contents = fread($fp, 5000); // close the file fclose($fp);
"r" stands for "read only". There are other types that we need to use for writing and appending that we will cover later in the article.
The second important thing to pay attention to is the second parameter in the fread function. This determines the length of the data (in bytes) to read from the file. To read the entire contents of the file, we need to pass the total file size. The filesize function does the trick:
Understanding File Pointers$file = "test.txt"; // open the file $fp = fopen($file, "r"); // read 5k data from the file $contents = fread($fp, filesize($file)); // close the file fclose($fp);
Since we started working with file pointers, let's take a moment and try to understand them better. A file pointer, also known as a file "handle", is a variable that refers to a file. The exact value of this variable is unimportant; all we need to know is that it points to a specific file. The pointer is usually obtained by opening a file. In PHP we use the
fopen function.
Even though PHP has an excellent garbage collector that closes all open file pointers at the end of a scripts execution, it is considered a good practice to close them manually using the fclose function.
Position in a File$fp = fopen($file, 'r'); // ... // always close files fclose($fp);
The file pointer actually does more than just pointing to a file. It also points to a specific position inside that file. In most cases, when you open a file, the file pointer points to the beginning (or position 0) in that file. We will cover this concept in more detail when we talk about
"seeking" later in the article.
Writing To a FileJust like reading files, there is more than one way of writing to a file. First we will see the basic way, and later in the article we will look at alternatives. The following code writes the contents of the $data variable into the test.txt file.
This time we used a different flag for opening the file. The$file = "test.txt"; $data = "0123456789abc"; // open the file for writing $fp = fopen($file, "w"); // write data to the file fwrite($fp, $data); // close the file fclose($fp);
"w" flag opens the file for writing, and overwrites all existing data in the file. If there was anything in the test.txt file, it will be replaced with the string in $data.
The fwrite function was very simple, we just passed the file pointer and the data to be written to the file. There is an optional third parameter that determines the length of data to be written:
If you run the code above, the contents of test.txt will only be "01234".$file = "test.txt"; $data = "0123456789abc"; // open the file for writing $fp = fopen($file, "w"); // write data to the file (only 5 bytes) fwrite($fp, $data, 5); // close the file fclose($fp);
Creating a New File
The examples above also work for creating new files. If the file test.txt does not exist, it will be created automatically, just by the
fopen function call.
If all you want to do is to create a new blank file, without writing any data in it, this code will work:
Seeking$file = "does_not_exist.txt"; // creates and opens the file $fp = fopen($file, "w"); // close the file fclose($fp);
The act of moving the file pointers location is called "seeking". To seek we can use the function
fseek, and to get the position of a given pointer, we can use the function ftell.
Before we use seeking, let's create a file with 10 bytes of data in it.
Now let's see how these functions behave. Here are a few different examples:$file = "test.txt"; $data = "0123456789"; $fp = fopen($file, "w"); fwrite($fp, $data); fclose($fp);
Other Operations Moving File Pointer Position$file = "test.txt"; // opening for reading, pointer should be at 0 $fp = fopen($file, "r"); echo "open: "; // outputs 0 echo ftell($fp)."\n"; // ----- // seek to byte 4 fseek($fp, 4); echo "seek 4: "; // outputs 4 echo ftell($fp)."\n"; // ----- // you can go out of bounds fseek($fp, 9000); echo "out of bounds: "; // outputs 9000 echo ftell($fp)."\n"; // ---- // this is how you get to the end fseek($fp, 0, SEEK_END); echo "end: "; // outputs 10 echo ftell($fp)."\n"; // ---- // move relative to current position // negative numbers work fseek($fp, -3, SEEK_CUR); echo "go back by 3: "; // outputs 7 echo ftell($fp)."\n"; // ---- // or seek relative to the end // again, negative works fseek($fp, -3, SEEK_END); echo "go back by 3 from the end: "; // outputs 7 echo ftell($fp)."\n"; // ---- // does the same thing as seeking to 0 rewind($fp); echo "rewind: "; // outputs 0 echo ftell($fp)."\n"; fclose($fp);
The file pointer position can move by operations other than
fseek.
For example, reading moves the position:
Writing also moves it:$file = "test.txt"; $fp = fopen($file, "r"); // reading 6 bytes $data = fread($fp, 6); // outputs 6 echo ftell($fp); fclose($fp);
$file = "test.txt"; $data = "0123456789"; $fp = fopen($file, "w"); // writing 10 bytes fwrite($fp, $data); // outputs 10 echo ftell($fp); fclose($fp);
File Access Modes
Now that we are familiar with the reading, writing and seeking concepts, it is time better understand the different file access modes. When opening a file with thefopen function, the second parameter must be provided, which is the file access mode. There is a table in the PHP manual describing them:
| Modes | Description |
|---|---|
| r | Open a file for read only. File pointer starts at the beginning of the file |
| w | Open a file for write only. Erases the contents of the file or creates a new file if it doesn't exist. File pointer starts at the beginning of the file |
| a | Open a file for write only. The existing data in file is preserved. File pointer starts at the end of the file. Creates a new file if the file doesn't exist |
| x | Creates a new file for write only. Returns FALSE and an error if file already exists |
| r+ | Open a file for read/write. File pointer starts at the beginning of the file |
| w+ | Open a file for read/write. Erases the contents of the file or creates a new file if it doesn't exist. File pointer starts at the beginning of the file |
| a+ | Open a file for read/write. The existing data in file is preserved. File pointer starts at the end of the file. Creates a new file if the file doesn't exist |
| x+ | Creates a new file for read/write. Returns FALSE and an error if file already exists |
Getting File Information
There are many pieces of information we can obtain about a file besides just its contents (size, last access time, modify time etc...) The main function used for this is stat. It returns the information in an array:The data is in 12 pieces and is repeated, first with numeric keys, and then again with string keys. The PHP manual has a table explaining each of them:$data = stat("test.txt"); print_r($data); /* prints: Array ( [0] => 2 [1] => 0 [2] => 33206 [3] => 1 [4] => 0 [5] => 0 [6] => 2 [7] => 10 [8] => 1264374556 [9] => 1264374556 [10] => 1264373231 [11] => -1 [12] => -1 [dev] => 2 [ino] => 0 [mode] => 33206 [nlink] => 1 [uid] => 0 [gid] => 0 [rdev] => 2 [size] => 10 [atime] => 1264374556 [mtime] => 1264374556 [ctime] => 1264373231 [blksize] => -1 [blocks] => -1 ) */
| Numeric | Associative | Description |
|---|---|---|
| 0 | dev | device number |
| 1 | ino | inode number * |
| 2 | mode | inode protection mode |
| 3 | nlink | number of links |
| 4 | uid | userid of owner * |
| 5 | gid | groupid of owner * |
| 6 | rdev | device type, if inode device |
| 7 | size | size in bytes |
| 8 | atime | time of last access (Unix timestamp) |
| 9 | mtime | time of last modification (Unix timestamp) |
| 10 | ctime | time of last inode change (Unix timestamp) |
| 11 | blksize | blocksize of filesystem IO ** |
| 12 | blocks | number of 512-byte blocks allocated ** |
Alternative Functions
As I mentioned earlier, there are other alternative functions that can be used for reading and writing files. Let's go over some of them. file_get_contentsThis function returns the entire contents of a given file. Also you do not need to deal with file pointers at all.
The function accepts four more additional parameters as described in the PHP manual. For example, to read only a portion of the file, you can set the fourth and fifth parameters:$file = "test.txt"; $contents = file_get_contents($file);
file$file = "test.txt"; // reads 5 bytes of data, starting at byte 3 $contents = file_get_contents($file, NULL, NULL, 3, 5);
Yes, this function is simply named file, and it again returns the entire contents of a file. But this time, the contents are split into an array, by the newline character. Let's create a file with the following contents:
Now use the function:abc 123 empty line after this last line
It may not be obvious, but there is a newline character at the of each array element. If you don't want them, you can either trim them manually, or use the$file = "test.txt"; $contents = file($file); print_r($contents); /* prints Array ( [0] => abc [1] => 123 [2] => empty line after this [3] => [4] => last line ) */
FILE_IGNORE_NEW_LINES flag:
If you do not want the empty lines either, you can use the$file = "test.txt"; $contents = file($file, FILE_IGNORE_NEW_LINES); print_r($contents); /* prints Array ( [0] => abc [1] => 123 [2] => empty line after this [3] => [4] => last line ) */
FILE_SKIP_EMPTY_LINES flag:
file_put_contents$file = "test.txt"; $contents = file($file, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES); print_r($contents); /* prints Array ( [0] => abc [1] => 123 [2] => empty line after this [3] => last line ) */
Again, there is no need to use file pointers. This function simply writes the given data to the given file:
filesize, fileatime, filemtime$file = "test.txt"; $data = "0123456789"; file_put_contents($file, $data);
These are alternatives to the stat function for getting file information.
$file = "test.txt"; // gets the file size echo filesize($file); // gets the last time the file was modified echo filemtime($file); // gets the last time the file accessed echo fileatime($file);
File Permissions
Unix-like systems have a quite detailed file permissions standard. Windows systems have it a little simpler. The whole subject of file permissions can be lengthy and a whole separate article can be written on it. So instead, we will only look at two simple concepts of file permissions: being "readable", and being "writable".Checking for Permissions
Your script may or may not have read and/or write access to a file due to various reasons. Before attempting to open a file for reading or writing, it is wise to check if you have permission to do so:
Setting the Permissions$file = "test.txt"; if (is_readable($file)) { // file is readable } if (is_writable($file)) { // file is writable }
To set the permissions of a file, we use the chmod function:
The above code should work on both Unix and Windows systems. However, you may not be able to set the permissions, if you do not own the file or have any permissions to it in the first place.$file = "test.txt"; // makes the file read-only chmod($file, 0444); // makes the file readable and writable chmod($file, 0666);
Using Loops for Big Files
Last thing we are going to talk about is a quick tip for handling big files. This has some performance implications. Easiest way to read and output a file is this:But that causes the entire contents of the file to be loaded into the memory. It will persist as long as it is being downloaded by the web surfer. If you have multiple people downloading files at the same time, this can consume your web servers memory very quickly. A better idea for handling this would be to use a loop to read only small chunks of the file at a time. For the loop condition we will utilize the$file = "test.txt"; echo file_get_contents($file);
feof function:
The code above will only load 4kb of data at once into the memory, and this will greatly reduce the memory usage for big file outputs. The$file = "test.txt"; $fp = fopen($file, 'r'); while (!feof($fp)) { echo fread($fp, 4092); } fclose($fp);
feof function returns true when we reach the end of the file, and this breaks out of the loop.
Was this article helpful?
Tags:
file operations, file handling, reading and writing in file