19
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

初心者がphp,sqlで簡単ブログ作成(備忘録)

phpとsqlを勉強を始めた初心者です。
今回はhttp://ponk.jp/php/basic/blog さん
の簡単んブログの作成と簡単な解説をして行きたいと思います。
あくまで、phpとsqlにおける解説なので、html,cssの説明は省きます。
下準備として、お使いのサーバーにblogとうフォルダを作成してください。
それから、blog.cssというものを作成しておいておきます。

blog.css
body {
  background-color:#f77;
  font-size: 14px;
  font-family: Helvetica,Arial,sans-serif;
}
a:link, a:visited {color: #a00;}
a:hover {color: #fca;}
p {
  margin: 0;
  padding: 0;
}
h1 {
  margin: 10px 0;
  padding: 0;
  color: white;
  font-size: 32px;
  text-align: center;
}
h2 {
  margin: 0 -20px 10px -20px;
  padding: 5px 10px;
  background-color: #379;
  color: white;
  font-size: 18px;
}
h3 {
  margin: 0 -15px 10px -15px;
  padding: 5px 10px;
  background-color: #a55;
  color: white;
  font-size: 14px;
}
.post {
  width: 500px; 
  margin: 0 auto 15px auto;
  padding: 0 20px 20px 20px; 
  background-color: #fb0; 
}
.comment {
  margin: 10px 0;
  padding: 0 15px 15px 15px; 
  background-color: #da7; 
}
.commment_link {
  text-align: right;
}

sqlをやっている方には以下のようなsql文を作成してください。

CREATE DATABASE blog;

CREATE TABLE post (
  no SERIAL,
  title TEXT,
  content TEXT,
  time TIMESTAMP
);

CREATE TABLE comment (
  no SERIAL,
  post_no INT,
  name TEXT,
  content TEXT,
  time TIMESTAMP
);

INSERT INTO post(no,title,content) VALUES(1,'記事1タイトル','記事1の内容です。');
INSERT INTO post(no,title,content) VALUES(2,'記事2タイトル','記事2の内容です。');
INSERT INTO comment(no,post_no,name,content) VALUES(1,1,'たろう','記事1へのコメントです。');
INSERT INTO comment(no,post_no,name,content) VALUES(2,1,'はなこ','記事1へのコメントです。');

はじめにデータベースのblogを作成しています。それから二つのテーブルを作成しています。一つ目はブログ情報を集めたテーブル、二つ目はブログのコメントを集めたテーブルとなっています。

次に、ブログの表示画面を作ります。

index.php

$pdo = new PDO("mysql:dbname=blog", "root","");
  $st = $pdo->query("SELECT * FROM post ORDER BY no DESC");
  $posts = $st->fetchAll();
  for ($i = 0; $i < count($posts); $i++) {
    $st = $pdo->query("SELECT * FROM comment WHERE post_no={$posts[$i]['no']} ORDER BY no DESC");
    $posts[$i]['comments'] = $st->fetchAll();
  }
  require 't_index.php';

はじめのブログラムでは、phpでデータベースを参照するためのPDOクラスのインスタンス作成します。
それが~new PDO~というところです。ここの部分ではデータベースとphpをつなげています。
PDOの中身でははじめにデータベースの名前を入力して、次の項目ではユーザー名とパスワードを入力します。
今回の場合、データベース名をblog,ユーザー名をroot,パスワードを無しにしています

 $st = $pdo->query("SELECT * FROM post ORDER BY no DESC");

の部分では、pdoインスタンスから->query()メソッドを呼び出してデータベースに指令を送っています。
そして、$stにはメソッドの戻り値が入ります。
命令内容はpostテーブルにあるすべてのフィールドを
noにおいて大きい順に返すように指示しています。
つまり、新しい順という意味ですね。

$posts = $st->fetchAll();

fetchAllメソッドはすべてのレコードを配列として返します。この場合だとposts[0]は最新の記事の内容となっております。

for ($i = 0; $i < count($posts); $i++) {
    $st = $pdo->query("SELECT * FROM comment WHERE post_no={$posts[$i]['no']} ORDER BY no DESC");
    $posts[$i]['comments'] = $st->fetchAll();
  }

上記の部分では、まずcounts($posts)でposts配列はどれくらいの数があるのか、調べています。それからその数分blogデータベースからcommentのフィールドすべてをnoの逆順にして返すようにしています。
つまりですね。それぞれのブログには対応したコメントが存在するため、それらをforで個別に呼び出してpost部分と対応付け用としています。

次に最初のプログラムが終わったらrequireで飛びます。

t_index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Special Blog</title>
<link rel="stylesheet" href="blog.css">
</head>
<body>
<h1>Special Blog</h1>
<?php foreach ($posts as $post) { ?>
  <div class="post">
    <h2><?php echo $post['title'] ?></h2>
    <p><?php echo nl2br($post['content']) ?></p>
    <?php foreach ($post['comments'] as $comment) { ?>
      <div class="comment">
        <h3><?php echo $comment['name'] ?></h3>
        <p><?php echo nl2br($comment['content']) ?></p>
      </div>
    <?php } ?>
    <p class="commment_link">
      投稿日:<?php echo $post['time'] ?> 
      <a href="comment.php?no=<?php echo $post['no'] ?>">コメント</a>
    </p>
  </div>
<?php } ?>
</body>
</html>

次の部分は表示部分です。
html部分の説明を省きますと。

<?php foreach ($posts as $post) {?>

では投稿されたブログをすべて表示するために、foreachでpostsの中身を一回ごとにpostに移しています。そして、$postsの数に応じて次のプログラムを行います。

<div class="post">
    <h2><?php echo $post['title'] ?></h2>
    <p><?php echo nl2br($post['content']) ?></p>
    <?php foreach ($post['comments'] as $comment) { ?>
      <div class="comment">
        <h3><?php echo $comment['name'] ?></h3>
        <p><?php echo nl2br($comment['content']) ?></p>
      </div>
    <?php } ?>
    <p class="commment_link">
      投稿日:<?php echo $post['time'] ?> 
      <a href="comment.php?no=<?php echo $post['no'] ?>">コメント</a>
    </p>
  </div>
<?php echo nl2br($post['content']) ?>

では、nl2brはcontent中に存在するテキストの改行\nを自動的に
に変換します。

あとの部分では、htmlに<? echo post[x]>などの表記をしてphpの変数をいいかんじにhtmlに表示していますね。
実行画面はを以下のようになります
myhtml.png

次はブログの投稿画面に映ります。

post.php
<?php
  $error = $title = $content = '';
  if (@$_POST['submit']) {
    $title = $_POST['title'];
    $content = $_POST['content'];
    if (!$title) $error .= 'タイトルがありません。<br>';
    if (mb_strlen($title) > 80) $error .= 'タイトルが長すぎます。<br>';
    if (!$content) $error .= '本文がありません。<br>';
    if (!$error) {
      $pdo = new PDO("mysql:dbname=blog", "root");
      $st = $pdo->query("INSERT INTO post(title,content) VALUES('$title','$content')");
      header('Location: index.php');
      exit();
    }
  }
  require 't_post.php';
?>

内容としては、はじめのほうはt_post.phpがすでに実行されたのかを調べています。実行された場合、if (_POST['submit'])がtrueとなり次の処理へと移ります。
それぞれ、title,contentを$_POST配列から読み出します。それから、それらのパラメータに以上がないかifで確認しています。
そして、最後にerrorがない場合、

$pdo = new PDO("mysql:dbname=blog", "root");
$st = $pdo->query("INSERT INTO post(title,content) VALUES('$title','$content')");
header('Location: index.php');
exit();

データベースにsql文で入力されたtitleとcontentを出力せよというプログラムを出力しています。

t_post.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>記事投稿 | Special Blog</title>
<link rel="stylesheet" href="blog.css">
</head>
<body>
<form method="post" action="post.php">
  <div class="post">
    <h2>記事投稿</h2>
    <p>題名</p>
    <p><input type="text" name="title" size="40" value="<?php echo $title ?>"></p>
    <p>本文</p>
    <p><textarea name="content" rows="8" cols="40"><?php echo $content ?></textarea></p>
    <p><input name="submit" type="submit" value="投稿"></p>
    <p><?php echo $error ?></p>
  </div>
</form>
</body>
</html>

こちらのほうが、formを作成して、それらの内容をpost.phpに送るためのプログラムです。

次はコメント差し込むphpプログラムです。同じくblogフォルダ内に作成しましょう。

comment.php
<?php
  $post_no = $error = $name = $content = '';
  if (@$_POST['submit']) {
    $post_no = strip_tags($_POST['post_no']);
    $name = strip_tags($_POST['name']);
    $content = strip_tags($_POST['content']);
    if (!$name) $error .= '名前がありません。<br>';
    if (!$content) $error .= 'コメントがありません。<br>';
    if (!$error) {
      $pdo = new PDO("mysql:dbname=blog", "root");
      $st = $pdo->prepare("INSERT INTO comment(post_no,name,content) VALUES(?,?,?)");
      $st->execute(array($post_no, $name, $content));
      header('Location: index.php');
      exit();
    }
  } else {
    $post_no = strip_tags($_GET['no']);
  }
  require 't_comment.php';
?>
t_comment.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>コメント投稿 | Special Blog</title>
<link rel="stylesheet" href="blog.css">
</head>
<body>
<form method="post" action="comment.php">
  <div class="post">
    <h2>コメント投稿</h2>
    <p>お名前</p>
    <p><input type="text" name="name" size="40" value="<?php echo $name ?>"></p>
    <p>コメント</p>
    <p><textarea name="content" rows="8" cols="40"><?php echo $content ?></textarea></p>
    <p>
      <input type="hidden" name="post_no" value="<?php echo $post_no ?>">
      <input name="submit" type="submit" value="投稿">
    </p>
    <p><?php echo $error ?></p>
  </div>
</form>
</body>
</html>

やっていることはpost.phpと同様に
ボタンおされた後?ならエラーはないかい?それならデータベースに挿入しなくちゃ!みたいなかんじだと思います笑

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
19
Help us understand the problem. What are the problem?