- 更新日: 2018年07月30日
- 公開日: 2018年07月29日
PHPからMySQLに接続する方法を簡単に解説
PHPとMySQLの接続は慣れていないと手順が多く複雑に感じることが多いと思ます。この記事では「PHPでMySQLを操作して、アプリケーションの基本的なデータベース操作を行う」ことを目標として手順をまとめています。これから、主に以下の内容を解説していきます。
- PHPとMySQLを接続するためにMySQLにデータベースを用意する
- PHPからMySQLへ接続する
- CRUD操作を行いPHPからMySQLを自在に操作する
- PHP側にてSQLインジェクション攻撃に対する対策をする
PHPからMySQLに接続する方法!
当記事は以下の環境にて検証しています。
- Mac OS X 10.12.4
- PHP 7.1.16
- MySQL 5.7.21
PHPからMySQLに接続して、様々な操作をしてみる
データベースを用意する
前提条件として、MySQLのインストールは完了しており、MySQLのログインができるものとします。もしわからなければ、公式リファレンスをご覧ください。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 2 MySQL のインストールと更新
今回は、例としてECサイトのデータベースを作ってみましょう。データベースは、扱うSQL構文の種類が多く、その全てを個別に説明することができません。もし、分からない構文があったら、公式リファレンスを読んでみてください。
まず、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サイト担当者としてのスキルが身に付く/
まとめ
PHPでMySQLと接続することは、MySQLのセットアップから接続、SQLの構文の理解、PHPでのMySQL操作の関数の使用などやるべきことが多く初心者が挫折しやすい箇所です。
しかし、WEBアプリケーションを作るためには、データベースは必要不可欠であり、PHPでデータベース操作を行えるようになると幅広いアプリケーションを作ることができます。ここでの説明は、マニュアル的な説明を最低限したものですので、もしわからないことがあったらMySQLかPHPの公式ドキュメントをその都度確認するようにしましょう。
また、昨今はWEBアプリケーションの脆弱性を狙ったSQLインジェクション攻撃が横行しています。WEBアプリケーションを公開することになったら、mysqli_real_escape_string()関数
を用いて入力値のエスケープを怠らないようにしましょう。
参考文献
「パーフェクトPHP」小川雄大、柄沢聡太郎、橋口誠、著、技術評論社、2010
- この記事を書いた人
- 山川竜太郎