logo

パレット - カラフルに🎨

Palette — ビジュアルページビルダー、デザインの専門知識は不要です。

ライブデモ パレットをダウンロード

Scroll

PHP レッスン — レッスン 3.2 — MySQL DB の操作。INSERT INTO によるデータの挿入。SELECT によるデータの抽出

08/12/2019, by Ivan

前のレッスンでは、サイト用のテーブルを作りました。このレッスンでは、テーブルを改良し、いよいよ DB を扱い始めます。そこにデータを入力し、テーブルからそのデータを取り出します。難しいことは特にないと思うので、始めましょう。

まず、messages テーブルを改良することを提案します。今はデータ用のフィールドがありますが、レコードに番号を付けるためのフィールドがもう 1 つ必要です。Drupal の DB を開くと、node テーブルには nid フィールドがあり、それでノードに番号を付けています。私たちの messages テーブルでも同じようにする必要があります。

phpMyAdmin(Denwer では http://localhost/tools/phpmyadmin)に入り、テーブルを編集しましょう。図のように、テーブルの先頭にもう 1 つ列を追加します:

 PhpMyAdmin

列を mid(message id)と名付け、データ型は INT(整数)、長さは 11 文字とします。また、AUTO_INCREMENT にチェックを入れます。これはこの列での自動採番を意味します。そして Index フィールドに primary を設定します。これは、これが私たちのテーブルの主キーであることを意味します。

PhpMyAdmin mid column

覚えていれば、テーブルを作成するために simpleCMS クラスの別のメソッドを作りました。このメソッドが mid フィールドも追加するよう、今、その動作を変更する必要があると思います。messages テーブルに入り、export をクリックしてください:

PhpMyAdmin export

テーブルのエクスポートページに行き着きます。エクスポートは、テーブルの作成と編集のための SQL クエリの形で行われます。phpmyadmin でテーブルを変更すると、その作成の SQL クエリを後でコピーできて、とても便利です。

エクスポートページでは、すべてをデフォルトのままにして OK を押します。PhpMyAdmin は、ブラウザに直接、またはファイルの形で sql クエリを出力します。どちらでも構いません。次のコードをコピーする必要があります:

PhpMyAdmin table

そこにあるバッククォート(斜めの引用符)に注目してください。phpMyAdmin ではこれが使われます。php では通常の単一引用符を使えます。テキストを buildDB() メソッドにコピーします:

  public function buildDB(){
    $sql = "CREATE TABLE IF NOT EXISTS 'messages' (
			  'mid' int(11) NOT NULL AUTO_INCREMENT,
			  'title' varchar(150) DEFAULT NULL,
			  'bodytext' text,
			  'created' varchar(100) DEFAULT NULL,
			  PRIMARY KEY ('mid')
			) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1";

    return mysql_query($sql);
  }

では、これがどう動作するか確認しましょう。messages テーブルを削除しましょう。

PhpMyAdmin drop table

削除を確認します。これで、サイトで index.php を実行すると buildDB() メソッドが起動し、テーブルが再び作成されるはずです。

  public function buildDB(){

$sql = "CREATE TABLE Messages
(
mid int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(mid),
title varchar(15),
bodytext text,
created  int(11)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1";

    $result = mysql_query($sql);
    print_r($result);
  }

では index.php を実行すると、以前と同じように Messages テーブルが現れます。

INSERT INTO 挿入クエリ

データベースが作られ、DB を使ってメッセージを記録・出力するメソッドを実装する準備がすべて整いました。DB への記録から始めましょう。では write() メソッドを開いて、変更していきます。

テーブルへの記録は、INSERT INTO 演算子を使って次のように行います:

  public function write($p) { // メッセージ記録のメソッド
    $sql = 'INSERT INTO Messages (title, bodytext, created) VALUES ("'. $p["title"] . '", "' . $p["bodytext"] . '", ' . time() . ')';
    return mysql_query($sql);
  } 

では、値が正確にどう挿入されるか見てみましょう。先に述べたように、挿入の SQL クエリは INSERT INTO 演算子から始まり、次にテーブル名 Messages が来ます。テーブル名の後に、どの列に値を挿入するかを書きます。mid は書かないことに注目してください。各新規レコードで自動インクリメント(1 ずつの加算)を設定したので、その値は MySQL によって自動的に設定されるからです。次に VALUES(値)演算子が来て、その後にテーブルの各列の値を書きます。しかも、列の順序と値の順序は一致していなければならず、値と列の数も同じでなければなりません。

値に文字列表現を挿入する必要がある場合は、引用符を使います。しかも、これらの引用符が、SQL クエリ全体を包む引用符と異なるように気をつける必要があります。また、SQL クエリに変数を挿入するときに混乱しないでください。sql クエリのテキスト部分を単一引用符で包む場合、変数から出力される文字列は二重引用符で包む必要があります。例えばここでは:

"'. $p["title"] . '"

 引用符の順序は次のとおりです:二重、単一、ドット、変数、ドット、単一、二重。

1 つの例で今のところ十分だと思います。この後さらに例が出てくるので、うまく説明できずすぐに理解できなくても落ち込まないでください。それより、テーブルにいくつかレコードを作りましょう。そのために、write() メソッドのコードを、上で示したものに置き換えてください。

SELECT 抽出クエリ

いくつか行を作り、phpmyadmin で見てみました:

PhpMyAdmin Browse

これで、display_public() メソッド(こちらも変更します)を使って、これらのレコードを出力できます。テーブルからの抽出は SELECT 演算子を使って行います。簡単な選択から始めましょう:

  public function display_public() { // メッセージ出力のメソッド
    $content = '';

	$sql = 'SELECT * FROM Messages'; // 抽出クエリ
	$result = mysql_query($sql);  // 抽出クエリの実行結果を変数に保存する

	while($row = mysql_fetch_array($result)){ // 抽出クエリの変数は、特別な関数 mysql_fetch_array() で処理する必要がある
	  print '<div class="post">'; // レコードを包む div
	  print '<span class="time">#' . $row['mid'] . ' ' . date('d-m-Y', $row['created']) . '</span><h2>' . $row['title'] . '</h2>'; 	// 時刻とタイトルを出力する
	  print '<p>' . $row['bodytext'] . '</p>'; // メッセージのテキストを出力する
	  print '</div>'; // 包む div の終わり
	}

	$content .= '<p><a href="/index.php?admin=1">メッセージを追加</a></p>';
    return $content;
  }

display_public() メソッドの実装を完全に置き換えました。これで、すべてのレコードが DB から出力されます。では、この例を見ていきましょう。抽出クエリは SELECT 演算子から始まり、次に * (アスタリスク)が来ます。これは、テーブルの各行のすべてのフィールドを選びたいという意味です。もしこう書けば:

$sql = 'SELECT mid,title FROM Messages'; // 抽出クエリ
$result = mysql_query($sql);

これは、各行から mid と title だけを選び、bodytext と created は不要という意味になります。

次に * の後に FROM 演算子が来て、どのテーブルから選ぶかを指定します。 

抽出クエリに対する mysql_query() 関数の実行結果は、変数に記録する必要があります(私たちの場合は $result 変数)。後でこの変数を mysql_fetch_array() 関数で処理する必要があるからです。

抽出クエリを行って 3 つのレコードを得たとします。mysql_fetch_array() 関数は、各呼び出しの後に 1 つずつ配列を順に形成できるようにします。つまり、最初の呼び出しでは 1 行目の配列を、2 回目の呼び出しでは 2 行目の配列を得る、という具合です。行が尽きると、mysql_fetch_array() 関数は配列ではなく false 値を返します。ですからこの場合、while ループ(条件が満たされる間、動作を行う)を使えます。これにより、テーブルのすべてのレコードに対して同じ動作を実行できます。こうして、条件が満たされる間、各レコードをループします。

初めての理解は難しいかもしれませんが、時が経つにつれ SQL クエリを書くのに慣れてきます。演算子はそれほど多くないので、すぐに覚えられます。

抽出クエリ、ORDER BY による並べ替え 

ORDER BY 演算子を使って抽出の順序を指定することもできます。デフォルトでは昇順に設定されます。例えば:

$sql = 'SELECT * FROM Messages ORDER BY mid';

こうして、抽出クエリを mid の昇順に並べ替えます。降順に並べ替えることもでき、そのためにはもう 1 つの追加演算子 DESC を使います。

$sql = 'SELECT * FROM Messages ORDER BY mid DESC';

ご覧のとおり、とても簡単です。降順に DESC を使うなら、昇順には ASC を使います:

$sql = 'SELECT * FROM Messages ORDER BY mid ASC';

もっとも、昇順の並べ替えはデフォルトで使われます。

抽出クエリ、WHERE 条件

並べ替えのほかに、WHERE 演算子を使って抽出に条件を設定し、抽出クエリをフィルタリングできます:

$sql = 'SELECT * FROM Messages WHERE mid<3 ORDER BY mid DESC';

 こうして、もちろんテーブルにそうしたレコードがあれば、最初の 2 つのレコード(mid=1 と mid=2)を出力します。複数の条件を結ぶために、AND(かつ)や OR(または)演算子も使えます。AND を置けば両方の条件が満たされる必要があり、OR を置けばどちらか一方の条件が満たされれば十分です。

$limit_time = time() - 3600; // 1 時間前の時刻
$sql = 'SELECT * FROM Messages WHERE mid<3 AND created>' . $limit_time . ' ORDER BY mid DESC'; // 抽出クエリ

 こうして、レコードが 1 時間前より新しく作られたという追加条件も課します。抽出クエリは今のところ十分だと思うので、次のレッスンに移りましょう。