IBM Cloud(旧Bluemix)でPHP+MySQLのWebアプリを動かす

# 前提
この記事はIBM Cloudアカウントを、従量課金 (PAYG) へアップグレードした人を対象としています。
アップグレードにはクレジットカード情報の登録が必要です。
クレジットカード登録をしていない無料アカウントではMySQLを作成できないため。

# 対象ユーザー
IBM Cloud上でPHP＋MySQLのアプリを動かしたい人。

# 概要
IBM Cloud上にPHP実行環境を作成して、MySQLに接続する。
MySQLにデータを入れ、Webブラウザに表示させる簡単なWebアプリを作成します。
IBM Cloudで使用できるMySQLには「Compose for MySQL」と「ClearDB　Managed MySQL Database」の２種類あります。
今回は「ClearDB」を使用します。


# PHPアプリの作成
1. IBM Cloudへログイン後、右上の「リソースの」作成を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/03670df5-82d9-ce15-2a4d-5dbb0584d023.png)

1. 検索窓に「php」と入力してフィルターした後、Cloud Foundryアプリの「PHP」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/ed8cf48f-b486-665f-50cb-64afad5e30cd.png)

1. 任意のアプリ名を入力
今回は「MyPhpApp001」と入力しています。※アプリ名はIBMCloud上でユニークでないといけません。（他のユーザーが使用していた場合はエラーになり作成できません）

1. 入力後、右下の「作成」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/a4f240ab-b7d4-7f75-33f4-e13a0abb5409.png)

# MySQLの作成
1. 「リソースの」作成を選択し、 検索窓に「mysql」と入力してフィルターした後、「ClearDB Managed MySQL Database」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/3d30a023-96ea-e538-67f0-e90ccb9c0cdb.png)

1. プランは「CB5」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/6667922a-c638-ca13-758a-1a635c475d5d.png)

# PHPアプリとMySQLを接続
1. 「ダッシュボード」へ移動
1. ダッシュボードから「MyPhpApp001」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/6475fbd4-cf83-f095-22ab-7a158b610277.png)

1. 「接続」から「接続の作成」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/760648e8-528b-987c-8c16-eac4feea39ed.png)

1. 「ClearDB」が表示されるので「Connect」を選択して再ステージする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/912dd366-6cf5-376b-3811-fa11bae6c90d.png)

# ClearDBの情報を確認
IBM CloudではCloudFoundaryアプリケーションに、MySQLなどのサービスを接続（バインド）することにより、CloudFoundaryアプリケーション側では、次のような値が環境変数VCAP_SERVICESに設定されます。(一部、伏せ字にしています)

1. 「ランタイム」より、「環境変数」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/82ba8c6b-c76e-b6ea-5151-4be307fb9c3d.png)

VCAP_SERVICESに「ClearDB」に接続するための情報が記述されています。


# MySQLにデータを入れる
### ローカルPCからMySQLへログイン

ターミナルから、以下のコマンドを入力する。
ユーザー名、ホスト名、パスワードはVCAP_SERVICESに記載の値を入力する。

```console:console
$ mysql -u ユーザー名 -p --host ホスト名 --ssl-mode=REQUIRED
Enter password: パスワード

mysql>
```
### データベースを表示

```sql:console
mysql> SHOW DATABASES;
+----------------------+
| Database             |
+----------------------+
| information_schema   |
| ibmx_xxxxxxxxxxxxxxx |
+----------------------+
```
VCAP_SERVICESのname欄と同じ名前のものがある

### データベースの選択

```sql:console
mysql> USE ibmx_xxxxxxxxxxxxxxx;
```

### サンプルのテーブルを作成

```sql:console
mysql> CREATE TABLE sample(id integer, name char(16), branch char(20), age integer);
```

### サンプルデータを挿入

```sql:console
INSERT INTO sample (id, name, branch, age) VALUES ('1','Takasaki','Nagoya','29');
INSERT INTO sample (id, name, branch, age) VALUES ('2','Sawanobori','Nara','31');
INSERT INTO sample (id, name, branch, age) VALUES ('3','Sugimoto','Wakayama','34');
INSERT INTO sample (id, name, branch, age) VALUES ('4','Kitada','Osaka','25');
INSERT INTO sample (id, name, branch, age) VALUES ('5','Yamamoto','Fukuoka','38');
INSERT INTO sample (id, name, branch, age) VALUES ('6','Kadokawa','Tokyo','24');
```

### テーブルの中身を表示

```sql:console
mysql> SELECT * FROM sample;
+------+------------+----------+------+
| id   | name       | branch   | age  |
+------+------------+----------+------+
|    1 | Takasaki   | Nagoya   |   29 |
|    2 | Sawanobori | Nara     |   31 |
|    3 | Sugimoto   | Wakayama |   34 |
|    4 | Kitada     | Osaka    |   25 |
|    5 | Yamamoto   | Fukuoka  |   38 |
|    6 | Kadokawa   | Tokyo    |   24 |
+------+------------+----------+------+
```
# PHPファイルを作成
MySQLに入れたデータをPHPを使ってWebブラウザで表示させてみます。
## Eclipse Orion Web IDEを起動
1. ダッシュボードからPHPアプリを選択し、「概要」から「継続的デリバリー」の有効化を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/2258ffef-b695-3094-69d8-a024c0ae08b8.png)

1. 「Eclipse Orion Web IDE」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/3ae4ba2c-ad0c-0696-308e-92294b3dac47.png)




# デプロイ設定
1. 「新規起動構成の作成」から「➕」ボタンを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/5441fef8-13f1-a982-0e63-5c24c07f3e4a.png)

1. そのまま「保存」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/7f778934-1d6d-133c-453c-875b7c0df75a.png)

# manifestファイル作成
1. アプリのルート直下に「manifest.yml」というファイルを作成し、以下のように記載

```yml:manifest.yml
---
applications:
- name: MyPhpApp001
  memory: 64M
  instances: 1
```

# PHP拡張モジュール有効化
1. アプリのルート直下に「.bp-config」というフォルダを作成
2. 「.bp-config」フォルダ内に「options.json」というファイルを追加
3. 「options.json」の内容を以下のように記載

```json:options.json
{
  "PHP_EXTENSIONS": ["bz2", "zlib", "openssl", "curl", "mcrypt", "mbstring", "pdo", "pdo_mysql", "mysqli"]
}
```
4.アプリのルート直下に「composer.json」というファイルを追加
5.「composer.json」の内容を以下のように記載(中括弧のみ)

```json:composer.json
{}
```

# MySQL接続用ファイルの作成
アプリのルート直下にDB接続用のファイル「db.php」を作成する

```php:db.php
<?php
if(!$_ENV["VCAP_SERVICES"]){ //local dev
    $mysql_server_name = "127.0.0.1：8889";
    $mysql_username = "username";
    $mysql_password = "password";
    $mysql_database = "database";
} else { //running in Bluemix
	$vcap_services = json_decode($_ENV["VCAP_SERVICES"]);
	if($vcap_services->{'mysql-5.5'}){ //if "mysql" db service is bound to this application
	    $db = $vcap_services->{'mysql-5.5'}[0]->credentials;
	} 
	else if($vcap_services->{'cleardb'}){ //if cleardb mysql db service is bound to this application
	    $db = $vcap_services->{'cleardb'}[0]->credentials;
	} 
	else { 
	    echo "Error: No suitable MySQL database bound to the application. <br>";
	    die();
	}
	$mysql_database = $db->name;
	$mysql_port=$db->port;
	$mysql_server_name =$db->hostname . ':' . $db->port;
	$mysql_username = $db->username; 
	$mysql_password = $db->password;
}
// 文字化け対策
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>"SET CHARACTER SET 'utf8'");

// DBに接続
try {
    $pdo = new PDO('mysql:host='.$mysql_server_name.';dbname='.$mysql_database, $mysql_username, $mysql_password, $options);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    exit('データベース接続失敗。'.$e->getMessage());
}

?>
```

# MySQLデータ表示用ファイルの作成
「index.php」の内容を以下のように記載

```php:index.php
<?php
// bluemix接続の場合はhttpsへリダイレクト
if($_ENV["VCAP_SERVICES"]){
    if (empty($_SERVER['HTTPS'])) {
        header("Location: https://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
        exit;
    }
}

// XSS対策用エスケープ関数
function h($s) {
    return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}

// DB接続
require_once('db.php');

// データを取得
$sql = 'SELECT * FROM sample';
$rows = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);

?>
<!DOCTYPE html>
<html>
<head>
	<title>てすと</title>
</head>
<body>
	<table border="1">
		<thead>
			<tr>
				<th>id</th>
				<th>name</th>
				<th>branch</th>
				<th>age</th>
			</tr>
		</thead>
		<tbody>
			<tr>
			<?php
			foreach ($rows as $row) {
				echo '<tr>';
				echo '<td>'.h($row['id']).'</td>';
				echo '<td>'.h($row['name']).'</td>';
				echo '<td>'.h($row['branch']).'</td>';
				echo '<td>'.h($row['age']).'</td>';
				echo '</tr>';
			}?>
			</tr>
		</tbody>
	</table>
</body>
</html>
```

# デプロイ
 「▶」を押して、デプロイ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/0d6e525d-3042-d735-dbb9-1ff267f38ca8.png)

# Webブラウザで表示

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172809/44d83cb3-2fce-34d4-c352-c79879302a0d.png)

# おわりに
今回は単純にMySQLのデータを表示するだけのアプリを作成しました。（アプリと言えるレベルではありませんが。。）
IBM CloudでPHPからMySQLへ接続する部分でお困りの方の手助けになれば幸いです。

# 参考資料
- [Bluemix CFランタイムのPHP と DBaaS MySQLを繋いでアプリを動かしてみた](https://qiita.com/MahoTakara/items/598fc3452be7dc712af4)
- [BluemixでPHP拡張モジュールを有効にする方法](https://qiita.com/kk300/items/ee5955039bd68e62bff6)