フリーPHPスクリプト配布サイト。
トップ > PHP入門 > ニュース投稿ツール(MySQL + PDO + Smarty を利用)
「クラスとライブラリの基本」の内容を踏まえて、ニュース投稿ツールを作成してみます。管理者がタイトルと本文を投稿すると一覧に表示される…という、ブログのごく簡単な物です。
記事の表示・登録・編集・削除とひととおりのことができるため、ファイル数が多く難しく感じるかもしれません。ですが、各ファイルとも処理の流れは似た様なものになっています。頑張って読み進めていってください。
まずはニュースデータ登録用にテーブルを作成します。今回は以下のようなテーブルを作成するものとします。
CREATE TABLE articles(
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
detail TEXT,
created DATETIME
);
id
には登録番号を、title
にはタイトルを、detail
には本文を、created
には投稿日時をそれぞれ格納するものとします。また、登録番号は AUTO_INCREMENT PRIMARY KEY
によって連番を作成するようにしています。
このテーブルにデータを登録する場合、実行するSQL文は以下のようになります。
INSERT INTO articles(title, detail, created) VALUES('タイトル', '本文', '2011-01-02 13:40:16');
もしくは、以下のようなSQLでも同様に登録することができます。
INSERT INTO articles VALUES(NULL, 'タイトル', '本文', '2011-01-02 13:40:16');
実際に、何件か記事を登録してみてください。
テーブルを作成できたら、まずは登録内容を一覧表示するPHPを作成します。ファイル名は index.php
としておきます。
<?php
//テンプレート利用準備
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
try {
//データベース接続
$pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$pdo->query('SET NAMES utf8');
//データ検索
$stmt = $pdo->query('SELECT * FROM articles ORDER BY id DESC');
//データ割り当て
$articles = array();
while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
$articles[] = $data;
}
$smarty->assign('articles', $articles);
} catch (PDOException $e) {
exit($e->getMessage());
}
//データベース接続終了
$pdo = null;
//結果表示
$smarty->display('index.html');
?>
ロジックとデザインを分離させるため、最初にSmartyを読み込んでいます。Smartyを使用するため、index.php
と同じフォルダ内に smarty
ディレクトリを作成し、その中にSmartyの libs
フォルダ内にあるファイルとディレクトリをすべてコピーします。テンプレートを格納する場所は templates
、コンパイル済みテンプレートを格納する場所は templates_c
としているので、index.php
と同じフォルダ内に templates
フォルダと templates_c
フォルダを作成しておきます。
その後、PDOでMySQLにアクセスし、articles
テーブルから記事を取得します。取得したデータは直接 echo
で表示せずに、Smartyの assign
メソッドでテンプレートに割り当てます。
最後に、Smartyの display
メソッドでテンプレートを読み込みます。テンプレートのファイル名は index.html
としています。
次に templates
フォルダ内に index.html
を作成し、以下の内容を記述します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ニュース</title>
</head>
<body>
<h1>ニュース一覧</h1>
<ul>
{foreach $articles as $article}
<li><a href="view.php?id={$article.id}">No.{$article.id} {$article.title|escape}</a></li>
{/foreach}
</ul>
<ul>
<li><a href="regist_form.php">登録</a></li>
</ul>
</body>
</html>
$articles
の内容を順に一覧表示しています。また、一覧のタイトルをクリックすると、詳細ページ(view.php
)に移動するようにしています。このページは後ほど作成します。「登録」のリンクをクリックすると新規登録ページ(regist_form.php
)に移動するようにしていますが、このページも後ほど作成します。
これで、index.php
にアクセスすると、投稿フォームの下にメッセージが一覧表示されます。
ニュース一覧のタイトルをクリックすると表示される、ニュース詳細を表示するページを作成します。index.php
と同じフォルダ内に view.php
を作成し、以下の内容を記述します。
<?php
//テンプレート利用準備
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
try {
//データベース接続
$pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$pdo->query('SET NAMES utf8');
//データ検索
$stmt = $pdo->prepare('SELECT * FROM articles WHERE id = :id');
$stmt->bindValue(':id', $_GET['id'], PDO::PARAM_INT);
$stmt->execute();
//データ割り当て
if ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
$smarty->assign('article', $data);
} else {
$smarty->assign('message', '指定されたニュースが見つかりません。');
$smarty->display('error.html');
exit;
}
} catch (PDOException $e) {
exit($e->getMessage());
}
//データベース接続終了
$pdo = null;
//結果表示
$smarty->display('view.html');
?>
PDOでMySQLにアクセスし、articles
テーブルから記事を取得します。取得したデータは、Smartyの assign
メソッドでテンプレートに割り当てます。
最後に、Smartyの display
メソッドでテンプレートを読み込みます。テンプレートのファイル名は view.html
としています。
次に templates
フォルダ内に view.html
を作成し、以下の内容を記述します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ニュース</title>
</head>
<body>
<h1>ニュース詳細</h1>
<h2>No.{$article.id} {$article.title|escape}</h2>
<p>{$article.detail|escape|nl2br}</p>
<p>投稿日時:{$article.created}</p>
<ul>
<li><a href="edit_form.php?id={$article.id}">編集</a></li>
<li><a href="delete_form.php?id={$article.id}">削除</a></li>
</ul>
<ul>
<li><a href="index.php">一覧へ戻る</a></li>
</ul>
</body>
</html>
次に templates
フォルダ内に error.html
を作成し、以下の内容を記述します。これはエラーメッセージを表示する画面として利用します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ニュース</title>
</head>
<body>
<h1>エラー</h1>
<p>{$message}</p>
<ul>
<li><a href="javascript:history.back();">前のページへ戻る</a></li>
</ul>
</body>
</html>
これで、ニュース一覧のタイトルをクリックすると、ニュースの詳細が表示されます。
「登録」のリンクをクリックすると表示される、ニュースを新規に登録するページを作成します。index.php
と同じフォルダ内に regist_form.php
を作成し、以下の内容を記述します。
<?php
//テンプレート利用準備
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
//結果表示
$smarty->display('regist_form.html');
?>
Smartyの display
メソッドでテンプレートを読み込みます。テンプレートのファイル名は regist_form.html
としています。
次に templates
フォルダ内に regist_form.html
を作成し、以下の内容を記述します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ニュース</title>
</head>
<body>
<h1>ニュース登録</h1>
<form action="regist.php" method="post">
タイトル:<br />
<input type="text" name="title" size="30" value="" /><br />
本文:<br />
<textarea name="detail" cols="30" rows="5"></textarea><br />
パスワード:<br />
<input type="password" name="key" size="10" value="" /><br />
<br />
<input type="submit" value="登録する" />
</form>
<ul>
<li><a href="index.php">一覧へ戻る</a></li>
</ul>
</body>
</html>
次に「登録する」ボタンをクリックすると実行される、ニュースを新規に登録する処理を作成します。index.php
と同じフォルダ内に regist.php
を作成し、以下の内容を記述します。
<?php
//テンプレート利用準備
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
//入力内容チェック
if ($_POST['key'] != 'abcd') {
$smarty->assign('message', 'パスワードが違います。');
$smarty->display('error.html');
exit;
}
if ($_POST['title'] == '' or $_POST['detail'] == '') {
$smarty->assign('message', 'タイトルと本文を入力してください。');
$smarty->display('error.html');
exit;
}
try {
//データベース接続
$pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$pdo->query('SET NAMES utf8');
//データ登録
$stmt = $pdo->prepare('INSERT INTO articles(title, detail, created) VALUES(:title, :detail, :created)');
$stmt->bindValue(':title', $_POST['title']);
$stmt->bindValue(':detail', $_POST['detail']);
$stmt->bindValue(':created', date('Y-m-d H:i:s'));
$stmt->execute();
} catch (PDOException $e) {
exit($e->getMessage());
}
//データベース接続終了
$pdo = null;
//結果表示
$smarty->display('complete.html');
?>
PDOでMySQLにアクセスし、articles
テーブルに記事を追加します。
最後に、Smartyの display
メソッドでテンプレートを読み込みます。テンプレートのファイル名は complete.html
としています。
次に templates
フォルダ内に complete.html
を作成し、以下の内容を記述します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ニュース</title>
</head>
<body>
<h1>完了</h1>
<p>作業が完了しました。</p>
<ul>
<li><a href="index.php">一覧へ戻る</a></li>
</ul>
</body>
</html>
これで、ニュースを新規に登録できるようになります。
「編集」のリンクをクリックすると表示される、ニュースを編集するページを作成します。index.php
と同じフォルダ内に edit_form.php
を作成し、以下の内容を記述します。
<?php
//テンプレート利用準備
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
try {
//データベース接続
$pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$pdo->query('SET NAMES utf8');
//データ検索
$stmt = $pdo->prepare('SELECT * FROM articles WHERE id = :id');
$stmt->bindValue(':id', $_GET['id'], PDO::PARAM_INT);
$stmt->execute();
//データ割り当て
if ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
$smarty->assign('article', $data);
} else {
$smarty->assign('message', '指定されたニュースが見つかりません。');
$smarty->display('error.html');
exit;
}
} catch (PDOException $e) {
exit($e->getMessage());
}
//データベース接続終了
$pdo = null;
//結果表示
$smarty->display('edit_form.html');
?>
PDOでMySQLにアクセスし、articles
テーブルから記事を取得します。取得したデータは、Smartyの assign
メソッドでテンプレートに割り当てます。
最後に、Smartyの display
メソッドでテンプレートを読み込みます。テンプレートのファイル名は edit_form.html
としています。
次に templates
フォルダ内に edit_form.html
を作成し、以下の内容を記述します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ニュース</title>
</head>
<body>
<h1>ニュース編集</h1>
<form action="edit.php" method="post">
<input type="hidden" name="id" value="{$article.id}" />
タイトル:<br />
<input type="text" name="title" size="30" value="{$article.title|escape}" /><br />
本文:<br />
<textarea name="detail" cols="30" rows="5">{$article.detail|escape}</textarea><br />
パスワード:<br />
<input type="password" name="key" size="10" value="" /><br />
<br />
<input type="submit" value="編集する" />
</form>
<ul>
<li><a href="view.php?id={$article.id}">記事へ戻る</a></li>
</ul>
</body>
</html>
次に「編集する」ボタンをクリックすると実行される、ニュースを編集する処理を作成します。index.php
と同じフォルダ内に edit.php
を作成し、以下の内容を記述します。
<?php
//テンプレート利用準備
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
//入力内容チェック
if ($_POST['key'] != 'abcd') {
$smarty->assign('message', 'パスワードが違います。');
$smarty->display('error.html');
exit;
}
if ($_POST['title'] == '' or $_POST['detail'] == '') {
$smarty->assign('message', 'タイトルと本文を入力してください。');
$smarty->display('error.html');
exit;
}
try {
//データベース接続
$pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$pdo->query('SET NAMES utf8');
//データ登録
$stmt = $pdo->prepare('UPDATE articles SET title = :title, detail = :detail WHERE id = :id');
$stmt->bindValue(':title', $_POST['title']);
$stmt->bindValue(':detail', $_POST['detail']);
$stmt->bindValue(':id', $_POST['id'], PDO::PARAM_INT);
$stmt->execute();
} catch (PDOException $e) {
exit($e->getMessage());
}
//データベース接続終了
$pdo = null;
//結果表示
$smarty->display('complete.html');
?>
PDOでMySQLにアクセスし、articles
テーブルの記事を更新します。
最後に、Smartyの display
メソッドでテンプレートを読み込みます。テンプレートのファイル名は、先ほど作成した complete.html
としています。
これで、ニュースを編集できるようになります。
「削除」のリンクをクリックすると表示される、ニュースを削除するページを作成します。index.php
と同じフォルダ内に delete_form.php
を作成し、以下の内容を記述します。
<?php
//テンプレート利用準備
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
try {
//データベース接続
$pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$pdo->query('SET NAMES utf8');
//データ検索
$stmt = $pdo->prepare('SELECT * FROM articles WHERE id = :id');
$stmt->bindValue(':id', $_GET['id'], PDO::PARAM_INT);
$stmt->execute();
//データ割り当て
if ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
$smarty->assign('article', $data);
} else {
$smarty->assign('message', '指定されたニュースが見つかりません。');
$smarty->display('error.html');
exit;
}
} catch (PDOException $e) {
exit($e->getMessage());
}
//データベース接続終了
$pdo = null;
//結果表示
$smarty->display('delete_form.html');
?>
PDOでMySQLにアクセスし、articles
テーブルから記事を取得します。取得したデータは、Smartyの assign
メソッドでテンプレートに割り当てます。
最後に、Smartyの display
メソッドでテンプレートを読み込みます。テンプレートのファイル名は delete_form.html
としています。
次に templates
フォルダ内に delete_form.html
を作成し、以下の内容を記述します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ニュース</title>
</head>
<body>
<h1>ニュース削除</h1>
<form action="delete.php" method="post">
<input type="hidden" name="id" value="{$article.id}" />
パスワード:<br />
<input type="password" name="key" size="10" value="" /><br />
<br />
<input type="submit" value="削除する" />
</form>
<ul>
<li><a href="view.php?id={$article.id}">記事へ戻る</a></li>
</ul>
</body>
</html>
次に「削除する」ボタンをクリックすると実行される、ニュースを削除する処理を作成します。index.php
と同じフォルダ内に delete.php
を作成し、以下の内容を記述します。
<?php
//テンプレート利用準備
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
//入力内容チェック
if ($_POST['key'] != 'abcd') {
$smarty->assign('message', 'パスワードが違います。');
$smarty->display('error.html');
exit;
}
try {
//データベース接続
$pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$pdo->query('SET NAMES utf8');
//データ削除
$stmt = $pdo->prepare('DELETE FROM articles WHERE id = :id');
$stmt->bindValue(':id', $_POST['id'], PDO::PARAM_INT);
$stmt->execute();
} catch (PDOException $e) {
exit($e->getMessage());
}
//データベース接続終了
$pdo = null;
//結果表示
$smarty->display('complete.html');
?>
PDOでMySQLにアクセスし、articles
テーブルの記事を削除します。
最後に、Smartyの display
メソッドでテンプレートを読み込みます。テンプレートのファイル名は、先ほど作成した complete.html
としています。
これで、ニュースを削除できるようになります。