Web開発でよく使われている「PHP」「MySQL」はご存じでしょうか。
今やWeb開発をするのに不可欠と言ってもよい「PHP」「MySQL」ですが、他のプログラミング言語と比べて仕様や文法が分かりやすいことから、プログラミング未経験の場合に、まずは「PHP」と「MySQL」から習得していこう、と考えている方も多いのではないでしょうか。
今回は、そういった方を対象に「PHP MySQL入門」と題して、PHP+MySQLデータベース環境の構築方法を紹介していきます。
目次
PHP MySQL 入門 事前知識
PHP・MySQLとは?
PHPとは正式名称を「PHP: Hypertext Preprocessor」といい、ユーザーが入力した情報やアクセスした時間帯などに応じて表示される内容が変わる「動的コンテンツ」を作成することができるプログラミング言語です。
PHPを使いこなせば、「お問い合わせフォーム」などの動的なコンテンツを実装することが可能となります。
また、MySQLと呼ばれるオープンソースのデータベース管理システムとの相性がよく、PHP+MySQLの組み合わせで、ブログや掲示板など、様々なWebサイトが構築されています。
特にブログは「Wordpress」のようなCMS(Contents Management System:コンテンツマネージメントシステム)を使った「ブラウザ上で記事の追加や更新ができるもの」で運用されるものが主流となっており、PHPとMySQLはWebサイトの開発にかかせないものとなっています。
PHP・MySQLを学習する環境
PHPは他のプログラム言語と比べて習得しやすい言語と言われており、実際のところ、PHPでホームページを作成するスキルがあればPHP言語を習得したも同然と言ってよいでしょう。
ですが、MySQLの習得となると「ローカル環境にWebサーバを構築し、コマンドラインでMySQLをインストールして・・・」と学習する環境を構築する時点からハードルが高いという印象をお持ちではないでしょうか。
そこで、今回の記事では、ローカル環境に学習する環境を構築するのではなく、無料のレンタルサーバーを使って学習していく方法を紹介したいと思います。
MySQLが使えるレンタルサーバーを使えば面倒なWebサーバーの構築やMySQLの環境を自分で作業する必要がなく、学習する効率が格段にアップしますので、以下の手順に従ってPHP+MySQLの環境を構築していきましょう。
XFreeのPHP・MySQLサーバ
MySQLが使えるレンタルサーバーはいくつかありますが、今回の記事では「XFree」を使います。
まずは、以下のURLからユーザー登録し、サーバーをレンタルしてください。
レンタルサーバーの申し込み手順は以下のURLに記載されていますので、そちらを参考にしながら設定するとよいでしょう。
https://www.xfree.ne.jp/manual/man_order_user.php
「PHP・MySQL」の「利用を開始する」のボタンをクリックすることで、準備は完了です。
ユーザーIDとパスワードを入力し、管理パネルにログインしましょう。
PHP MySQL 入門 データベースの作成
それでは早速、レンタルサーバー上に、MySQLのデータベースを作成していきたいと思います。
MySQLデータベースの作成
XFreeではサーバー管理パネルのGUI操作(画面上のアイコンやボタンクリックによる操作)によってデータベースを作成することができます。
手順としては「MySQL追加」のタブを選択し、画面のようにデータベース名を入力することで作成します。
XFreeのデータベース名は「(サーバーID)_(任意の文字列)」の名前でデータベースを作成することになります。
ここでは「(サーバーID)_db」という名前でデータベースを作成しました。
MySQLユーザ設定
データベースを作成したら、データベースにアクセスするためのユーザーを登録する必要があります。
「MySQLユーザ設定」のタブから画面のようにユーザー名とパスワードを入力することで作成します。
MySQL情報
データベースとユーザーを作成したら、「MySQL一覧」タブでMySQL情報を確認しておきましょう。
以下の画面のように設定されていれば準備完了です。
この画面の中の以下の項目については、後述するプログラミングの説明の際に必要となってきますので、どこを見れば確認できるか把握しておいてください。
- データベース名
- ユーザー名
- MySQLホスト名
phpMyAdmin
MySQLに作成したデータベースの操作は「phpMyAdmin」という管理ツールを使って操作します。
XFreeでphpMyAdminを使う場合は管理パネルの「phpMyAdmin」タブからアクセスすると、以下の画面が表示されます。
作成したデータベースが左側に表示されていることを確認しておきましょう。
テーブルの作成
データベースを作成した後は、データが格納される「テーブル」を作成していくことになります。
「phpMyAdmin」を開くと先ほど作成した名前のデータベースが一覧に表示されています。
データベースをクリックして以下の画面に遷移することでテーブルが作成可能です。
テーブルを作成する際、あらかじめ「どんなデータが格納されるのか」といったことを想定し「何列のフィールドを用意しておくべきか」を設計しておく必要があります。
今回は、学習用ということで会員制のWebサイトを構築するつもりで「ユーザーID」「ユーザー名」「パスワード」といったカラムのある「t_user」テーブルを作成してみましょう。
作成する手順は以下の通りです。
- データベース名をクリック
- テーブル名の欄に「t_user」を入力
- フィールド数の欄に「3」を入力
- 「実行」ボタンをクリック
なお、テーブル名に使われる文字数は64byteまでという制限がありますので、テーブルの名前は、あまり長くなりすぎないように注意しましょう。
フィールドの設定
テーブル名を作成した後は、カラムの「名前」や、どういった型のデータが入るのかの「種別」などを設定する「フィールド設定」画面に遷移します。
今回は詳細な説明は省きますので、以下のように設定してください。
フィールド | 種別 | 長さ | その他 |
---|---|---|---|
t_user_id | int | 11 | auto_increment・主キー |
t_user_name | VARCHAR | 50 | |
t_user_password | VARCHAR | 100 |
設定後は以下の画面のような構造となります。
データの挿入
作成したテーブルにデータを挿入する場合はphpMyAdminの「挿入」タブから実施します。
以下の画面の「値」の欄に挿入したいデータを入力していくことになるので、直感的に挿入することができると思います。
実際にデータベースを運用する場合、この画面で1件1件データを登録していくのは現実的ではありませんが、今回は学習用ということで画面のようにデータを挿入してみてください。
登録した結果は以下のようになります。
PHP MySQL 入門 phpファイルの作成
データベースを作成し、テーブルへのデータ登録が完了しましたので、早速、PHPを使ってデータベースにアクセスしてみましょう。
ここでは、ユーザー名を検索して「t_user_id」や「t_user_password」を表示せるWebページの作り方を紹介していきたいと思います。
PDOを使ったDB接続
PHPを使ってMySQLにアクセスする方法はいくつかありますが、今回は最もベターな方法である「PDO」を使って接続する方法を紹介します。
「PDO」とは「PHP Data Object」の略称で、PHP5.1.0以降のデータベース接続クラスのことですが、今のところは「PDOを使えばMySQLに接続できるんだな」といった程度にとらえていただければOKです。
プログラミング
それでは、いよいよPHPを使ったプログラミングの説明に移ります。
まずはテキストエディタなどで「Output.php」ファイルを作成し、以下のプログラミングコードを記述してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
<?php //データベース情報の指定 $db['dbname'] = "◯◯◯◯"; // データベース名 $db['user'] = "◯◯◯◯"; // ユーザー名 $db['pass'] = "◯◯◯◯"; // ユーザー名のパスワード $db['host'] = "◯◯◯◯"; // DBサーバのURL //エラーメッセージの初期化 $errorMessage = ""; //フラグの初期化 $o = false; //検索ボタンが押された時の処理 if (isset($_POST["search"])) { //入力チェック if (empty($_POST["username"])) { $errorMessage = '名前が未入力です。'; } if (!empty($_POST["username"])) { $o = true; //入力したユーザ名を変数に格納 $username = $_POST["username"]; //dsnを作成 $dsn = sprintf('mysql:host=%s; dbname=%s; charset=utf8', $db['host'], $db['dbname']); try { //PDOを使ってMySQLに接続 $pdo = new PDO($dsn, $db['user'], $db['pass'], array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION)); //SQLを作成 $sql = "SELECT * FROM t_user WHERE t_user_name = '".$username."'"; //$pdoにあるqueryメソッドを呼び出してSQLを実行 $stmt = $pdo->query($sql); //出力結果を$rowに代入 $row = $stmt->fetchAll(); //出力結果をそれぞれの配列に格納 $user_id = array_column($row,'t_user_id'); $user_name = array_column($row,'t_user_name'); $user_pass = array_column($row,'t_user_password'); } catch (PDOException $e) { $errorMessage = 'データベースエラー'; } } } ?> <!doctype html> <html> <head> <meta charset="UTF-8"> <title>検索</title> </head> <body> <h1>出力画面</h1> <form id="outputForm" name="outputForm" action="" method="POST"> <p>検索フォーム</p> <div><font color="#ff0000"><?php echo htmlspecialchars($errorMessage, ENT_QUOTES); ?></font></div> <label for="username">名前</label> <input type="text" id="username" name="username" placeholder="名前を入力" value="<?php if (!empty($_POST["username"])) {echo htmlspecialchars($_POST["username"], ENT_QUOTES);} ?>"> <input type="submit" id="search" name="search" value="検索"> </form> <div> <?php if(count($user_id) > 0){ echo '<p>検索結果<br>'; echo '- - - - - - - - - - - - - - - - - - - - - - - - </p>'; for ($i=0;$i<count($user_id);$i++){ echo '<div>ユーザーID:'.$user_id[$i].'</div>'; echo '<div>名前:'.$user_name[$i].'</div>'; echo '<div>パスワード:'.$user_pass[$i].'</div>'; echo '<p>- - - - - - - - - - - - - - - - - - - - - - - - </p>'; } }else{ if($o == true){ echo '<p>検索結果</p>'; echo '<div>該当するデータはありません</div>'; }else{ } } ?> </div> </body> </html> |
このプログラムをWebサーバーにアップし、ブラウザでアクセスします。
「名前」を検索することで「ユーザーID」と「名前」「パスワード」が出力されれば成功です。
プログラムの内容についてですが、基本的にはコード内のコメントでどういった処理をしているのかを記載していますので、ここでは特に、以下の3点について言及いたします。
$pdo = new PDO()
30行目の処理は、記述したデータベースの接続設定を使ってデータベースにアクセスし、PDOクラスのインスタンス(実体)を生成しています。
クラスやインスタンスの説明は割愛しますが、この処理により、PDOクラスが保有しているメソッドを呼び出すことができるようになります。
$stmt = $pdo->query()
36行目の処理はインスタンス「$pdo」が保有している「query」メソッドを呼び出し、SQL文の実行結果を取得しています。
この処理によって「$stmt」にSQLの実行結果が格納されることになります。
$row = $stmt->fetchAll();
39行目の処理は取得したデータの全件を$rowに代入しています。
この処理を行うことで、各カラムごとのデータを配列に格納できるようになります。
サンプルプログラムの問題点
PHPでMySQLデータベースを操作する基本的な流れは以上のとおりですが、このプログラムにはいくつか問題点があります。
たとえば、検索ボックスに以下のような文字列「’ OR ‘1’=’1」を入力して検索してみてください。
おそらく、「t_user」テーブルに登録されている全てのデータが出力されてしまうのではないでしょうか。
これでは全てのユーザーのIDとパスワードが簡単に他人に知られてしまうことになり、安全に運用することができません。
SQLインジェクション
結論から言うと、このようなWebサイト上の入力フォームに「SQL文を含む文字列」を入力して情報を盗み取ったり、データを改ざんしたりする攻撃のことを「SQLインジェクション」と呼び、実際に様々な被害が報告されています。
今回のプログラムの場合、36行目の「queryメソッド」で実行しているSQL文の条件指定(WHERE句)に「$username」という変数を使用していることが原因で、そこに「’ OR ‘1’ = ‘1」と入力した場合、以下のようなSQL文が実行され、結果的に全てのデータが出力されてしまいます。
1 |
SELECT * FROM t_user WHERE t_user_name = '' OR '1' ='1' |
このような問題を防ぐために「Output.php」は以下のように修正しておく必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
<?php //データベース情報の指定 $db['dbname'] = "◯◯◯◯"; // データベース名 $db['user'] = "◯◯◯◯"; // ユーザー名 $db['pass'] = "◯◯◯◯"; // ユーザー名のパスワード $db['host'] = "◯◯◯◯"; // DBサーバのURL //エラーメッセージの初期化 $errorMessage = ""; //フラグの初期化 $o = false; //検索ボタンが押された時の処理 if (isset($_POST["search"])) { //入力チェック if (empty($_POST["username"])) { $errorMessage = '名前が未入力です。'; } if (!empty($_POST["username"])) { $o = true; //入力したユーザ名を変数に格納 $username = $_POST["username"]; //dsnを作成 $dsn = sprintf('mysql:host=%s; dbname=%s; charset=utf8', $db['host'], $db['dbname']); try { //PDOを使ってMySQLに接続 $pdo = new PDO($dsn, $db['user'], $db['pass'], array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION)); //SQLを作成 $sql = "SELECT * FROM t_user WHERE t_user_name = ?"; //$pdoにあるexecuteメソッドを呼び出してSQLを実行 $stmt = $pdo->prepare($sql); $stmt->execute(array($username)); } catch (PDOException $e) { $errorMessage = 'データベースエラー'; } } } ?> <!doctype html> <html> <head> <meta charset="UTF-8"> <title>検索</title> </head> <body> <h1>出力画面</h1> <form id="outputForm" name="outputForm" action="" method="POST"> <p>検索フォーム</p> <div><font color="#ff0000"><?php echo htmlspecialchars($errorMessage, ENT_QUOTES); ?></font></div> <label for="username">名前</label> <input type="text" id="username" name="username" placeholder="名前を入力" value="<?php if (!empty($_POST["username"])) {echo htmlspecialchars($_POST["username"], ENT_QUOTES);} ?>"> <input type="submit" id="search" name="search" value="検索"> </form> <div> <?php if($stmt){ $ct = 0; echo '<p>検索結果<br>'; echo '- - - - - - - - - - - - - - - - - - - - - - - - </p>'; foreach($stmt as $row){ if($ct == 0){ } echo '<div>ユーザーID:'.$row['t_user_id'].'</div>'; echo '<div>名前:'.$row['t_user_name'].'</div>'; echo '<div>パスワード:'.$row['t_user_password'].'</div>'; echo '<p>- - - - - - - - - - - - - - - - - - - - - - - - </p>'; $ct++; } if($ct ==0){ echo '<div>該当するデータはありません</div>'; } }else{ } ?> </div> </body> </html> |
以上のように修正しておけば、とりあえずは安心でしょう。
ですが、同姓同名の人がいた場合にはどうでしょうか。また、名前を検索してパスワードが表示されてしまう仕様は問題ないのでしょうか。
実際にWebシステムを構築する場合は、処理を理解するだけでなく、こういったことも考えながら構築していく必要があります。
掲載したプログラミングコードを参考に、自分ではどんなデータベースシステムを構築したいのかを考えながら、じっくりと理解を深めていただければと思います。
PHP MySQL 入門 ユーザー認証機能を作ってみよう
それでは最後に、今回学習した内容を応用させて、簡単な会員制サイトの「ユーザー認証機能」を作ってみましょう。
ログイン画面の作成
ログイン画面を構成する「Login.php」を作成し、以下のコードを記述してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
<?php $db['dbname'] = "◯◯◯◯"; // データベース名 $db['user'] = "◯◯◯◯"; // ユーザー名 $db['pass'] = "◯◯◯◯"; // ユーザー名のパスワード $db['host'] = "◯◯◯◯"; // DBサーバのURL //エラーメッセージの初期化 $errorMessage = ""; //ログインボタンが押された時の処理 if (isset($_POST["login"])) { //入力チェック if (empty($_POST["userid"])) { $errorMessage = 'ユーザーIDが未入力です。'; } else if (empty($_POST["password"])) { $errorMessage = 'パスワードが未入力です。'; } if (!empty($_POST["userid"]) && !empty($_POST["password"])) { $userid = $_POST["userid"]; $password = $_POST["password"]; $dsn = sprintf('mysql:host=%s; dbname=%s; charset=utf8', $db['host'], $db['dbname']); try { $pdo = new PDO($dsn, $db['user'], $db['pass'], array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION)); $stmt = $pdo->prepare('SELECT * FROM t_user WHERE t_user_id = ?'); $stmt->execute(array($userid)); if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { if($password == $row['t_user_password']){ header("Location: Main.php"); exit(); } else { $errorMessage = 'ログインできませんでした'; } } else { $errorMessage = 'ログインできませんでした'; } } catch (PDOException $e) { $errorMessage = 'データベースエラー'; } } } ?> <!doctype html> <html> <head> <meta charset="UTF-8"> <title>ログイン</title> </head> <body> <h1>ログイン画面</h1> <form id="loginForm" name="loginForm" action="" method="POST"> <p>ログインフォーム</p> <div><font color="#ff0000"><?php echo htmlspecialchars($errorMessage, ENT_QUOTES); ?></font></div> <label for="userid">ユーザーID</label> <input type="text" id="userid" name="userid" placeholder="ユーザーIDを入力" value="<?php if (!empty($_POST["userid"])) {echo htmlspecialchars($_POST["userid"], ENT_QUOTES);} ?>"> <br> <label for="password">パスワード</label><input type="password" id="password" name="password" value="" placeholder="パスワードを入力"> <br> <input type="submit" id="login" name="login" value="ログイン"> </form> </body> </html> <!-- ※1 このプログラムは学習用のためパスワードを暗号化していません。 セキュリティの強度が必要な場合は、このプログラムを使わないでください。 --> |
メインページの作成
ログイン後に表示される「メインページ」を構成する「Main.php」を作成し、以下のコードを記述してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php ?> <!doctype html> <html> <head> <meta charset="UTF-8"> <title>メイン</title> </head> <body> <h1>メイン画面</h1> <p>ようこそ</p> <ul> <li><a href="Login.php">ログイン画面に戻る</a></li> </ul> </body> </html> |
ログインページへのアクセス
ログインページにアクセスすると、以下のような画面が表示されます。
データベースに登録した「ユーザーID(t_user_id)」と「パスワード(t_user_password)」を入力し、「ログイン」ボタンをクリックすることで、ログイン後の画面である「メインページ」に遷移すれば成功です。
このプログラムの問題点
さて、今回作成した「ユーザー認証機能」ですが、多くの問題点があることにお気づきでしょうか。
例えば、データベースに登録されているパスワードが暗号化されておらず、Webサイトの管理者がユーザーのログインパスワードを閲覧できてしまいます。
また、ログイン画面を経由せず、直接メインページのURLにアクセスしてもページの内容が閲覧できてしまうという致命的な欠陥が存在します。
こういった問題を解決するために、データベースに登録する際のパスワードを「ハッシュ関数」で暗号化したり、クライアントとサーバー間の通信を「セッション」で管理したりといった処理を追加していく必要があります。
今回の記事は「データベースへ接続する方法の解説」でいったん区切らせていただきますが、これらの問題点の改善については別の機会に説明したいと考えています。
特に「セッション」の説明については「記事の続き」という形で、今回作成した環境をベースに説明を展開したいと思いますので、そちらも参考にしていただければと思います。
まとめ
いかがでしたか?
今回はPHP+MySQLデータベースの環境を構築する方法を紹介させていただきました。
PHPとMySQLを使ってデータベースの抽出結果をブラウザに出力させることができるようになりましたでしょうか。
SESSIONを使ったユーザー認証機能の実装については別の機会に紹介したいと思っていますので、今後、PHP+MySQLデータベースの環境を構築したくなった時にでも、こちらの記事を思い出していただければ幸いです。