PHP入門（PHPの基本的な組み込み関数）

# なにこれ？
- [PHP+MySQLマスターブック](http://www.amazon.co.jp/o/ASIN/4839947597/)の学習記録です。

# 目次
1. PHPの基礎
2. **PHPの基本的な組み込み関数**
3. WebでのPHP
4. クラスとオブジェクト
5. データベースの準備
6. データ操作の基本
7. PHPからデータベースを操作する
8. データベースの運用
9. PHPの応用

# 前提条件
* PHP version 5.4


# 文字列の操作
## 入力データの処理
### **strlen / mb_strlen**
* 文字列バイト数を得る

```php:書式
$変数 = strlen(文字列);
```

```php:mb_strlen.php
$str = "Hello!";
$length = strlen($str);
$mb_length = mb_strlen($str);
echo $length . "\n";
echo $mb_length . "\n";

// 日本語として何文字かカウントしたい場合はmb_strlen関数を使用する。
```

```php:結果
18
6
```


### **substr**
* 文字列を分割する

```php:書式
$変数 = substr(文字列, 文字列の位置, 文字列の長さ);
```

```php:substr.php
// 文字列の位置は先頭の文字が「0」番目
$string = "ACDEFGHIJKLMN";
$result = substr($string, 3, 5);
echo $result;
```

```php:結果
DEFGH
```

### **str_replace**
* 文字列を置換する

```php:書式
$変数 = str_replace(置換対象文字, 置換文字, 文字列);
```

```php:str_replace.php
$html = '<font size="3">Hello!</font><br>';
$search = 'size=3';
$replace = 'size=5';
$result = str_replace($search, $replace, $html);
echo $result;
```

```html:結果
<font size="5">Hello!</font><br>
```

### **trim**
* スペースを除去する

```php:書式
$変数 = trim(文字列);
```

```php:trim.php
$string = " 1234567890 ";
$result = trim($string);
echo $result;
```

```php:結果
1234567890
```

## HTMLの表示
### **htmlspecialchars**
* HTMLタグを無効にする

```php:書式
$変数 = htmlspecialchars(文字列, オプション);
```

```php:htmlspecialchars.php
// CSRF対策
$string = '<a href="http://google.com">Google</a>';
$result = htmlspecialchars($string, ENT_QUOTES);
echo $result;
```

```php:結果
<a href="http://google.com">Google</a>
```

|オプション|説明|
|:---|:---|
|ENT_COMPAT|「"」のみを変換（デフォルトオプション）|
|ENT_QUOTES|「"」、「'」どちらも変換|
|ENT_NOQUOTES|どちらも変換しない|

### **strip_tags**
* HTMLタグを取り除く

```php:書式
$変数 = strip_tags(文字列, 許可するタグ);
```

```php:strip_tags.php
$string = `<a href="http://google.com">Google</a>`;
$result = strip_tags($string);
echo $result;
```

```php:結果
Google
```

### **nl2br**
* 改行コードの前に改行タグを付ける

```php:書式
$変数 = nl2br(文字列);
```

```php:nl2br.php
$string = "PHPの関数は
　　　　　　とても便利
　　　　　　ですね。";
$result = nl2br($string);
echo $result;
```

```html:結果
PHPの関数は<br/>
とても便利<br/>
ですね。
```

## 配列を使った文字列処理
### **implode**
* 配列から文字列を作成する

```php:書式
$変数 = implode(区切り文字, 配列);
```

```php:implode.php
$data = array("A", "B", "C", "D");
$result = implode(',', $data);
echo $result;
```

```php:結果
A,B,C,D
```

### **explode**
* 文字列から配列を作成する

```php:書式
$変数 = explode(区切り文字, 文字列);
```

```php:explode.php
$string = "A, B, C, D";
$array = explode(',', $string);
print_r($array);
```

```php:結果
Array
(
    [0] => A
    [1] => B
    [2] => C
    [3] => D
)
```

## データベースへ渡す文字列の加工
### **addslashes**
* エラーになる文字をエスケープする

>
WEBアプリでは検索キーに送信フォームから送られてきたデータを使いデータベースを検索する事があるが、このデータの中に、SQL言語から見て意味のある文字が含まれてしまうとエラーとなり、処理が止まってしまう。
`addslashes`関数を使うとエラーになる文字列があった場合にエスケープしてSQLとしては機能しないようにする。

```php:書式
$変数 = addslashes(文字列);
```

```php:addslashes.php
$string = "A", "B", "C", "D";
$result = addslashes($string);
print $result;
```

```php:結果
\"A\", \"B\", \"C\", \"D\"
```

# 配列の操作
## 配列データを変数に格納
### **list**
* 配列のデータをすべて変数に格納する

```php:書式
list($変数1, $変数2, $変数3) = $配列;
```

```php:list.php
$data = array("A", "B", "C");
list($a0, $b1, $c2) = $data;
```

```php:結果
// このような状態となる
$a0 = $data[0];
$b1 = $data[1];
$c2 = $data[2];
```

## 配列内のデータの並び替え
### **フラグを指定してソートする場合のフラグ一覧**

|フラグ|意味|
|:--|:--|
|SORT_REGULAR|通常通りにデータを比較|
|SORT_NUMERIC|数値としてデータを比較|
|SORT_STRING|文字列としてデータを比較|
|SORT_LOCALE_STRING|現在のロケールに基いてデータを比較|
|SORT_NATURAL|データを自然順で比較|
|SORT_FLAG_CASE|SORT_STRINGやSORT_NATURALと組み合わせて比較|


### **sort**
* 昇順にソートする

```php:書式
sort($配列, フラグ);
```

```php:sort.php
$numbers = array(18,7,20,5);
sort($numbers);
print_r($numbers);
```

```php:結果
Array
(
    [0] => 5
    [1] => 7
    [2] => 18
    [3] => 20
)
```

### **rsort**
* 降順にソートする

```php:書式
rsort($配列, フラグ);
```

```php:sort.php
$numbers = array(18,7,20,5);
rsort($numbers);
print_r($numbers);
```

```php:結果
Array
(
    [0] => 20
    [1] => 18
    [2] => 7
    [3] => 5
)
```

## 連想配列内のデータの並び替え
### **asort**
* データを昇順にソートする

```php:書式
asort($配列, フラグ);
```

```php:asort.php
$sales = array("TV2" => "1000", "TV1" => "500", "RADIO1" => "800");
asort($sales);
print_r($sales);
```

```php:結果
Array
(
    [TV1] => 500
    [RADIO1] => 800
    [V2] => 1000
)
```

### **arsort**
* データを降順にソートする

```php:書式
arsort($配列, フラグ);
```

```php:arsort.php
$sales = array("TV2" => "1000", "TV1" => "500", "RADIO1" => "800");
arsort($sales);
print_r($sales);
```

```php:結果
Array
(
    [V2] => 1000
    [RADIO1] => 800
    [TV1] => 500
)
```

### **ksort**
* キーを昇順にソートする

```php:書式
ksort($配列, フラグ);
```

```php:ksort.php
$sales = array("TV2" => "1000", "TV1" => "500", "RADIO1" => "800");
ksort($sales);
print_r($sales);
```

```php:結果
Array
(
    [RADIO1] => 800
    [TV1] => 500
    [V2] => 1000
)
```

### **krsort**
* キーを降順にソートする

```php:書式
krsort($配列, フラグ);
```

```php:krsort.php
$sales = array("TV2" => "1000", "TV1" => "500", "RADIO1" => "800");
krsort($sales);
print_r($sales);
```

```php:結果
Array
(
    [V2] => 1000
    [TV1] => 500
    [RADIO1] => 800
)
```

## 配列末尾データの追加削除
### **array_push**
* 末尾にデータを追加する

```php:書式
array_push($配列, "追加文字列");
array_push($配列, $追加変数);
```

```php:array_push.php
$data = array("A", "B", "C");
array_push($data, "D", "E");
print_r($data);
```

```php:結果
Array
(
    [0] => A
    [1] => B
    [2] => C
    [3] => D
    [4] => E
)
```

### **array_pop**
* 末尾のデータを削除する

```php:書式
$変数 = array_pop(配列);
```

```php:array_pop.php
$data = array("A", "B", "C");
$c = array_pop($data);
print_r($data);
print $c;
```

```php:結果
Array
(
    [0] => A
    [1] => B
)
C
```

## 配列先頭データの追加削除
### **array_unshift**
* 先頭のデータを追加する

```php:書式
array_unshift($配列, "追加文字列");
array_unshift($配列, $追加変数);
```

```php:array_unshift.php
$data = array("A", "B", "C");
array_unshift($data, "X", "Y");
print_r($data);
```

```php:結果
Array
(
    [0] => X
    [1] => Y
    [2] => A
    [3] => B
    [4] => C
)
```

### **array_shift**
* 先頭のデータを削除する

```php:書式
$変数 = array_shift(配列);
```

```php:array_shift.php
$data = array("A", "B", "C");
$a = array_shift($data);
print_r($data);
print $a;
```

```php:結果
Array
(
    [0] => B
    [1] => C
)
A
```

## 配列の結合と切り出し
### **array_merge**
* 配列をマージする

>
配列演算子「+」を使っても配列同士を結合することは可能だが、動作に違いがある。
`array_merge`関数はインデックスが0番から付け直されるが、
「+」演算子はそのままインデックスが保持される。
また、結合するとき同じキーまたはインデックスがある場合、`array_merge`関数では
後から指定した配列に上書きするが、演算子による結合では上書きされない。

```php:書式
$配列 = array_merge($元の配列,$追加配列);
```

```php:array_merge.php
$data = array("TV1" => "500", "TV2" => "1000", "RADIO1" => "800");
$add_data = array("TV1" => "2000", "RADIO2" => "600");
$result = array_merge($data, $add_data);
print_r($result);
```

```php:結果
Array
(
    [TV1] => 2000
    [TV2] => 1000
    [RADIO1] => 800
    [RADIO2] => 600
)
```

**array_slice**
* 配列を切り出す

```php:書式
$配列 = array_slice($元の配列, 開始位置, 長さ);
```

```php:array_slice.php
$data = array("A", "B", "C", "D", "E");
print implode(',', $data) . "\n";
// A,B,C,Dを取り出す
$result = array_slice($data, 0, 4);
print implode(',', $result) . "\n";
// Cを取り出す
$result = array_slice($result, -3, 1);
print implode(',', $result) . "\n";
// Dを取り出す
$result = array_slice($data, 3, -1);
print implode(',', $result) . "\n";
//C,D,Eを取り出す
$result = array_slice($data, 2);
print implode(',', $result) . "\n";
```

```php:結果
A,B,C,D,E
A,B,C,D
C
D
C,D,E
```

## その他の関数
### **array_reverse**
* データを反転する

```php:書式
$配列 = array_reverse($元の配列);
```

```php:array_reverse.php
$data = array("A", "B", "C", "D", "E");
$result = array_reverse($data);
print_r($result);
```

```php:結果
Array
(
    [0] => E
    [1] => D
    [2] => C
    [3] => B
    [4] => A
)
```

# 日付・時刻
## 現在の日時の取得
### **time**
* UNIXのタイムスタンプを表示する

```php:書式
$変数 = time();
```

```php:time.php
$now = time();
print $now;
```

```php:結果
1447958527
```

### **mktime**
* 日付をUNIXのタイムスタンプとして取得する

```php:書式
$変数 = mktime(時間, 分, 秒, 月, 年,);
```

```php:mktime.php
$timestamp = mktime(0, 0, 0, 20, 11, 2015);
print $timestamp;
```

```php:結果

```

### **date**
* UNIXタイムスタンプを日付にする

```php:書式
$変数 = date(フォーマット, UNIXタイムスタンプ);
```

```php:date.php
$timestamp = time() + (60 * 60 * 24) * 7;
$next_week = date('Y年m月d日H時i分s秒', $timestamp);
print $next_week;
```

```php:結果
2015年11月20日 4時09分17秒
```

* フォーマット用記号

|記号|内容|
|:--|:--|
|Y|数字4桁の年|
|m|数字2桁の月、先頭にゼロを付ける|
|d|数字2桁の日、先頭にゼロを付ける|
|H|数字2桁の時、24時間単位|
|i|数字2桁の分、先頭にゼロを付ける|
|s|数字2桁の秒、先頭にゼロを付ける|

## 日付のチェック
### **checkdate**
* 日付の妥当性をチェックする

>
正しい日付の場合は`TRUE`を、正しくない日付の場合は`FALSE`を返す

```php:書式
$変数 = checkdate(月, 日, 年);
```

```php:checkdate.php
$month = 11;
$day = 20;
$year = 2015;

if(!checkdate($month, $date, $year)){
  print "正しい日付を入力して下さい"
}
```

# ファイルの操作
## ファイルの読み書き
### **file_get_contents**
* ファイルを読み込む

>
**`file`関数**
読み込んだファイルの内容を1行毎に「配列」に取得したいときは`file`関数を使う
使い方は`file_get_contents`関数と同じ

```php:書式
$変数 = file_get_contents("ファイル名またはURL");
```

```php:file_get_contents.php
$filename = "test.txt";
if(is_readable($filename)){
  $contents = file_get_contents($filename);
  print $contents;
} else {
  print $filename . "は読み込めません。";
}
```

### **file_put_contents**
* ファイルにデータを書き込む

>
ファイルが無い時は作成され、ある時は上書きされる

```php:書式
file_put_contents("ファイル名", $変数);
```

```php:file_put_contents.php
$filename = "test.txt";
$contents = "abcdefghijklmn";
file_put_contents($filename, $contents);
```

### **mb_convert_encoding**
- 文字コードを変換する

```php:書式
$変数 = mb_convert_encoding($変数, "変更する文字コード", "元の文字コード");
```

```php:mb_convert_encoding.php
$filename = "test.txt";
$contents = "あいうえおかきくけこ";
$contents = mb_convert_encoding($contents, "SJIS", "UTF-8");
file_put_contents($filename, $contents);
```

### **fopen / fread / fwrite / fclose**
- ファイルポインタを利用してテキストファイルをプログラムで読み込む

>
`file_get_contents`や`file_put_contents`と違う点はファイルポインタを利用する点と、
画像ファイルなどバイナリファイルが扱える点

```php:書式
$ファイルポインタ = fopen("ファイル名またはURL", "オプション");
fwrite($ファイルポインタ, "書き込みデータ");
fclose($ファイルポインタ);
```

|オプション|内容|
|:--|:--|
|r|読み込み専用|
|w|書き込み専用|
|a|追記専用|

## ファイルの操作
### **unlink**
- ファイルを削除する

```php:書式
$変数 = unlink("ファイル名");
```

```php:unlink.php
$filename = "test.txt";
// is_file関数でファイル存在確認
if(is_files($filename) && unlink($filename)){
  print $filename . "を削除しました。";
} else {
  print $filename . "は削除できませんでいした。";
}
```

### **copy**
- ファイルをコピーする

>
コピー先ファイルが既に存在する場合、上書きされるので注意

```php:書式
copy(コピー元ファイル名, コピー先ファイル名);
```

```php:copy.php
if(copy("test.txt", "test.bak")){
  print "コピーに成功しました。";
} else {
  print "コピーできませんでした。";
}
```

## ディレクトリの操作
### **mkdir**
- ディレクトリを作成する

>
モードはディレクトリの権限のこと
省略すると`0777`が設定される

```php:書式
$変数 = mkdir("パス名", モード);
```

```php:mkdir.php
$dirname = "temp";
// is_dir関数でディレクトリ存在確認
if(!is_dir($dirname) && mkdir($dirname)){
  print $dirname . "を作成しました。";
} else {
  print $dirname . "は作成できませんでした。";
}
```

### **rmdir**
- ディレクトリを削除する

```php:書式
rmdir(ディレクトリ名);
```

```php:rmdir.php
rmdir("temp");
```

# HTTPヘッダー
## HTTPヘッダーの操作
### **header**
- レスポンスヘッダ―を送信する

>
レスポンスヘッダ―に関して、CSV形式ファイルをダウンロードさせる処理に特別なヘッダーを出力させることがある

```php:書式
header("レスポンスヘッダ―");
```

```php:header.php
<?php
$downloadfile = "data.csv";
header("Content-Disposition: attachment; file");
header("Content-type: application/octet-stream; name=$downloadfile");
$result = file_get_contents("test.data");
print $result;
```

## リダイレクト
### **location**

>
レスポンスヘッダ―として`Location: URL`をブラウザに対して送信するとリダイレクトを実現させることができる
指定するURLは絶対パスにする必要がある

```php:location.php
header("Location: http://google.com/");
exit;
```

# メール送信
## メールの送信
### **mb_send_mail**
- メールを送信する

```php:書式
mb_send_mail(宛先, 件名, 本文, 追加のヘッダー);
```

```php:mb_send_mail.php
$to = "hoge@gmail.com";
$subject = "test";
$message = "hello world";
$add_header = "From:hogehoge@gmail.com\r\nCc:hogehogehoge@gmail.com";
if(mb_send_mail($to, $subject, $message, $add_header)){
  print "メールを送信しました。";
} else {
  print "メール送信に失敗しました。";
}
```

# 正規表現
## 正規表現を使用する
### **preg_match**
- 正規表現を使用する

```php:書式
preg_match(正規表現パターン, 文字列);
```

― if文で使う

```php:preg_match1.php
$number = "123456";
if(preg_match("/[0-9]+/", $number)){
  print "数字です";
} else {
  print "数字以外の文字です";
}
```

>
マッチした文字列を参照したいときは「"/([0-9]+)/"」のように正規表現を（）で囲む
3つ目の引数に配列`$matches`を指定すると、
`$matches[0]`に文字列全体を格納
`$matches[1]`に1番目にマッチした文字列を格納
`$matches[2]`に2番目にマッチした文字列を格納

```php:preg_match2.php
$number = "123456";
if(preg_match("/([0-9][0-9])([0-9]+)/", $number, $matches)){
  // 123456が格納される
  print $matches[0];
  // 12が格納される
  print $matches[1];
  // 3456が格納される
  print $matches[2];
}
```

### **preg_replace / ereg_replace / mb_ereg_replace**
- 正規表現を使った置換処理

```php:書式
$変数 = preg_replace(正規表現, 置換後の文字, 置換対象文字列);
$変数 = ereg_replace(正規表現, 置換後の文字, 置換対象文字列);
$変数 = mb_ereg_replace(正規表現, 置換後の文字, 置換対象文字列);
```

>
`preg_replace`関数は正規表現の指定時「/正規表現/」のようにPerl形式で指定
`ereg_replace`関数は「//」が不要
`mb_ereg_replace`関数は`ereg_replace`関数をマルチバイトを扱えるようにしたもの

# 後記
頑張って全部のチャプター書き上げたいなといった気持ちです。