PHPからMySQLに接続する方法を簡単に解説


PHPからMySQLに接続する方法を簡単に解説

PHPとMySQLの接続は慣れていないと手順が多く複雑に感じることが多いと思ます。この記事では「PHPでMySQLを操作して、アプリケーションの基本的なデータベース操作を行う」ことを目標として手順をまとめています。これから、主に以下の内容を解説していきます。

  • PHPとMySQLを接続するためにMySQLにデータベースを用意する
  • PHPからMySQLへ接続する
  • CRUD操作を行いPHPからMySQLを自在に操作する
  • PHP側にてSQLインジェクション攻撃に対する対策をする
目次
  1. PHPからMySQLに接続する方法!
  2. PHPからMySQLに接続して、様々な操作をしてみる
  3. データベースを用意する
  4. PHPのmysqli_connect()関数でMySQLに接続する
  5. データベースの選択ができるmysqli_select_db()関数
  6. PHPでCRUD操作を行う
  7. まとめ
  8. 参考文献

PHPからMySQLに接続する方法!

当記事は以下の環境にて検証しています。

  • Mac OS X 10.12.4
  • PHP 7.1.16
  • MySQL 5.7.21

PHPからMySQLに接続して、様々な操作をしてみる

images

データベースを用意する

前提条件として、MySQLのインストールは完了しており、MySQLのログインができるものとします。もしわからなければ、公式リファレンスをご覧ください。

MySQL :: MySQL 5.6 リファレンスマニュアル :: 2 MySQL のインストールと更新

今回は、例としてECサイトのデータベースを作ってみましょう。データベースは、扱うSQL構文の種類が多く、その全てを個別に説明することができません。もし、分からない構文があったら、公式リファレンスを読んでみてください。

MySQL :: MySQL Documentation

まず、shopというデータベースを作りましょう。データベースの作成は、CREATE DATABASE構文で行います。

mysql> CREATE DATABASE shop;
Query OK, 1 row affected (0.00 sec)

データベースが正常に作られたかどうかは、SHOW DATABASES構文で確認できます。

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| shop               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

テーブルを作成する。

次にuserテーブルを作りましょう。userテーブルは、顧客の名前を管理するテーブルです。まず、shopデータベースを選択しましょう。洗濯したら、CREATE TABLE構文でテーブルを作ります。userテーブルのカラムは以下の通りです。

  • id: 顧客番号
  • name: 顧客の名前
mysql> USE shop;
Database changed

mysql> CREATE TABLE user (id int, name varchar(20));
Query OK, 0 rows affected (0.04 sec)

CREATE TABLE構文が成功したら、SHOW TABLES構文でテーブルが作成できたか一覧を表示しましょう。さらにSHOW COLUMNS構文でテーブルの構成が正しいか確認しておきましょう。

mysql> SHOW TABLES;
+--------------------+
| Tables_in_shop     |
+--------------------+
| user               |
+--------------------+
1 row in set (0.00 sec)

mysql> SHOW COLUMNS FROM user;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(20) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

userテーブルが正しく作成できていたら、INSERT構文でデータを挿入していきます。顧客番号が「1」で名前が「yamada」というデータを記録します。

mysql> INSERT INTO user (id, name) VALUES (1, 'yamada');
Query OK, 1 row affected (0.01 sec)

次に、INSERT構文でデータが本当にデータベースに記録されているか、SELECT構文で確認してみましょう。

mysql> SELECT * FROM user;
+------+--------+
| id   | name   |
+------+--------+
|    1 | yamada |
+------+--------+
1 row in set (0.00 sec)

正しく記録されていたら、もう1レコードをINSERTしていきます。

mysql> INSERT INTO user (id, name) VALUES (2, 'takahashi');
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM user;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | yamada    |
|    2 | takahashi |
+------+-----------+

以上で準備は完了です。いよいよこれからPHPでMySQLに接続します。

PHPのmysqli_connect()関数でMySQLに接続する

いよいよPHPでMySQLに接続していきます。接続にはmysqli_connect()関数を使用します。mysqli_connect()関数は、新たにMySQLサーバーへの接続をオープンにします。

mysql_connect()関数は、PHP5.5.0で非推奨となり、PHP7.0.0で削除されました。これからmysql_connect()関数を使用するメリットはないので、明確な理由がない限りmysqli_connect()関数を使用しましょう。

書式

mysqli_connect($host,$username,$passwd,$dbname,$port,$socket)
引数 属性 パラメータ
$host string ホスト名またはIPアドレス
$username(任意) string MySQLのユーザー名
$passwd(任意) string $usernameのパスワード
$dbname(任意) string クエリが行われるデフォルトのデータベース
$port(任意) string MySQLサーバーに接続する際のポート番号
$socket(任意) string 使用するソケット

返り値

MySQLサーバーへの接続を表すオブジェクトを返します。

サンプルコード

mysqli_connect()関数を使用してMySQLサーバーに接続してみます。サンプルコードでは、mysqli_connect()関数の引数は筆者の環境に合わせたものになっているので、ご自身の環境に合わせて読み替えてみてください。

connect.php

<?php

$link = mysqli_connect('localhost', 'user', 'pass', 'shop');

// 接続状況をチェックします
if (mysqli_connect_errno()) {
    die("データベースに接続できません:" . mysqli_connect_error() . "\n");
} else {
    echo "データベースの接続に成功しました。\n";
}

出力結果

$ php connect.php
データベースの接続に成功しました。

エラーの対処法

サンプルコードでは、MySQLの接続に失敗したときのエラーメッセージをmysqli_connect_errno()関数にてエラーコードのチェックの後に、接続エラーが発生した場合には、エラーメッセージをmysqli_connect_error()関数で表示しています。各種エラーメッセージの例を挙げるので、もしMySQLに接続できないときはエラーメッセージで原因を把握して解決してください。

ホスト名たはIPアドレスが間違っている場合は「Operation timed out」と表示されます。

$ php connect.php

Warning: mysqli_connect(): (HY000/2002): Operation timed out in /src/mysql/connect.php on line 3
データベースに接続できません:Operation timed out

MySQLのユーザー名かパスワードが間違っている場合は「Access denied for user 'ユーザー名'@'ホスト名'」と表示されます。

$ php connect.php

Warning: mysqli_connect(): (HY000/1045): Access denied for user 'user'@'localhost' (using password: YES) in /src/mysql/connect.php on line 3
データベースに接続できません:Access denied for user 'user'@'localhost' (using password: YES)

存在しないデータベースを指定した場合は「Unknown database 'データベース名'」と表示されます。

$ php connect.php

Warning: mysqli_connect(): (HY000/1049): Unknown database 'store' in /src/mysql/connect.php on line 3
データベースに接続できません:Unknown database 'store'

MySQLサーバーが立ち上がっていない場合は「Connection refused」と表示されます。

$ php connect.php
PHP Warning:  mysqli_connect(): (HY000/2002): Connection refused in /src/mysql/connect.php on line 3

Warning: mysqli_connect(): (HY000/2002): Connection refused in /src/mysql/connect.php on line 3
データベースに接続できません:Connection refused

データベースの選択ができるmysqli_select_db()関数

mysqli_connect()関数でデフォルトのデータベースの選択をしたあとに、デフォルトのデータベースを変更するために新たに選択できるmysqli_select_db()関数があります。

書式

mysqli_select_db($link,$dbname)
引数 属性 パラメータ
$link mysqliオブジェクト mysqli_connect()が返したリンクID
$dbname string データベース名

返り値

成功した場合にTRUEを、失敗した場合にFALSEを返します。

サンプルコード

shopからshop_groceryに接続するデータベースを変更します。サンプルコードでは、current_database()関数という現在選択されているデータベース名を表示する関数を作っています。

mysqli_select_db.php

<?php

//$link = mysqli_connect('localhost', 'user', 'pass', 'shop');

// 接続状況をチェックします
if (mysqli_connect_errno()) {
    die("データベースに接続できません:" . mysqli_connect_error() . "\n");
}

echo "データベースの接続に成功しました。\n";

// 現在のデータベースを確認します。
current_database($link);

// データベースを shop_grocery に変更します
mysqli_select_db($link, 'shop_grocery');

// 現在のデータベースを確認します。
current_database($link);

// 接続を閉じます
mysqli_close($link);


// 現在の現在のデータベース名を返す関数です。
function current_database($link)
{
    if ($result = mysqli_query($link, "SELECT DATABASE()")) {
        $row = mysqli_fetch_row($result);
        printf("今のデータベースは %s です\n", $row[0]);
        mysqli_free_result($result);
    }
}

出力結果

$ php mysqli_select_db.php
データベースの接続に成功しました。
今のデータベースは shop です
今のデータベースは shop_grocery です

無事に変更することができました。現在のデータベースを変更することは、あまり行いませんが覚えておいて損はないはずです。

PHPでCRUD操作を行う

CRUD(クラッド)とはデータを操作するための必要最低限の機能のことです。以下の頭文字を並べたものです。

  • 生成(Create)
  • 読み取り(Read)
  • 更新(Update)
  • 削除(Delete)

具体的に、データベースに当てはめると、以下のSQLの構文に対応します。

データ操作の機能 SQLの構文
Create INSERT構文
Read SELECT構文
Update UPDATE構文
Delete DELETE構文

各種CRUD操作について、サンプルコードを交えて詳しく説明します。

INSERT構文

INSERT構文は、既存のテーブルに新しいレコードを挿入します。データベースを準備する段階で、登場していますがPHPではどのように実行するのか見ていきます。

MySQLでの書式の一例

INSERT INTO [テーブル名] [(カラム名1,カラム名2,...)] VALUES [(カラム名1の値,カラム名2の値,...)];

insert.php

<?php

$link = mysqli_connect('localhost', 'user', 'pass', 'shop');

// 接続状況をチェックします
if (mysqli_connect_errno()) {
    die("データベースに接続できません:" . mysqli_connect_error() . "\n");
}

echo "データベースの接続に成功しました。\n";

// カラム`id`には`1`を、カラム`name`には`yamada`をもつレコードを挿入する
$query = "INSERT INTO user (id, name) VALUES (1, 'yamada');";

// クエリを実行します。
if (mysqli_query($link, $query)) {
    echo "INSERT に成功しました。\n";
}

// 接続を閉じます
mysqli_close($link);

出力結果

$ php insert.php
データベースの接続に成功しました。
INSERT に成功しました。

mysqli_query()関数では、引数として渡されたSQLを実行して結果を返却します。次に解説するSELECT構文以外を実行した場合は、booleanを返却します。

SELECT構文

SELECT構文は、1つ以上のテーブルから選択されたレコードを取得するために使用されます。これもデータベースを準備する段階で、登場していますが、PHPでの実行を改めて確認しておきましょう。

MySQLでの書式の一例

SELECT [(カラム名1,カラム名2,...)] FROM [テーブル名];

select.php

<?php

$link = mysqli_connect('localhost', 'user', 'pass', 'shop');

// 接続状況をチェックします
if (mysqli_connect_errno()) {
    die("データベースに接続できません:" . mysqli_connect_error() . "\n");
}

echo "データベースの接続に成功しました。\n";

// userテーブルの全てのデータを取得する
$query = "SELECT id, name FROM user;";

// クエリを実行します。
if ($result = mysqli_query($link, $query)) {
    echo "SELECT に成功しました。\n";
    foreach ($result as $row) {
        var_dump($row);
    }
}

// 接続を閉じます
mysqli_close($link);

出力結果

$ php select.php
データベースの接続に成功しました。
SELECT に成功しました。
array(2) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(6) "yamada"
}

SELECT構文でのmysqli_query()関数からの返り値は、クエリの結果が連想配列になって返ってきます。正確にはmysqli_resultクラスが返ってくるのですが、連想配列が返ってくるという認識でも問題はありません。

UPDATE構文

UPDATE構文は、指定されたテーブル内の既存のレコードのカラムを新しい値に更新します。

MySQLでの書式の一例

UPDATE [テーブル名] SET [カラム名1 = カラム名1の値,カラム名2 = カラム名2の値,...] WHERE [更新する条件式] ;

update.php

<?php

$link = mysqli_connect('localhost', 'user', 'pass', 'shop');

// 接続状況をチェックします
if (mysqli_connect_errno()) {
    die("データベースに接続できません:" . mysqli_connect_error() . "\n");
}

echo "データベースの接続に成功しました。\n";

// id=1のレコードを更新する
$query = "UPDATE user SET id = 2, name = 'yamato' WHERE id = 1;";

// クエリを実行します。
if (mysqli_query($link, $query)) {
    echo "UPDATE に成功しました。\n";
}

// 接続を閉じます
mysqli_close($link);

出力結果

$ php update.php
データベースの接続に成功しました。
UPDATE に成功しました。

DELETE構文

DELETE構文は、テーブルのレコードを削除します。

MySQLでの書式の一例

DELETE FROM [テーブル名] WHERE [削除する条件式] ;

delete.php

<?php

$link = mysqli_connect('localhost', 'user', 'pass', 'shop');

// 接続状況をチェックします
if (mysqli_connect_errno()) {
    die("データベースに接続できません:" . mysqli_connect_error() . "\n");
}

echo "データベースの接続に成功しました。\n";

// id=2のレコードを削除する
$query = "DELETE FROM user WHERE id = 2;";

// クエリを実行します。
if (mysqli_query($link, $query)) {
    echo "DELETE に成功しました。\n";
}

// 接続を閉じます
mysqli_close($link);

出力結果

$ php delete.php
データベースの接続に成功しました。
DELETE に成功しました。

エスケープ処理

WEBアプリケーションを作るに当たりSQL構文の中にユーザーから受け取った値を使用したくなる時があります。入力した値をそのまま使用したいですが、ユーザーはどんな値をフォームに入力するかわかりません。そこで危険なのがSQLインジェクション攻撃です。SQLインジェクション攻撃とは以下のような事象です。

Web コンテンツ (Web サーバー) から接続しているデータベースサーバーに、管理者・開発者の意図しない特別な細工を施した SQL 文を処理させる事

SQL インジェクション攻撃とその対策 | Microsoft Docsより

そのSQLインジェクション攻撃を防ぐために、使用するのがmysqli_real_escape_string()関数です。

mysqli_real_escape_string()関数は、SQL構文で使用する文字列の特殊文字をエスケープします。つまり、文字列をSQLでは意味の持たない文字列にしてしまうことです。スペースやダブルクォーテーションなどはSQLでは句の区切りだったり、文字列の始まり終わりを表現したりと特別な意味を持ちます。それを無効化します。

次のサンプルコードでは、最初に実行するINSERT構文は、nameカラムの値である$userにスペースが入っているため、失敗します。2回目に実行するINSERT構文は、$userのスペースをSQLでは意味のない文字に変換し、SQLとして解釈できるように無害化することが必要です。

mysqli_real_escape_string.php

<?php

$link = mysqli_connect('localhost', 'user', 'pass', 'shop');

// 接続状況をチェックします
if (mysqli_connect_errno()) {
    die("データベースに接続できません:" . mysqli_connect_error() . "\n");
}

echo "データベースの接続に成功しました。\n";

$user = "'s Sato";

// このクエリは失敗します。$user をエスケープしていないからです
if (!mysqli_query($link, "INSERT INTO user (name) VALUES ('$user')")) {
    printf("エラー: %s\n", mysqli_sqlstate($link));
}

// 文字列のエスケープを行います
$user = mysqli_real_escape_string($link, $user);

// $user をエスケープしたので、このクエリは正しく動作します
if (mysqli_query($link, "INSERT INTO user (name) VALUES ('$user')")) {
    printf("%d 行をINSERTしました。\n", mysqli_affected_rows($link));
}

// 接続を閉じます
mysqli_close($link);
$ php mysqli_real_escape_string.php
データベースの接続に成功しました。
エラー: 42000
1 行をINSERTしました。

Webサイト担当者としてのスキルが身に付く

無料カウンセリングはこちら

まとめ

images

PHPでMySQLと接続することは、MySQLのセットアップから接続、SQLの構文の理解、PHPでのMySQL操作の関数の使用などやるべきことが多く初心者が挫折しやすい箇所です。

しかし、WEBアプリケーションを作るためには、データベースは必要不可欠であり、PHPでデータベース操作を行えるようになると幅広いアプリケーションを作ることができます。ここでの説明は、マニュアル的な説明を最低限したものですので、もしわからないことがあったらMySQLかPHPの公式ドキュメントをその都度確認するようにしましょう。

また、昨今はWEBアプリケーションの脆弱性を狙ったSQLインジェクション攻撃が横行しています。WEBアプリケーションを公開することになったら、mysqli_real_escape_string()関数を用いて入力値のエスケープを怠らないようにしましょう。

参考文献

「パーフェクトPHP」小川雄大、柄沢聡太郎、橋口誠、著、技術評論社、2010

MySQL :: MySQL Documentation

mysqli_connect()関数

mysqli_connect_errno()関数

mysqli_connect_error()関数

mysqli_select_db()関数

クラッド (CRUD)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

INSERT構文

SELECT構文

mysqli_result クラス

UPDATE構文

DELETE構文

SQLインジェクション攻撃

mysqli_real_escape_string()関数


山川竜太郎
この記事を書いた人
山川竜太郎
まずは7日間お試し!人気プログラミング講座を無料公開中
オンライン・プログラミングレッスンNo.1のCodeCamp