PHPプログラミング

#1 はじめに
PHPは、スクリプト言語の1つです。
HTMLに埋め込むことができるので、Web開発に適しています。


#2 環境
VMware Workstation 15 Player上の仮想マシンを使いました。
仮想マシンの版数は以下のとりです。

```console:CentOSの版数
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 8.3.2011
```

```console:カーネル版数
[root@server ~]# uname -r
4.18.0-240.el8.x86_64
```

#3 インストール方法

```console:インストール方法
[root@server ~]# dnf install php
```

```console:版数確認
[root@server ~]# php -v
PHP 7.2.24 (cli) (built: Oct 22 2019 08:28:36) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
```

#4 Hello World
`<?php`で始まる開始タグと、`?>`で終わる終了タグの間にPHPコマンドを定義します。

```console:スクリプトファイル作成
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
echo "Hello world!!"."\n";
?>
```

```console:実行権付与
[root@server ~]# chmod 744 tp.php
```

```console:実行結果
[root@server ~]# ./tp.php
Hello world!!
```


#5 コマンドライン引数の使い方
|変数名              | 意味                            |
|:-----------------|:--------------------------------|
|argc              |引数の数を表します。              |
|argv[0]           |PHPスクリプトファイル自身の名前を表します |
|argv[1]～argv[N]  |第1引数から第N引数を表します       |


```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
if( $argc != 2 ){
  print "usage:./tp [arg1]"."\n";
  exit(1);
}
print "arg[0]=$argv[0]"."\n";
print "arg[1]=$argv[1]"."\n";
?>
```

```console:実行結果
[root@server ~]# ./tp.php 1
arg[0]=./tp.php
arg[1]=1
```

```console:実行結果
[root@server ~]# ./tp.php a
arg[0]=./tp.php
arg[1]=a
```


#6 変数の使い方
変数はドルマーク($)＋変数名であらわします。
なお、変数名には以下の条件があります。
・先頭文字は、アルファベット、またはアンダースコアのみ使用可。
・2文字目以降の文字は、アルファベット、数字、アンダースコアのみ使用可。

##6.1 文字列の使い方

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
$name="hana_shin";
echo "My name is $name"."\n";
?>
```

```console:実行結果
[root@server ~]# ./tp.php
My name is hana_shin
```

##6.2 シングルクォートとダブルクォートの違い

|引用符の種類      | 意味 |
|:---------------|:------|
|ダブルクォート   |ダブルクォートで囲まれた変数は値に置き換わる   |
|シングルクォート |シングルクォートで囲まれた変数は値に置き換わらない   |

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
$name="hana_shin";
echo "My name is $name"."\n";
echo 'My name is $name'."\n";
?>
```

```console:実行結果
[root@server ~]# ./tp.php
My name is hana_shin
My name is $name
```


##6.3 数値の使い方

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
$val=12345;
echo "$val\n";
?>
```

```console:実行結果
[root@server ~]# ./tp.php
12345
```


#7 文字列の操作方法
##7.1 各種文字列操作関数の使い方

|関数      | 意味 |
|:---------------|:------|
|strlen   |文字列の長さを調べる   |
|substr |文字列の一部を取り出す   |
|str_replace |文字列の一部を別の文字列に置き換える   |

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
$str="12345";
printf("strlen=%d\n", strlen($str));
printf("substr=%s\n", substr($str,2,3));
printf("str_replace=%s\n", str_replace('234','bcd',$str));
?>
```


```console:実行結果
[root@server ~]# ./tp.php
strlen=5
substr=345
str_replace=1bcd5
```


##7.2 文字列結合演算子の使い方(ピリオド)

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
print "123"."45"."\n";
?>
```

```console:実行結果
[root@server ~]# ./tp.php
12345
```

##7.3 クエリ文字列を分解する方法(parse_str)
クエリ文字列とは、名前と値を`=`で紐づけたペアを`&`で結合した文字列です。
たとえば、次のような文字列になります
`first_name=hana&last_name=shin&age=10`
`parse_str`を使って、クエリ文字列から名前と値のペアを取り出してみます。

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $str = "first_name=hana&last_name=shin&age=10";
  parse_str($str, $output);
  foreach($output as $key => $value) {
    print "$key=$value"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php
first_name=hana
last_name=shin
age=10
```



#8 条件分岐の使い方

##8.1 基本的な使い方

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $var=$argv[1];
  if($var == 1) {
    print "1"."\n";
  }
  else if($var == 2) {
    print "2"."\n";
  }
  else {
    print "other"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php 1
1
```

```console:実行結果
[root@server ~]# ./tp.php 2
2
```

```console:実行結果
[root@server ~]# ./tp.php 3
other
```

##8.2 論理演算子の使い方
・`$a && $b` :`$a`および`$b`が共に真の場合に真となる
・`$a|| $b` :`$a`または`$b`のどちらかが真の場合に真となる


コマンドライン引数の値が10以上,20未満なら`IN`、
それ以外なら`OUT`と表示するスクリプトを作成します。

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $var=$argv[1];
  if(($var >=10) && ($var <20)) {
    print "IN"."\n";
  }
  else {
    print "OUT"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php 10
IN
```

```console:実行結果
[root@server ~]# ./tp.php 20
OUT
```



#9 繰り返しの使い方

##9.1 while文

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $var=0;
  while($var++ < 5){
    print "$var"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php
1
2
3
4
5
```


##9.2 for文

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  for($var=0; $var<5; $var++) {
   print "$var"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php
0
1
2
3
4
```


#10 配列の使い方


##10.1 配列の作り方
###10.1.1 arrayを使う方法

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $var = array("aa","bb","cc");
  print "$var[0]"."\n";
  print "$var[1]"."\n";
  print "$var[2]"."\n";
?>
```


```console:実行結果
[root@server ~]# ./tp.php
aa
bb
cc
```

###10.1.2 キーを指定して値を代入する方法
キーが`0`,`1`,`2`の要素に値`10`,`20`,`30`を代入してみます。

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $var[0] = 10;
  $var[1] = 20;
  $var[2] = 30;
  foreach ($var as $tmp) {
    print "$tmp"."\n";
  }
?>
```


```console:実行結果
[root@server ~]# ./tp.php
10
20
30
```

###10.1.3 連想配列の作成方法
連想配列とは、数値ではなく文字列をキーとした配列のことです。
以下の場合、`suzuki`,`sato`,`ito`が数値ではなく文字列になっています。
foreachを使って、連想配列の値を表示してみます。

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $person=array("suzuki"=>30, "sato"=>40, "ito"=>50);
  foreach($person as $key=>$value) {
    print "$key is $value years old"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php
suzuki is 30 years old
sato is 40 years old
ito is 50 years old
```


##10.2 配列への要素の追加、削除方法

###10.2.1 配列の先頭に要素を追加する方法(array_unshift)

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  print "--- before adding item ---"."\n";
  $item = array("11", "22", "33");
  foreach($item as $key => $value) {
    print "[$key]=$value"."\n";
  }

  print "--- after adding item ---"."\n";
  $size = array_unshift($item, "88", "99");
  foreach($item as $key => $value) {
    print "[$key]=$value"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php
--- before adding item ---
[0]=11
[1]=22
[2]=33
--- after adding item ---
[0]=88
[1]=99
[2]=11
[3]=22
[4]=33
```

###10.2.2 配列の末尾に要素を追加する方法(array_push)

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  print "--- before adding item ---"."\n";
  $item = array("11", "22", "33");
  foreach($item as $key => $value) {
    print "[$key]=$value"."\n";
  }

  print "--- after adding item ---"."\n";
  $size = array_push($item, "88", "99");
  foreach($item as $key => $value) {
    print "[$key]=$value"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php
--- before adding item ---
[0]=11
[1]=22
[2]=33
--- after adding item ---
[0]=11
[1]=22
[2]=33
[3]=88
[4]=99
```


###10.2.3 配列の先頭から要素を削除する方法(array_shift)
```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  print "--- before adding item ---"."\n";
  $item = array("11", "22", "33");
  foreach($item as $key => $value) {
    print "[$key]=$value"."\n";
  }

  print "--- after adding item ---"."\n";
  $size = array_shift($item);
  foreach($item as $key => $value) {
    print "[$key]=$value"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php
--- before adding item ---
[0]=11
[1]=22
[2]=33
--- after adding item ---
[0]=22
[1]=33
```


###10.2.4 配列の末尾から要素を削除する方法(array_pop)

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  print "--- before adding item ---"."\n";
  $item = array("11", "22", "33");
  foreach($item as $key => $value) {
    print "[$key]=$value"."\n";
  }

  print "--- after adding item ---"."\n";
  $size = array_pop($item);
  foreach($item as $key => $value) {
    print "[$key]=$value"."\n";
  }
?>
```

```console:実行結果
[root@server ~]# ./tp.php
--- before adding item ---
[0]=11
[1]=22
[2]=33
--- after adding item ---
[0]=11
[1]=22
```




##10.4 配列の要素を全て表示する方法(var_dump)
デバッグするときに使います。

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $var = array("aa","bb","cc");
  var_dump($var);
?>
```

```console:実行結果
[root@server ~]# ./tp.php
array(3) {
  [0]=>
  string(2) "aa"
  [1]=>
  string(2) "bb"
  [2]=>
  string(2) "cc"
}
```

##10.6 配列の要素の値を合計する方法(array_sum)

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $value_array = array(100, 200, 300, 400);
  $sum = array_sum($value_array);
  print "sum is $sum"."\n"
?>
```

```console:実行結果
[root@server ~]# ./tp.php
sum is 1000
```

##10.7 配列の要素を検索する方法(array_search)
`array_search`は、配列から指定した値をもつ要素を検索するときに使います。
書式は以下のとおりです。
`array_search(検索値,対象配列,型チェックオプション）`
指定した値を持つ要素が見つかった場合、その要素のキーを返します。
型チェックオプションを省略すると、`FALSE`を指定したことになります。
`FALSE`は、数値の10と文字列の"10"は同じと判断されます。

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $val = $argv[1];
  $customer = array("suzuki"=>30, "sato"=>40, "kato"=>50);
  $key = array_search($val, $customer);
  if($key == TRUE) {
    print "$key is $val years old"."\n";
  }
  else {
    print "Not Fond"."\n";
  }
?>
```

年齢が20歳の人を探す。誰もいないことがわかる。

```console:実行結果
[root@server ~]# ./tp.php 20
Not Fond
```

年齢が30歳の人を探す。suzukiさんが該当することがわかる。

```console:実行結果
[root@server ~]# ./tp.php 30
suzuki is 30 years old
```

年齢が50歳の人を探す。katoさんが該当することがわかる。

```console:実行結果
[root@server ~]# ./tp.php 50
kato is 50 years old
```



#11 関数の使い方
##11.1 引数の使い方

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  function add($arg1, $arg2) {
    $sum = $arg1 + $arg2;
    return $sum;
  }
  print add(10,20);
  print "\n";
?>
```

```console:実行結果
[root@server ~]# ./tp.php
30
```

##11.2 引数のデフォルト値の使い方
関数の引数には、呼び出し時に値がない場合に備え、デフォルト値を指定することができます。
デフォルト値を持つ全ての引数は、デフォルト値を持たない引数の後に置きます。

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  function add($arg1, $arg2=20, $arg3=30) {
    $sum = $arg1 + $arg2 + $arg3;
    return $sum;
  }
  print add(10);
  print "\n";
  print add(100,200,300);
  print "\n";
?>
```

```console:実行結果
[root@server ~]# ./tp.php
60
600
```

#12 時刻を表示する方法

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  print "date      :".date('c')."\n";
  print "strftime  :".strftime('%c')."\n";
?>
```


```console:実行結果
[root@server ~]# ./tp.php
date      :2021-01-09T10:59:06+00:00
strftime  :Sat Jan  9 10:59:06 2021
```


#13 ファイルを読み書きする方法

##13.1 ファイルの内容を全て読み込む方法

```console:事前準備
[root@server ~]# echo 1234567890 > test.txt
[root@server ~]# cat test.txt
1234567890
```

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $str = file_get_contents('./test.txt');
  print "$str"."\n";
?>
```


```console:実行結果
[root@server ~]# ./tp.php
1234567890
```


##13.2 ファイルの一部を読み込む方法
`test.txt`の6文字目から3文字読み込んでみます。

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  $str = file_get_contents('./test.txt', FALSE, NULL, 5, 3);
  print "$str"."\n";
?>
```


```console:実行結果
[root@server ~]# ./tp.php
678
```

#14 ファイルをインクルードする方法(include)

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  print "main file"."\n";
  include('hoge.php');
?>
```

```console:ソースコード
[root@server ~]# cat hoge.php
<?php
  print "hoge file"."\n";
?>
```

```console:実行結果
[root@server ~]# ./tp.php
main file
hoge file
```


#15 データベースへの接続方法
ここでは、MariaDBに接続してみます。MariaDBの構築方法は、[MariaDBの使い方](https://qiita.com/hana_shin/items/4d7e9f07e206e989834b)を参照ください。
セキュリティ上、rootでデータベースに接続すべきではないと思いますが、
便宜上rootで接続しています。

##15.1 事前準備
私の環境では、スクリプトを実行すると、下記エラーが発生したので、

```console:発生したエラー
PHP Fatal error:  Uncaught Error: Class 'PDO' not found in /root/tp.php:3
PHP Fatal error:  Uncaught PDOException: could not find driver in /root/tp.php:3
```

以下のパッケージをインストールしました。

```console:パッケージのインストール
[root@server ~]# dnf -y install php-pdo
[root@server ~]# dnf -y install php-mysqlnd
```

##15.2 データベースの作成
PHPから`testdb`という名前のデータベースに対して接続をするので、
あらかじめ、MariaDBのモニタで`testdb`データベースを作成しておきます。

```console:データベースの作成
MariaDB [(none)]> create database testdb;
Query OK, 1 row affected (0.000 sec)
```

データベースを確認する。
`testdb`という名前のデータベースが作成されたことがわかる。

```console:データベースの確認
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| testdb             |
+--------------------+
5 rows in set (0.001 sec)
```


##15.3 データベースへの接続
データベースに接続して、`customer`という名前のテーブルを作成します。
そして、`customer`テーブルにレコードを登録します。
レコードは、名前と年齢から構成されています。

```console:ソースコード
[root@server ~]# cat tp.php
#!/usr/bin/php
<?php
  try {
    $pdo = new PDO('mysql:host=127.0.0.1;dbname=testdb', 'root', 'admin');
    $sql = "create table customer (name varchar(32), age tinyint unsigned)";
    $stmt = $pdo->query($sql);
    $sql = "insert into customer values('suzuki', 40)";
    $stmt = $pdo->prepare($sql);
    $res = $stmt->execute(null);
  }catch(Exception $e) {
    die("Connection Failed: ".$e->getMessage());
  }
  $pdo = null;
?>
```

`testdb`データベースに登録されているテーブルを確認する。
テーブルはなにも登録されていないことがわかる。

```console:テーブルの確認
MariaDB [testdb]> show tables;
Empty set (0.001 sec)
```

スクリプトを実行する。

```console:スクリプト実行
[root@server ~]# ./tp.php
```

テーブルを確認する。
`customer`という名前のテーブルが作成されたことがわかる。

```console:テーブルの確認
MariaDB [testdb]> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| customer         |
+------------------+
1 row in set (0.000 sec)
```

`customer`テーブルに登録されたレコードを確認する。
名前が`suzuki`、年齢`40`のレコードが登録されたことがわかる。

```console:レコードの確認
MariaDB [testdb]> select * from customer;
+--------+------+
| name   | age  |
+--------+------+
| suzuki |   40 |
+--------+------+
1 row in set (0.000 sec)
```



#Z 参考情報
[PHP Data Objects](https://www.php.net/manual/ja/book.pdo.php)
[とほほのPHP入門](http://www.tohoho-web.com/php/about.html#install)
[徹底攻略 PHP5技術者認定[初級]試験 問題集 [PJ0-100]対応 ](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-PHP5%E6%8A%80%E8%A1%93%E8%80%85%E8%AA%8D%E5%AE%9A-PJ0-100-IT%E3%83%97%E3%83%AD-IT%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5/dp/4844332775/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=PHP5&qid=1610176229&sr=8-2)