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

ナビゲーションに移動 検索に移動
日本語に翻訳
M (en:PHP_Programming/Filesからインポート済みの25版: Wikibooks:インポート依頼による)
(日本語に翻訳)
 
<noinclude>{{Programming/Navigation}}</noinclude>
ファイルの処理はどんなプログラミング言語にとっても重要なことであり、PHPも例外ではない。ファイルを使う理由が何であれ、PHPはいくつかの関数でそれを可能にしている。なお、このページでは[[PHP/入門]]の読了を前提としている。
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.
 
== Foldersディレクトリ ==
現在のディレクトリを表示する: dirname().
To display the current directory: dirname().
 
ディレクトリを変更する: chdir().
To change the directory: chdir().
 
ディレクトリを作成する: mkdir().
To make a new directory: mkdir().
 
== ''fopen()'' and ''fclose()'' ==
''fopen()''はファイル処理の基本である。この関数はファイルを(指定されたモードで)開き、ファイルハンドル(ポインタ)を返す。このハンドルを使うことで、ファイルを読み込んだり、書き込んだりすることができ、それが終わると''fclose()''関数でファイルを閉じる。
''fopen()'' is the basis for file manipulation. It opens a file in a certain mode (that you specify) and returns a handle. Using this handle you can read or write to the file, before closing it with the ''fclose()'' function.
 
{{Code:Basic|例
|Example Usage
|<source lang="php">
<?php
$handle = fopen('data.txt', 'r'); // Open the file for readingファイルを読み込むために開く
fclose($handle); // Close the fileファイルを閉じる
?>
</source>
|}}
 
上記の例では'r'モードを指定して、「読み込む」ために開くことを示している。''fopen()''で使えるモードの一覧は[http://php.net/fopen PHPのマニュアル]を参照の事。
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()''].関数を知る必要がある。
 
PHPスクリプトの実行が終了すると、開かれたファイルは全て自動的に閉じられる。そのため、厳密にはファイルを開いた後にそれを閉じる必要はないが、ファイルをきちんと閉じることはプログラミングにおける良い慣習とされている。
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.関数を使うことができる。
 
これらの関数は一般的にはお互いの間で互換性がある。''file_get_contents()''と''file()''ではファイルを予め''fopen()''で開いておく必要も読み込んだ後に''fclose()''で閉じる必要もなく、ファイルを一度だけ使う場合などで役に立つ。より多くの作業を必要としている場合、''fopen()''、''fread()''、''fwrite()''、''fclose()''を使うほうが良い。
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
|An example of using file_get_contents()を使った例
|<source lang="php">
<?php
?>
</source>
|<pre>I am the contents of これはdata.txtの内容です</pre>
|この関数はファイルの内容全てを文字列に読み込む。その後、ほかの文字列と同じように処理することができる。}}
|This function reads the entire file into a string and from then on you can manipulate it as you would any string.}}
 
{{Code:Output
|file()を使った例
|An example of using file()
|<source lang="php">
<?php
?>
</source>
|<pre>Line 1: I am the first line of fileファイルの1行目
Line 2: ファイルの2行目
Line 2: I am the second line the of the file
Line 3: ファイルの4行目だと言ったら嘘になる</pre>
Line 3: If I said I was the fourth line of the file, I'd be lying</pre>
|この関数はファイルの内容全てを配列に読み込む。配列の値はそれぞれファイルの1行となる。}}
|This function reads the entire file into an array. Each item in the array corresponds to a line in the file.}}
 
{{Code:Output
|fread()を使った例
|An example of using fread()
|<source lang="php">
<?php
</source>
|<pre>I am the first 64 bytes of data.txt (if it was ASCII encoded). I</pre>
|この関数は指定されたバイト数をファイルから読み込み、それを文字列として返す。多くの場合、file_get_contents()とfile()のほうが良いが、この関数が必要な場合もある。}}
|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.}}
 
このように、上記の3関数を使うことでファイルを簡単に読み込み、処理に適するデータ型に変換することができる。下記の例は上記の関数の互換性を示すが、興味がない場合はスキップして次の節に移ることもできる。
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 writing section, if you are not interested.
 
{{Code:Basic|
}
 
/* This is equivalent to file_get_contents($file), but is less efficientと同等だが、より遅い */
$handle = fopen($file, 'r');
$contents = fread($handle, filesize($file));
fclose($handle);
 
/* file($file)と同等だが、改行記号に留意する必要がある。
/* 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 エンコードがASCIIの場合、fread($file, 64), if the file is ASCII encodedと同じ */
$contents = file_get_contents($file);
$string = substr($contents, 0, 64);
|}}
 
== ファイルに書き込む ==
==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()''] that 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.の節でのみ説明される。
 
ファイルへの書き込みに使われるオプションは使える関数のバラエティではなく、ファイルを開くときに使えるモードにある。ファイルのモードは[http://php.net/fopen ''fopen()'']で指定することができ、うちファイルへの書き込みを許可するモードは3つある。'w'モードではファイルの内容を削除するため、書き込んだ内容がそのままファイルに記載される内容となる。'a'モードでは元からファイルにある内容を残し、書き込んだ内容は元からある内容の後に記載される。'x'モードはファイルが開かれる時点でまだ存在しない場合のみ成功する。これらのモードはファイルが存在しない場合、その作成を試みるが、'r'モードではファイルの作成は行われない。
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
|'w'モードを使った例
|An example of using the 'w' mode
|<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);
 
{{Code:Output
|'a'モードを使った例
|An example of using the 'a' mode
|<source lang="php">
<?php
$handle = fopen('data.txt', 'a'); // Open the file for appendingファイルを追加書き込みモードで開く
$data = "\n\nI am new content.n新しい内容";
fwrite($handle, $data);
fclose($handle);
?>
</source>
|<pre>元々の内容
|<pre>I am the original content.
 
I am new content.新しい内容</pre>
|}}
 
{{Code:Output
|'x'モードを使った例
|An example of using the 'x' mode
|<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);
?>
</source>
|<pre>I am this file's first ever content!はじめての内容です</pre>
|}}
 
上記の例で示されたモードのうち、'w'と'a'が最もよく使われるが、書き込みの手順はほぼ同じである。
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==
[http://php.net/fopen ''fopen()'']でファイルを開いて読み込むことと書き込むことの両方を行いたい場合、モードの後ろに'+'を追記するだけでよい。例えば、ファイルの読み込みには'r'モードを使うが、書き込むことも必要な場合は'r+'モードを使う。同じように'w+'モードでも読み書きができるが、ファイルに元からある内容は削除される。詳しい説明は[http://php.net/fopen ''fopen()'']を参照のこと。
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. However, this will also truncate the file to zero length. For a better description visit the [http://php.net/fopen ''fopen()''] page that has a very useful table describing all the modes available.
 
== エラー検出 ==
==Error Checking==
エラー検出はどんなプログラミングにとっても大事なことであるが、PHPでファイルを処理するときは特に大事である。エラー検出が必要な理由は主にファイルシステムに由来する。現在使われているウェブサーバーはUnixベースのものが大半なので、PHPでウェブアプリケーションを開発している場合、ファイルパーミッションにも留意しなければならない。PHPにファイルを読み込む権限がない場合、エラーになってしまう。また、(当然のことだが)ファイルが存在するかどうかも重要である。例えば、ファイルの読み込みを試みるとき、まずファイルが存在することを確かめる必要がある。一方、'x'モードでファイルを作成して書き込む場合ではファイルが存在''しない''ことを確かめる必要がある。
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.
 
かいつまんで言うと、コードを書いてファイルを処理する場合、常に最悪な場合を予想すべきである。例えば、ファイルが存在しない場合や読み書きのパーミッションがない場合を想定すべきである。大半の場合ではユーザーにファイルのパーミッションを変更して、PHPスクリプトが処理を行えるようにするよう求めるが、一部の場合では代替となる処理に変更することもできる。
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 from/write to it. In most cases this means you have to tell the users that, in order for the script to work, they need to adjust those file permissions so that PHP can create files and read from/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 エラー処理は主に2つの方法で行われる。1つは'[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 であるかを検査する方法である。もう1つは[http://php.net/file_exists ''file_exists()''], [http://php.net/is_readable ''is_readable()''] and [http://php.net/is_writeableis_writable ''is_writeableis_writable()''].などの関数を使う方法である。
 
{{Code:Basic
|'@'演算子を使った例
|Examples of using the '@' operator
|<source lang="php">
<?php
$handle = @ fopen('data.txt', 'r');
if(!$handle) {
echo 'PHPにファイル読み込みのパーミッションがないか、ファイルが存在しない。';
echo 'PHP does not have permission to read this file or the file in question doesn\'t exist.';
} else {
$string = fread($handle, 64);
}
 
$handle = @ fopen('data.txt', 'w'); // The same applies for 'a'モードでも同じ
if(!$handle) {
echo 'PHPにファイルへの書き込みパーミッションがないか、現在のディレクトリにファイルを作成するパーミッションがない。';
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 'ファイルがすでに存在するか、PHPに現在のディレクトリにファイルを作成するパーミッションがない。';
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>
|上記で示されているように、'@'演算子は主に''fopen()''関数とともに使われる。ほかの場合でも使えるが、より遅いことが多い。
|As you can see, the '@' operator is used mainly when working with the ''fopen()'' function. It can also be used in other cases, but is generally less efficient.
}}
 
{{Code:Basic
|検査用関数を使った例
|Examples of using specific checking functions
|<source lang="php">
<?php
 
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に現在のディレクトリにファイルを作成するパーミッションがない。';
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にファイル読み込みのパーミッションがない。';
echo 'PHP does not have permission to read that file.';
}
}
 
if(file_exists($file) && is_writeableis_writable($file)) {
$handle = fopen($file, 'w');
fwrite($handle, 'I can has content?書き込みテスト');
fclose($handle);
}
|}}
 
最後の例にみられるように、エラー検出を行うことで、プログラムが強固になる。このプログラムは大半の場合によって柔軟に対応を変えることができる。
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 改行記号 ==
改行記号は[[#ファイルを読み込む|ファイルを読み込む]]節でも軽く触れられたが、ファイル処理ではそれに留意することが大事である。改行記号とはプログラムに改行を行うよう指示する特別な記号である。例えば、Windowsの[[w:メモ帳|メモ帳]]アプリでは改行の直前に\r\nの記号がある場合のみ、次の行に移動する(右端を折り返す設定でも改行が行われる)。
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).
 
Windowsでテキストファイルを作成する場合、改行記号に\r\nが使われると予想される。同じように、より古いMacintosh(Mac OS 9以下)で作成した場合は改行記号が\rになり、UnixベースのMac OS XやGNU/Linuxでは\nになる。
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".
 
改行記号が重要である理由はなんでしょうか。例えば、[http://php.net/file_get_contents ''file_get_contents()'']でファイルの内容を文字列に読み込む場合、改行記号もそのまま読み込まれる。それが処理を阻害する場合もあるので、下記のように改行記号を除去することができる。
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>
 
また、ファイルに内容を追加するとき、改行記号を元からある内容と合わせたい場合がほとんどなので、下記のdetectLineEndings()関数で改行記号を調べることができる。
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) {
?></source>
 
しかし、大半の場合では改行記号がファイル内に存在して、PHPスクリプトもそれに合わせる必要があると頭の片隅に留める程度で十分である。
Most of the time though, it is just sufficient to be aware of their existence within the text so you can adjust your script to cope properly.
 
==Binary-safe==
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 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.
これまで使われたテキストはASCIIやUTF-8のようなプレーンテキスト形式でエンコードされている。しかし、画像や実行ファイルなどプレーンテキスト形式以外のファイルも多い。このようなファイルを処理する場合、ファイル関数が「バイナリ安全」(binary-safe)でなければならない。以前のPHPではモードに'b'を追記してファイルをバイナリファイルであると明示する必要があり、それがなされていない場合は予想外の結果となる。しかし、およそPHP 4.3以降、PHPはファイルがテキストファイルかバイナリファイルかを検出することができ、モードで明示する必要がなくなった。
 
バイナリデータの処理はプレーンテキスト処理と大きく違い、このページではカバーできないが、このような差が存在することを知るのは大事である。
Working with binary data is a lot different to working with plaintext strings and characters and involves many more functions that are beyond the scope of this chapter. However, it is important you know about these differences.
 
== シリアライズ ==
==Serialization==
シリアライズはデータを特定のフォーマットに変換して、後で元に戻せるようにするテクニックである。例えば、配列を文字列に変換してそれを保存することで、そのデータは後に配列に変換して再び使用することができる。
Serialization is a technique used by programmers to preserve their working data in a format that can later be restored to its previous form. In simple cases this means converting a normal variable such as an array into a string and then storing it somewhere. That data can then be unserialized and the programmer will be able to work with the array once again.
 
[[Programming:PHP/シリアライズ|シリアライズ]]は便利なテクニックであり、それ自体が一章に値するほどの内容であるが、データベースが使えないときはファイルに保存することが多いので、ここでも言及している。また、スクリプトの状態を保存したり、データをキャッシュしてより素早くアクセスできたりすることにも使われており、これらの目的にはファイルの方が適任である。
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 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
|ユーザーデータをファイルに保存して、後で取り出す例。
|An example of storing user details in a file so that they can be easily retrieved later.
|<source lang="php">
<?php
/* このスクリプトではデータをファイルに保存している */
/* This part of the script saves the data to a file */
$data = array(
'id' => 114,
fclose($handle);
 
/* その後、データをファイルから取り出してそれを出力する */
/* Then, later on, we retrieve the data from the file and output it */
$string = file_get_contents('data.dat');
$data = unserialize($string);
|}}
 
== PHP 5 ==
PHP 5ではファイル関連の関数が1つ導入されている。それは[http://php.net/file_put_contents ''file_put_contents()'']のことであり、ファイル書き込みの新しい方法である。
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
|Examples showing writing to a file in PHP 4 and the equivalent in でファイルに書き込む例、及びPHP 5 with the file_put_contents() function関数を使った例
|<source lang="php">
<?php
$content = 'New content.';
 
// PHP 4、ファイルの内容を削除した後に書き込む
// PHP 4, overwrite entire file with data
$handle = fopen($file, 'w');
fwrite($handle, $content);
file_put_contents($file, $content);
 
// PHP 4, append to a file、ファイルに追記する
$handle = fopen($file, 'a');
fwrite($handle, $content);
?>
</source>
|''file_put_contents()''はファイルが存在しない場合に作製を試み、またバイナリ安全でもある。なお、'x'モードと同等の機能は提供されていない。
|''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()''.
}}
 
ファイルを繰り返し操作する場合を除き、''file_put_contents()''のほうが''fopen()''より優先すべきである。下記はPHP 4で''file_put_contents()''の挙動を再現する方法である。
''file_put_contents()'' is almost always preferable over the ''fopen()'' method except when performing multiple operations on the same file. It is more preferable to use it for writing than ''file_get_contents()'' is for reading and for this reason, a function is provided here to emulate the behaviour of ''file_put_contents()'' for PHP 4:
<source lang="php">
<?php
 
{{Programming/Navigation}}
[[Category:PHP|ふあいる]]
177

回編集

案内メニュー