phpのファイルシステム関数の基本。アクセス情報の書き込みと読み込みを関数を用いて行う

#近況報告

エンジニア転職成功しました。YouTubeでエンジニア転職したい方向けに情報発信しています。

https://www.youtube.com/channel/UCcXQG8lu_EdyP2Cbhtz1bcA



#今回紹介する内容
- phpでファイルシステム上のアクセス情報をテキストファイルへ書き込み、書き込んだ情報を別のファイルで表形式で読み込む方法を解説します。
- 目的は独習php5章のファイルシステム関数の内容を理解し、アプリケーション開発に役立てることです

##ファイルシステム関数とは？
- ディレクトリやファイルを操作するための関数

##今回紹介する関数一覧

###テキストファイルへの書き込み関数
- fopen関数
- flock関数
- fwrite関数
- fclose関数

###テキストファイルの読み込み関数
- fgetcsv関数
- fgets関数
- file関数

##ファイル書き込みの順序

1. ファイルを開く　→　fopen関数など
2. ファイルをロックする
3. ファイルに対して書き込みを行う
4. ファイルを閉じる（ロックを解除する）

### ファイルオープン - fopen関数

- fopen関数の構文表記

```php
resource fopen(string $file, string $mode [, bool $include = false])
```

- $file ファイルのパス
- $mode オープンモード
- $include include_pathパラメータ（5.5.8項）を利用するか


#### 主なオープンモード

| モード | 概要 |
|:-----------|:-----------|
| r | 読み込み専用 |
| r+ | 読み込み/書き込み可能 |
| w | 書き込み専用（ファイルの内容をクリア、存在しない場合には新規作成）|
| w+ | 読み込み/書き込み可能（ファイルの内容をクリア、存在しない場合には新規作成）|
| a | 書き込み専用（既存の内容に追記。ファイルが存在しない場合は新規作成）|
| a+ | 読み込み/書き込み可能（既存の内容に追記。ファイルが存在しない場合は新規作成）|
| x | 書き込み専用（ファイルが存在する場合はエラー）|
| x+ | 読み込み専用（ファイが存在する場合はエラー））|
| c | 書き込み専用（存在しない場合は新規作成。存在する場合もクリアしない）|
| c+ | 書き込み/読み込み可能（存在しない場合は新規作成。存在する場合もクリアしない）|

#### クローズモード

- fclose関数の構文表記

```php
bool fclose(resource $handle)
```

- $handle ファイルハンドル

#### fopen関数でのエラー処理 --- エラー制御演算子

- fopen関数利用時、エラー時（例外処理）の時の処理を加える場合、以下のように指定する
- fopenの前に@を加えると、警告メッセージを無くす
- or die ~で、die関数を用いて終了時に表示するメッセージを引数に加える
- or 演算子では、左辺がtrueの場合、右側は無視される（ショートカット 演算の性質）
- 「@演算子 + or die」の記述は、ファイルオープンのところではよく見かける記述である

```php
$file = @fopen('ファイルのパス', 'ab') or die('エラー時のメッセージ');
```

### ファイルへの書き込み - fwrite関数

- fwrite関数の構文表記

```php
int fwrite(resource $handle, string $str [, int $len])
```

- $handle 書き込み対象のファイルハンドル
- $str 書き込む文字列
- $len 書き込む文字列のながさ（バイト単位）

### ファイルのロック - flock関数

- flock関数の構文表記

```php
bool flock(resource $handle, int $ope)
```

- $handle ファイルハンドル
- $ope ロックモード

- オープン、書き込み、クローズ のみだけでファイルへの書き込みはできるが、ファイル書き込み中に他のユーザーがファイルを書き込んだりして矛盾が発生しないように、書き込み前にロックを掛ける必要がある。そのための関数がflock関数

#### ロックモード一覧

| 設定値 | 概要 |
|:--------|:------------|
|LOCK_SH|共有ロック（読み込み中なので、他者による書き込みを禁止とする）|
|LOCK_EX|排他ロック（書き込み中なので、他者による書き込みを禁止とする）|
|LOCK_UN|ロックの解除|
|LOCK_NB|非ブロックモード|

- LOCK_NBは|（論理和演算子）を用いて、LOCK_SHやLOCK_EX等と組み合わせて使う。
- LOCK_NBは他のユーザーが指定ファイルをブロックしていた場合（ロック中の時）、即座にロックをキャンセルする(通常はロックがキャンセルされるまで待つ)

##ファイル読み込み関数

### fgetcsv関数

- fgetcsv関数の構文表記

```php
array fgetcsv(resource $handle [, int $len [, string $delimiter] [, string $enclosure [, string $escape]]])
```

- $handle ファイルハンドル
- $len 読み込む最大長（バイト単位）
- $delimiter 区切り文字（デフォルトはカンマ）
- $enclosure フィールドの囲み文字（デフォルトはダブルクォート）
- $escape エスケープ文字（デフォルトはバックスラッシュ）


- 特定の区切り文字を持ったテキストに汎用的に対応する関数
- ファイルポインタを1行ずつ後ろにずらしながら、現在行のテキストを読み込み、指定された区切り文字で分割した値を配列として返す関数
- ファイルポインタは、ファイルを開いた初期状態では先頭に位置している
- 読み込むべき次の行（ファイルポインタが指し示す位置）が存在しない場合にfalseを返す

### fgets関数

- fgets関数の構文表記

```php
string fgets(resource $handle [, int $len])
```
- $handle ファイルハンドル
- $len 読み込む最大長（バイト単位）


- 指定されたファイルから1行分のデータを読み込む
- fgets関数を使用した場合、読み込んだ行データをexplode関数で分割処理する必要あり（特定の区切り文字を持たない場合はfgetsを使用した方が良い）

### file関数

- file関数の構文表記

```php
array file(string $filename [, int $flags])
```

- $filename 読み込むファイルのパス
- $flags 動作フラグ
- $flagsには、FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINESとすると、改行も空行も読み飛ばすので便利

- 指定されたファイルをまとめて読み込み、行単位に格納した配列を返す
- explode関数と組み合わせると良い


### 動作フラグ($flags)の設定値

| 設定値 | 概要 |
|:--------|:------------|
| FILE_USE_INCLUDE_PATH | include_pathパラメータ（5.5.8項）からファイル検索 |
| FILE_IGNORE_NEW_LINES | 配列の要素末尾に改行文字を追加しない |
| FILE_SKIP_EMPTY_LINES | 空行を読み飛ばす |


### file_get_contents関数

- ファイルの内容を、配列ではなく文字列をまとめて読み込む


```php
string file_get_contents(string $filename)
```

- $filename 読み込むファイルのパス

## ファイルシステム関数の設定パラメータ

- phpでは、ファイルシステム関数の挙動をphp.iniファイルで制御している
  - php.iniで設定可能ないくつかのパラメータが存在する
  - 設定によってファイルが正しく読み込めない原因を見つけられるように、最低限以下パラメータは理解しておきたい

### allow_url_fopenパラメータ

- fopen関数にて、読み込めるデータはサーバ上のデータだけでなく、ネットワーク上のファイルを読み込むこともできるが、その場合はphp.iniファイルのallow_url_fopenのパラメータをOnにする必要がある

```ini:/Applications/XAMPP/etc/php.ini
 892 ; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
 893 ; http://php.net/allow-url-fopen
 894 allow_url_fopen=On     ;ここがOnになっていればOK
```

### open_basedirパラメータ

- 指定したパスのファルダにしかアクセスできなくなる

```ini:/Applications/XAMPP/etc/php.ini
 376 ; open_basedir, if set, limits all file operations to the defined directory
 377 ; and below.  This directive makes most sense if used in a per-directory
 378 ; or per-virtualhost web server configuration file. This directive is
 379 ; *NOT* affected by whether Safe Mode is turned On or Off.
 380 ; http://php.net/open-basedir
 381 ;open_basedir =        ; ここでフォルダパスを指定する　例：open_baedir = "c:/data/;c:/User/Yamada/Document"
```

### include_pathパラメータ

- 指定した読み込みファイルの絶対パスを、複数に渡って指定することができる
- UNIX(MacOS系)では、複数パスのデリミタには「:」を、Windows系では「;」で区切る
- 読み込みの優先度は左から順番
- fopen関数でinclude_pathパラメータを有効化するには、第三引数にtrueを指定する
- file関数では相対パスで読み込み先を指定しなくてはならない（include_pathが適用されない）


```ini:/Applications/XAMPP/etc/php.ini
 786 ;;;;;;;;;;;;;;;;;;;;;;;;;
 787 ; Paths and Directories ;
 788 ;;;;;;;;;;;;;;;;;;;;;;;;;
 789
 790 ; UNIX: "/path1:/path2"
 791 include_path = ".:/Applications/XAMPP/xamppfiles/htdocs/selfphp"       ; ⇦MacOSの場合はここを「:」で区切って絶対パスを指定する
 792 ;
 793 ; Windows: "\path1;\path2"
 794 ;include_path = ".;c:\php\includes"                                    ; ⇦Windowsの場合はここを「;」で区切って絶対パスを指定する
 795 ;
 796 ; PHP's default setting for include_path is ".;/path/to/php/pear"
 797 ; http://php.net/include-path
```

```php:fopen関数にinclude_pathパラメータを適用する場合
fopen('test.log', 'ab', true) // ⇦第三引数にtrueを指定して、include_pathパラメータを有効化する
```