さて、いよいよphpの軸とも言える、データベースとの接続です。
phpはデータベースにデータを保存したり、取り出したりするなどの処理が可能です。
データベースを使ったデータの扱いこそ、バックエンド言語の醍醐味です。
今回はエックスサーバーを参考として使っていきます。
もし、今回の記事をそのまま再現したい場合は、エックスサーバーをご利用ください。
ただ、他のサーバーでも作業としての違いはあまりありません。
検索して調べながら進めば、他のサーバーでも理解できるでしょう。
データベースとは、サーバーの中のデータを保存しておく場所です。
HTMLやCSS、画像などがファイルという形を取るのに対し、データベースは「文字」を扱います。
例えば会員データやブログ記事のような、多くの情報を扱う場合に活用できます。
WEBサービスは基本的にデータベースが無ければ成り立ちません。
サーバーでデータベースを設定しよう。
データベースを扱うには、まずサーバー内でデータベースを作る必要があります。
エックスサーバーを参考として、進めていきましょう。
まずはコントロールパネルを開いてください。
そして、MySQL設定を開きます。
他のサーバーでも「データベース作成」等の機能があるはずですので検索してみてください。
すると、データベース名を決めるエリアが現れます。
ご自由にわかりやすいデータベース名を入力してください。
入力し終わったら、右下のMySQLの追加ボタンを押します。
確認画面が現れますので、続けて「MySQLデータベースの追加(確定)」を押してください。
これでデータベースが作成されました。
次にMySQLユーザ追加タブを押します。
データベースにログインする時に必要な「ユーザー名」「パスワード」を決めます。
入力したら、右下のMySQLユーザの追加(確認)を押してください。
MySQLユーザ一覧に、ユーザーが登録されました。
このユーザー名とパスワードは、データベースに接続する際にも使いますので控えておきましょう。
次に「MySQL一覧」タブを押して、作ったデータベースを確認してください。
ここで、先程作った「ユーザー」を「追加」することで、データベースにログイン可能になります。
すぐ下にある「追加」ボタンを押しましょう。
これで、MySqlを扱うユーザーが追加されました。
もう少しだけ、データベースを使うための準備があります。
phpMyAdminメニューをクリックして開いてください。
ログイン後、上記の画面が現れるはずです。
実際にデータベースを使う際は、画面上部のDB情報が必要になるので、こちらも控えておきましょう。
それぞれ、左からサーバー名とデータベース名と呼びます。
では、次に、データの「入れ物」を作っていきましょう。
下記の「名前」と「カラム数」に注目してください。
それぞれ「userdata」「4」と入力されていることにお気づきでしょうか。
データベースには、データを入れるための入れ物を作る必要があります。
それが「テーブル」と呼ばれるものです。
テーブルは、さらに「カラム」という入れ物に細分化されます。
配列で「引き出し」と「小箱」として説明した項目を覚えてらっしゃるでしょうか。
今回はテーブルが引き出しで、カラムが引き出しの中の小箱のようなものです。
テーブルという引き出しに入った、たくさんのカラムという小箱。
その中にデータを入れていきます。
実際に、ユーザーデータを保存したいとします。
ユーザーデータの中には「ID」「名前」「年齢」「スキル」があるとします。
そんな時は「userdata」というテーブルを作り、テーブルの中に4つのカラム ( 番号、名前、年齢、スキル ) を作るということです。
userdataが引き出しとすると、4つのカラムが引き出しに入った小箱です。
だからこ、今回はテーブルの名前をuserdateとつけ、さらにテーブルの中に4つのカラムを作る、という設定をしています。
設定したら画面右下の「実行」ボタンを押しましょう。
これで、userdataという入れ物が出来ました。
今度はカラムを1つ1つ設定していきましょう。
まずは、上記のように設定してください。
基本的には下記の4つを設定すればOKです。
- 名前 ( カラムの名前 )
- データ型 ( 数字や文字、文章などデータの形 )
- 長さ/値 ( データの長さ )
- デフォルト値 ( 何もなければNULLか未記入 )
idだけは他と設定が少し異なります。
データが入力されたら、自動的に連番になるように作ります。
その時は「A_I」にチェックを入れましょう。
ポップアップが出てくるので、実行を押してください。
実行すると、そのまま確定され、データが入る度にカウントされる連番になります。
すべて設定し終わったら、右下の保存を押しましょう。
これで、データを入れる入れ物ができました。
ひとまず、以上でデータベースの設定は完了ですので、開発に入っていきましょう。
なお、データベースは自分で色々な設計ができます。
今は慣れることが先決ですので、難しく考えず、設定してみてください。
ミッションの内容
今回は、登録フォームを作ります。
まずは、サンプルファイルを確認してください。
フォームから「お名前」「年齢」「スキル」の3種類を登録します。
登録すると、フォームの下に登録データが表示されます。
まず、ソースコードの解説を読み、自分自信で実装してみてください。
どうしても分からない場合は回答ファイルを参考にしましょう。
ソースコードの説明を下記に記載します。
まず一通り目を通して、同時に自分のエディタで試してみてください。
ソースコードの解説
順番にソースコードを見ていきましょう。
今回は、データを登録するためのフォームを作ります。
仕組みはシンプルで、フォームから送信したデータがデータベースに登録され、下に表示されます。
処理の流れとしては、下記のような順番となっています。
- フォームに入力し、送信ボタンを押す。
- 同じページが再度読み込まれる。
- 同時にフォームの入力内容が再読み込みされたページに送られる。
- 送られてきたデータを受け取り、変数に入れる。
- 送られてきたデータに漏れがないか確認。
- OKだったらデータベースに登録。
- 登録された内容を一覧で出力する。
まずは、全体のソースコードを確認してみましょう。
<?php
//データベースに接続
$mysqli = new mysqli("サーバー名", "ユーザー名", "パスワード", "データベース名");
//もしエラーが起きたら、エラー内容が表示されます。
if ($mysqli->connect_errno) {
printf("接続失敗: %s\n", $mysqli->connect_error);
exit();
}
?>
<?php
//フォームから送られてきたデータを各変数で受け取ります。
//$name = $_POST['name']でも受け取れますが、セキュリティ上よくないので、htmlspecialcharsを使います。
//htmlspecialcharsを使うとjsやhtmlを削除してくれるので、悪意あるコードが送られても防御できます。
//これをサニタイズ処理と言います。
$name = htmlspecialchars($_POST['name'], ENT_QUOTES);
$age = htmlspecialchars($_POST['age'], ENT_QUOTES);
$skill = htmlspecialchars($_POST['skill'], ENT_QUOTES);
//変数のいずれかにデータが入っていたら、
if (!empty($name)||!empty($age)||!empty($skill)){
//データベースに登録されます。
$result = mysqli_query($mysqli,"insert into userdata(name,age,skill) VALUES('$name','$age','$skill')");
};
?>
<!-- 普通のHTMLフォームです。 -->
<h1>登録フォーム</h1>
<!--methodをpostにすると、submitを押した時に、actionで指定したリンク先にフォームのデータが投げられます。-->
<!--投げられたデータはお名前の場合$_POST['name']で受け取れます。-->
<form method="post" action="index.php">
<input type="text" name="name" placeholder="お名前" /><br/>
<input type="text" name="age" placeholder="年齢" /><br/>
<input type="text" name="skill" placeholder="スキル" /><br/>
<input type="submit" name="submitBtn" value="登録" />
</form>
<?php
//データベースにアクセスします。
$userdata = "select * from userdata order by id DESC";
$userdata = mysqli_query($mysqli,$userdata);
//データが存在する分、繰り返しで表示されます。
while ($userdataArray = mysqli_fetch_assoc($userdata)) {
echo $id = $userdataArray["id"];
echo ",";
echo $name = $userdataArray["name"];
echo ",";
echo $age = $userdataArray["age"];
echo ",";
echo $skill = $userdataArray["skill"];
echo "<br>";
};
?>
このような流れとなります。
次に、それぞれ、細かく見ていきましょう。
<h1>登録フォーム</h1>
<form method="post" action="index.php">
<input type="text" name="name" placeholder="お名前" /><br/>
<input type="text" name="age" placeholder="年齢" /><br/>
<input type="text" name="skill" placeholder="スキル" /><br/>
<input type="submit" name="submitBtn" value="登録" />
</form>
HTMLに関しては、特に何の変哲もないformです。
お名前、年齢、スキルをinputで入力し、submitを押すと画面が自動で更新されます。
formにpostと設定してあることで、更新後の画面に入力したデータが投げられます。
ここまでは、HTMLの基本機能です。
そして、下記のソースコードでpostされたデータを更新後の画面で受け取ります。
$name = htmlspecialchars($_POST['name'], ENT_QUOTES);
$age = htmlspecialchars($_POST['age'], ENT_QUOTES);
$skill = htmlspecialchars($_POST['skill'], ENT_QUOTES);
上記のソースコードで、各変数にそれぞれのデータを格納します。
なお$name = $_POST[‘name’]でもデータは取得できます。
ではなぜ、わざわざhtmlspecialchars(〜〜〜, ENT_QUOTES);で囲ってあるのでしょう。
理由は、セキュリティを強化することが出来るからです。
悪い人たちは、セキュリティの弱いフォームを使って悪さをしようとします。
例えば、javascriptなどで妙なプログラムを送り、サイトを壊されたりする可能性があるのです。
ですので、プログラミングに使うようなソースコードを無害な文字列に変換し、プログラムとして安心な状態にする必要があります。
そんな処理をサニタイズと言い、htmlspecialcharsは受け取ったデータをサニタイズしてくれるのです。
データの受け渡しにサニタイズは必要不可欠な処理です。
データベースとの接続
サニタイズを行うと同時に、データベースと接続します。
普段鍵がかかっているデータベースの扉を一時的に空けるイメージです。
これでデータをやり取りできるようにします。
<?php
$mysqli = new mysqli("サーバー名", "ユーザー名", "パスワード", "データベース名");
if ($mysqli->connect_errno) {
printf("接続失敗: %s\n", $mysqli->connect_error);
exit();
}
?>
サーバー名、ユーザー名、パスワード、データベース名を入力してください。
その下のif文は、もし接続が失敗した場合、エラーを出すための処理です。
ここでエラーが出る場合、大抵データベースの接続情報が間違っているケースが大半になります。
エラーが出たら、接続情報を確認してみてください。
ひとまず、上記の処理で、データベースの扉は開いたはずです。
これで、データベースとデータをやり取りできます。
PDO形式で接続する
実は、データベースを接続する方法には2種類あります。
1つが今、ご説明させて頂いたmysqli方式。
そしてもう1つが、PDO方式です。
少し前まではmysqli方式が主流でしたが、今ではPDO形式が主流で使われています。
なぜなら「どのデータベースでも使える」というのが理由の1つ。
データベースにも基本となる種類があり、一般的にはmysqlというデータベースが使われます。
ただ、他にもoracleやMaria DBのように、いくつか種類があるのです。
それぞれデータベースへの接続方法が異なるのですが、PDOだと変更する必要がありません。
また、整理されているので見やすい、というのもポイントです。
では、先程のデータベース接続のコードをPDO形式に書き換えてみましょう。
こうなります。
<?php
$dsn = 'mysql:dbname=データベース名;host=サーバー名;
try{
$dbh = new PDO($dsn, ユーザー名, パスワード);
}catch (PDOException $e){
print('Error:'.$e->getMessage());
die();
}
?>
書き方自体は、そんなに変わりませんね。
日本語で書いてある部分だけ、サーバーごとに書き換えましょう。
データベースにデータを保存する
では、いよいよ、データベースにデータを保存していきましょう。
<?php
if (!empty($name)||!empty($age)||!empty($skill)){
//データベースに登録
$result = mysqli_query($mysqli,"insert into userdata(name,age,skill) VALUES('$name','$age','$skill')");
};
?>
まずif文で、$name、$age、$skillのいずれかにデータが入っているかどうかを判別します。
もし1つでも入っていれば、if文の中の処理が実行されるわけですね。
なお、比較演算子「||」は「または」という意味で、使われます。
if文の項目で出てきましたね。
そして、データを「mysqli_query」でデータベースに挿入します。
一行で書くと、何が書かれているか分かりづらいですが、下記のようになります。
$result = mysqli_query($mysqli,"insert into テーブル名(カラム1,カラム2,カラム3) VALUES('変数1','変数2','変数3')");
なお、insert into〜と書いてあるダブルクオーテーション内の文章をsql文と呼びます。
データベースにデータを書き込んだり、呼び出したりするときに使う記法ですね。
上記のルールで書き換えることで、自在に希望するテーブルにデータを保存できます。
PDOの場合
PDO形式でinsertする場合は下記のように記述します。
if (!empty($name)||!empty($age)||!empty($skill)){
$stmt = $dbh->prepare("INSERT INTO user (name,age,skill) VALUES (:name, :age, :skill)");
$stmt->execute(array(':name' => $name,':age' => $age,':skill' => $skill));
};
$dbh->prepareの()内にSQL文が書いてあるのですが、少し書き方が異なります。
直接、データを持つ変数が指定されていませんよね。
では、どこでデータを持つ変数が指定されているかと言えば、すぐ下の$stmt->executeの中です。
‘:name’ => $nameを見てください。
これは「$dbh->prepareで指定した、:nameの中に変数$nameを格納してください」という意味です。
つまり、直接データベースにデータを入れるのではなく、一度、executeを通しています。
一体、なぜこんな面倒な方法を行うのでしょうか?
わかりやすい1つの理由が、セキュリティです。
例えば、検索機能を作るとしましょう。
検索機能はユーザーが打った文字列で検索をかけます。
つまり、ユーザーが打った文字列がSQL文に直接渡されることになります。
では、もし文字列の中に別のSQL文が紛れ込んでいたらどうなるでしょう。
書き方によっては、別の命令を実行させることもできます。
例えば、すべてのデータを消す、みたいな文章を差し込まれたら?
もちろん、データが消えてしまいます。
なので、一度executeを通すことでSQL文を無害化して渡します。
この方法をプリペアドステートメントと言います。
セキュリティに関しては、別の項目で記載したので、ぜひ、読んでみてください。
ひとまず、これで書き込み可能です。
ぜひ、データベースに色々なテーブルやカラムを作り、試してみてください。
データベースの出力
最後に、保存したデータを出力します。
<?php
$userdata = "select * from userdata where skill = 'WEBデザイナー' order by id DESC";
$userdata = mysqli_query($mysqli,$userdata);
?>
まず「$userdata = “select * from テーブル名 where skill = ‘WEBデザイナー’ order by id DESC”;」でデータを呼び出す準備をします。
今回は、skillがWEBデザイナーのデータだけを呼び出します。
それが「where skill = ‘WEBデザイナー’」の部分です。
もしすべてのデータを呼び出したい場合、この部分は不要です。
最後の「order by id DESC」は、データを呼び出す順番で、idの数字順で降順か昇順かを意味しています。
一覧でデータを表示する時に、逆の順番で表示することが出来るんですね。
なお、こちらの「id」は、データベースを作った際に作ったカラム「id」を意味します。
なお、この時点ではまだ、データベースからデータは呼び出されていません。
命令の形を作り、実行の準備をしているだけです。
実行する前に、もう1つ準備があります。
それが「$userdata = mysqli_query($mysqli,$userdata);」です。
データベース情報と指定したsql文をつなぎ合わせています。
これで準備が整いました。
準備したsqlを実行します。
<?php
while ($userdataArray = mysqli_fetch_assoc($userdata)) {
echo $id = $userdataArray["id"];
echo ",";
echo $name = $userdataArray["name"];
echo ",";
echo $age = $userdataArray["age"];
echo ",";
echo $skill = $userdataArray["skill"];
echo "<br>";
};
?>
上記の処理で、呼び出したデータを出力します。
受け取ったデータを$userdataArrayに配列として入れ、while文で配列の中身を順番に出力します。
あとはechoで実際に表示すれば、これでデータベースの中身を出力することが可能です。
PDOでの書き方
もちろん、今回の命令もPDOで書くことができます。
//データベースにSQL文を指定する。
$stmt = $dbh->prepare("SELECT * FROM userdata where skill = :userskill order by id DESC");
//whereに指定したuserskillにWEBデザイナーという値を渡す。
$stmt->execute(array(':userskill' => 'WEBデザイナー'));
//呼び出したデータを配列で返す。
$result = $stmt->fetchAll();
//配列に入ったデータを出力する。
foreach ($result as $userdata) {
echo $id = $userdata["id"];
echo ",";
echo $name = $userdata["name"];
echo ",";
echo $age = $userdata["age"];
echo ",";
echo $skill = $userdata["skill"];
echo "<br>";
};
このような流れになっています。
今回、mysqliとPDO、2つ説明しましたが、基本はPDOを使いましょう。
ざっくりでも理解して頂ければ今回はOKです。
やっているうちに分かるようになりますので、もし理解できなくても悲観する必要はありません。
とにかく動くまでは頑張って、ざっくり把握したら次に進んでいきましょう。
次回は入力したデータを変更したり、消す処理を書いていきます。