ニュース投稿ツール(MySQL + PDO + Smarty を利用)

トップ > PHP入門 > ニュース投稿ツール(MySQL + PDO + Smarty を利用)

目次

広告

WADAX
安心の365日電話サポート付きレンタルサーバーです。
ロリポップ!
月額263円からのレンタルサーバー。マニュアルも充実しています。

プログラムの概要

「クラスとライブラリの基本」の内容を踏まえて、ニュース投稿ツールを作成してみます。管理者がタイトルと本文を投稿すると一覧に表示される…という、ブログのごく簡単な物です。

記事の表示・登録・編集・削除とひととおりのことができるため、ファイル数が多く難しく感じるかもしれません。ですが、各ファイルとも処理の流れは似た様なものになっています。頑張って読み進めていってください。

プログラムの概要

プログラムの概要

プログラムの概要

テーブルの作成

まずはニュースデータ登録用にテーブルを作成します。今回は以下のようなテーブルを作成するものとします。

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 としています。

これで、ニュースを削除できるようになります。