「PHP Programming/Files」の版間の差分

削除された内容 追加された内容
M Minor edits
M Minor edits
1 行
{{Programming/Navigation|next=Mailing|previous=Functions}}
Working with files is an important part of any programming language, and PHP is no different. Whatever your reasons are for wanting to manipulate files, PHP will happily accommodate them through the use of a handful of functions. You should have read and be comfortable with the concepts presented in the first five sections of this book before beginning here.
|lang=PHP
|next=Mailing
|previous=Functions
}}
Working with files is an important part of any programming language and PHP is no different. Whatever your reasons are for wanting to manipulate files, PHP will happily accommodate them through the use of a handful of functions. You should have read and be comfortable with the concepts presented in the first five sections of this book before beginning here.
 
==''fopen()'' and ''fclose()''==
''fopen()'' is the basis for file manipulation. It opens a file in a certain mode (whichthat you specify) and returns a handle. Using this handle you can read and/or write to the file, before closing it with the ''fclose()'' function.
 
{{Code:Basic
13 ⟶ 9行目:
|<source lang="php">
<?php
$handle = fopen('data.txt', 'r'); // Open the file for reading
fclose($handle); // Close the file
?>
</source>
|}}
 
In the example above you can see the file is opened for reading by specifying 'r' as the mode. For a full list of all the modes available to ''fopen(),'' you can look at the [http://php.net/fopen PHP Manual] page.
 
Opening and closing the file is all well and good, but to perform useful operations, you need to know about [http://php.net/fread ''fread()''] and [http://php.net/fwrite ''fwrite()''].
 
When a PHP script finishes executing, all open files are automatically closed. So although it is not strictly necessary to close a file after opening it, it is considered good programming practice to do so.
 
==Reading==
Reading can be done in a number of ways. If you just want all the contents of a file available to work with, you can use the [http://php.net/file_get_contents ''file_get_contents()''] function. If you want each line of the file in an array, you can use the [http://php.net/file ''file()''] command. For total control over reading from files, [http://php.net/fread() ''fread()''] can be used.
 
These functions are usually interchangeable and each can be used to perform each other's function. The first two do not require that you first open the file with ''fopen()'' or then close it with ''fclose()''. These are good for quick, one-time file operations. If you plan on performing multiple operations on a file it is best to use ''fopen()'' in conjunction with ''fread()'', ''fwrite()'' and ''fclose()'' as it is more efficient.
 
{{Code:Output
34 ⟶ 30行目:
|<source lang="php">
<?php
$contents = file_get_contents('data.txt');
echo $contents;
?>
</source>
45 ⟶ 41行目:
|<source lang="php">
<?php
$lines = file('data.txt');
foreach($lines as $Key => $line) {
$lineNum = $Key + 1;
echo "Line $lineNum: $line";
}}
}
?>
</source>
61 ⟶ 57行目:
|<source lang="php">
<?php
$handle = fopen('data.txt', 'r');
$string = fread($handle, 64);
fclose($handle);
 
echo $string;
?>
</source>
|<pre>I am the first 64 bytes of data.txt (if it was ASCII encoded). I</pre>
|This function can read up to the specified number of bytes from the file and return it as a string. For the most part, the first two functions will be preferable, but there are occasions when this function is needed.}}
 
As you can see, with these three functions you are able to easily read data from a file into a form that is convenient to work with. The next part shows how these functions can be used to do the jobs of the others, but this is optional. You may skip it and move onto the Writingwriting section, if you are not interested.
 
{{Code:Basic|
|<source lang="php">
<?php
$file = 'data.txt';
 
function detectLineEndings($contents) {
if(false !== strpos($contents, "\r\n")) return "\r\n";
else elseifif(false !== strpos($contents, "\r")) return "\r";
else return "\n";
}}
}
 
/* This is equivalent to file_get_contents($file), but is less efficient */
$handle = fopen($file, 'r');
$contents = fread($handle, filesize($file));
fclose($handle);
 
/* This is equivalent to file($file), but requires you to check for the line-ending
type. Windows systems use \r\n, Macintosh \r and Unix \n. File($file) will
automatically detect line-endings whereas fread/file_get_contents won't */
$lineEnding = detectLineEndings($contents);
$contents = file_get_contents($file);
$lines = explode($lineEnding, $contents);
 
/* This is also equivalent to file_get_contents($file) */
$lines = file($file);
$contents = implode("\n", $lines);
 
/* This is equivalent to fread($file, 64), if the file is ASCII encoded */
$contents = file_get_contents($file);
$ctringstring = substr($contents, 0, 64);
?>
</source>
108 ⟶ 104行目:
 
==Writing==
Writing to a file is done by using the [http://php.net/fwrite() ''fwrite()''] function in conjunction with [http://php.net/fopen() ''fopen()''] and [http://php.net/fclose() ''fclose()'']. As you can see, there aren't as many options for writing to a file as there are for reading from one. However, PHP 5 introduces the function [http://php.net/file_put_contents ''file_put_contents()''] whichthat simplifies the writing process somewhat. This function will be discussed later in the PHP 5 section, as it is fairly self-explanatory and does not require discussion here.
 
The extra options for writing don't come from the amount of functions, but from the modes available for opening the file. There are three different modes you can supply to the [http://php.net/fopen ''fopen()''] function, if you wish to write to a file. One mode, 'w', wipes the entire contents of the file so anything you then write to the file will fully replace what was there before. The second mode, 'a' appends stuff to the file so anything you write to the file will appear just after the original contents of the file. The final mode 'x' only works for non-existent files. All three writing modes will attempt to create the file, if it doesn't exist whereas the 'r' mode will not.
 
{{Code:Output
116 ⟶ 112行目:
|<source lang="php">
<?php
$handle = fopen('data.txt', 'w'); // Open the file and delete its contents
$data = "I am new content\nspread across\nseveral lines.";
fwrite($handle, $data);
fclose($handle);
 
echo file_get_contents('data.txt');
?>
</source>
133 ⟶ 129行目:
|<source lang="php">
<?php
$handle = fopen('data.txt', 'a'); // Open the file for appending
$data = "\n\nI am new content.";
fwrite($handle, $data);
fclose($handle);
 
echo file_get_contents('data.txt');
?>
</source>
150 ⟶ 146行目:
|<source lang="php">
<?php
$handle = fopen('newfile.txt', 'x'); // Open the file only, if it doesn't exist
$data = "I am this file's first ever content!";
fwrite($handle, $data);
fclose($handle);
 
echo file_get_contents('newfile.txt');
?>
</source>
161 ⟶ 157行目:
|}}
 
Of the three modes shown above, 'w' and 'a' are used the most, but the writing process is essentially the same for all the modes.
 
==Reading ''and'' Writing==
If you want to use [http://php.net/fopen ''fopen()''] to open a file for both reading ''and'' writing all you need to do is put a '+' on the end of the mode. For example, reading from a file requires the 'r' mode. If you want to read and write to/from that file you need to use 'r+' as a mode. Similarly you can read and write to/from a file using the 'w+' mode. howeverHowever, this will also truncate the file to zero length. For a better description visit the [http://php.net/fopen ''fopen()''] page whichthat has a very useful table describing all the modes available.
 
==Error Checking==
Error checking is important for any sort of programming, but when working with files in PHP it is especially important. This need for error checking arises mainly from the filesystem the files are on. The majority of webservers today are Unix-based and so, if you are using PHP to develop web-applications, you have to account for file permissions. In some cases PHP may not have permission to read the file and so, if you've written code to read a particular file, it will result in an ugly error. More likely is that PHP doesn't have permission to write to a file and that will again result in ugly errors. Also, the file's existence is (somewhat obviously) important. When attempting to read a file, you must make sure the file exists first. On the other side of that, if you're attempting to create and then write to a file using the 'x' mode then you must make sure the file ''doesn't'' exist first.
 
In short, when writing code to work with files, always assume the worst. Assume the file doesn't exist and you don't have permission to read/write to it. In most cases this means you have to tell the user that, in order for the script to work, he/she needs to adjust those file permissions so that PHP can create files and read/write to them, but it also means that your script can adjust and perform an alternative operation.
 
There are two main ways of error checking. The first is by using the '[http://uk.php.net/manual/en/language.operators.errorcontrol.php @]' operator to suppress any errors when working with the file and then checking, if the result is '''false''' or not. The second method involves using more functions like [http://php.net/file_exists ''file_exists()''], [http://php.net/is_readable ''is_readable()''] and [http://php.net/is_writeable ''is_writeable()''].
 
{{Code:Basic
177 ⟶ 173行目:
|<source lang="php">
<?php
$handle = @ fopen('data.txt', 'r');
if(!$handle) {
echo 'PHP does not have permission to read this file or the file in question doesn\'t exist.';
} else {
in question doesn\'t exist.';
$string = fread($handle, 64);
} else {
$string = fread fclose($handle, 64);
}
fclose($handle);
 
}
$handle = @ fopen('data.txt', 'w'); // The same applies for 'a'
if(!$handle) {
$handle = @ fopen('data.txt', 'w'); // The same applies for 'a'
echo 'PHP either does not have permission to write to this file or
if(!$handle) {
echo 'PHP either does not have permission to write to this file or
it does not have permission to create this file in the current directory.';
} else {
fwrite($handle, 'I can has content?');
fclose($handle);
}
}
 
$handle = @ fopen('data.txt', 'x');
if(!$handle) {
echo 'Either this file exists or PHP does not have permission to
create this file in the current directory.';
} else {
fwrite($handle, 'I can has content?');
fclose($handle);
}
}
?>
</source>
|As you can see, the '@' operator is used mainly when working with the fopen() function. It can be used in other cases, but is generally less efficient.
}}
 
212 ⟶ 207行目:
|<source lang="php">
<?php
$file = 'data.txt';
 
if(!file_exists($file)) {
// No point in reading since there is no content
$contents = '';
// But might want to create the file instead
$handle = @ fopen($File, 'x'); // Still need to error-check ;)
if(!$handle) {
echo 'PHP does not have permission to create a file in the current directory.';
} else {
fwrite($handle, 'Default data');
fclose($handle);
}
}
} else {
// The file does exist so we can try to read its contents
if(is_readable($file)) {
$contents = file_get_contents($file);
} else {
echo 'PHP does not have permission to read that file.';
}
}
}
}
 
if(file_exists($file) && is_writeable($file)) {
$handle = fopen($file, 'w');
fwrite($handle, 'I can has content?');
fclose($handle);
}
}
?>
</source>
|}}
 
You can see by that last example that error-checking makes your code very robust. It allows it to be prepared for most situations and behave accordingly, which is an essential aspect of any program or script.
 
==Line-endings==
Line-endings were mentioned briefly in the final example in the 'Reading' section of this chapter and it is important to be aware of them when working with files. When reading from a text file it is important to know what types of line-endings that file contains. 'Line-endings' are special characters that try to tell a program to display a new line. For example, Notepad will only move a piece of text to a new line, if it finds "\r\n" just before the new line (it will also display new lines, if you put word wrap on).
 
If someone writes a text file on a Windows system, the chances are that each line will end with "\r\n". Similarly, if they write the file on a Classic Macintosh (Mac OS 9 and under) system, each line will probably end with "\r". Finally, if they write the file on a Unix-based system (Mac OS X and GNU/Linux), each line will probably end with "\n".
 
Why is this important? Well, when you read a file into a string with [http://php.net/file_get_contents ''file_get_contents()''], the string will be one long line with those line-endings all over the place. Sometimes they will get in the way of things you want to do with the string so you can remove them with:
<source lang="php"><?php
$string = str_replace(array("\n", "\r"), '', $string);
?></source>
 
Other times you may need to know what kind of line-ending is being used throughout the text in order to be consistent with any new text you add. Luckily, in 99% of cases, the line-endings will never change type throughout the text so the custom function 'detectLineEndings' can be used as a quick way of checking:
<source lang="php"><?php
function detectLineEndings($string) {
if(false !== strpos($string, "\r\n")) return "\r\n";
else elseifif(false !== strpos($string, "\r")) return "\r";
else return "\n";
}
}
?></source>
 
270 ⟶ 265行目:
So far, all of the text seen in this chapter has been assumed to be encoded in some form of plaintext encoding such as UTF-8 or ASCII. Files do not have to be in this format however and in fact there exist a huge number of formats that are aren't (such as pictures or executables). If you want to work with these files you have to ensure that the functions you are using are 'binary safe'. Previously you would have to add 'b' to the end of the modes you used to tell PHP to treat the file as a binary file. Failing to do so would give unexpected results and generally 'weird-looking' data.
 
Since about PHP 4.3, this is no longer necessary as PHP will automatically detect, if it needs to open the file as a text file or a binary file and so you can still follow most of the examples shown here.
 
Working with binary data is a lot different to working with plaintext strings and characters and involves many more functions whichthat are beyond the scope of this chapter however it is important you know about these differences.
 
==Serialization==
279 ⟶ 274行目:
There is a whole chapter devoted to [[Programming:PHP/Serialization|Serialization]] in this book as it is a useful technique to know how to use effectively. It is mentioned here as one of the primary uses of serialization is to store data on plain files when a database is not available. It is also used to store the state of a script and to cache data for quicker access later and files are one of the preferred media for this storage.
 
In PHP, serialization is very easy to perform through use of the [http://php.net/serialize ''serialize()''] and [http://php.net/unserialize ''unserialize()''] functions. Here follows an example of serialization used in conjunction with file functions.
 
{{Code:Output
285 ⟶ 280行目:
|<source lang="php">
<?php
/* This part of the script saves the data to a file */
$data = array(
'id' => 114,
'first name' => 'Foo',
'last name' => 'Bartholomew',
'age' => 21,
'country' => 'England'
);
$string = serialize($data);
 
$handle = fopen('data.dat', 'w');
fwrite($handle, $string);
fclose($handle);
 
/* Then, later on, we retrieve the data from the file and output it */
$string = file_get_contents('data.dat');
$data = unserialize($string);
 
$output = '';
foreach($data as $key => $datum) {
$field = ucwords($key);
$output .= "$field: $datum\n";
}
}
 
echo $output
?>
</source>
321 ⟶ 316行目:
 
==PHP 5==
There is one particular function specific to files that was introduced in PHP 5. That was the [http://php.net/file_put_contents ''file_put_contents()''] function. It offers an alternative method of writing to files that does not exist in PHP 4. To see how it differs, it is easiest to just look at an example.
 
{{Code:Basic
327 ⟶ 322行目:
|<source lang="php">
<?php
$file = 'data.txt';
$content = 'New content.';
 
// PHP 4, overwrite entire file with data
$handle = fopen($file, 'w');
fwrite($handle, $content);
fclose($handle);
 
// PHP 5
file_put_contents($file, $content);
 
// PHP 4, append to a file
$handle = fopen($file, 'a');
fwrite($handle, $content);
fclose($handle);
 
// PHP 5
file_put_contents($file, $content, FILE_APPEND);
?>
</source>
|File_put_contents() will also attempt to create the file, if it doesn't exist and it is binary safe. There is no equivalent of the 'x' mode for file_get_contents().
}}
 
353 ⟶ 348行目:
<source lang="php">
<?php
if(!function_exists('file_put_contents')) {
function file_put_contents($file, $data, $append = false) {
if(!$append) $mode = 'w';
else $mode = 'a';
$handle = @ fopen($file, $mode);
if(!$handle) return false;
$bytes = fwrite($handle, $data);
fclose($handle);
return $bytes;
}
}
}
}
?>
</source>
 
{{Programming/Navigation|next=Mailing|previous=Functions}}
|lang=PHP
|next=Mailing
|previous=Functions
}}
{{BookCat}}