質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.38%

  • PHP

    25064questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • オブジェクト指向

    335questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

オブジェクト指向の書き換えについて

解決済

回答 6

投稿

  • 評価
  • クリップ 0
  • VIEW 780

newyee

score 145

現在PHPの学習をしているものです。学習を進めていく内に、簡易な掲示板は作れるようになったのですが、それをオブジェクト指向を用いて書き換えようと思った際に、どの機能をどのようなクラスにまとめれば良いか、などといったことが分からず、どこから手をつけて良いか分からない状態です。オブジェクト指向につきましては、参考書で勉強したり、ネットの記事を見るなどして、調べたりしたのですが、実際に現状自分のコードをどのように、オブジェクト指向に書き換えたらよいのかが分からない為、ご助言頂きたくご質問させていただきました。
以下は、自分の作成した掲示板のコードになります。
下記のコードは、掲示板のコメント投稿画面、及びコメント一覧画面を表示する、「bbs.php」です。

<?php 
include 'includes/login.php';
  error_reporting(E_ALL);
  ini_set("display_errors",1);
  //1ページに表示されるコメントの数
  $num = 10;
  $user = 'root';
  $password = '';
  $dsn = 'mysql:host=localhost;dbname=online_bbs;charset=utf8';
  //ページ数が指定されている時
  $page = 0;
  if(isset($_GET['page']) && $_GET['page'] > 0){
    $page = intval($_GET['page']) -1;

  }

  try{
    $dbh = new PDO($dsn,$user,$password);
    $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);

    $stmt = $dbh->prepare("SELECT id,name,title,comment,created_at,password FROM post ORDER BY created_at DESC LIMIT
    :page,:num");
    //パラメーターを割り当て
    $page = $page * $num;

    $stmt->bindValue(':page',$page,PDO::PARAM_INT);
    $stmt->bindValue(':num',$num,PDO::PARAM_INT);
    $stmt->execute();

  }catch(PDOException $e){
    echo "エラー: " . $e->getMessage();
  }



?>

  <html>
    <head>
      <title>交流サイト:掲示板</title>
      <meta charset="utf-8">
    </head>
    <body>
      <h1>掲示板</h1>
      <form action="write.php" method="post">
        <p>名前:<input type="text" name="name" value="<?php echo isset($_COOKIE['name']) ? $_COOKIE['name'] : '' ?>"></p>
        <p>タイトル:<input type="text" name="title" size="60"></p>
        <textarea name="comment"></textarea>
        <p>削除パスワード(数字4桁):<input type="text" name="pass">
        <input type="submit" name="submit" value="書き込む">
        <input type="hidden" name="token" value="<?php echo password_hash(session_id(),PASSWORD_DEFAULT); ?>">
      </form> 
      <hr>
    <?php 
      while($row = $stmt->fetch()):

        $title = $row['title'] ? $row['title'] : '(無題)';
      ?>
      <p>名前:<?php echo $row['name'] ?></p>
      <p>タイトル:<?php echo $title ?></p>
      <p><?php echo nl2br(htmlspecialchars($row['comment'],ENT_QUOTES,'UTF-8'),false) ?></p>
      <p><?php echo $row['created_at'] ?></p>
      <form action="delete.php" method="post">
        <input type="hidden" name="id" value="<?php echo $row['id']; ?>">
        削除パスワード:<input type="password" name="pass">
        <input type="submit" value="削除">
        <input type="hidden" name="token" value="<?php echo password_hash(session_id(),PASSWORD_DEFAULT); ?>">
      </form>
    <?php 
      endwhile;
      //ページ数の表示
      try{
        $stmt = $dbh->prepare("SELECT COUNT(*) FROM post");
        $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
        $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

        //クエリの実行
        $stmt->execute();

      }catch(PDOException $e){
        echo "エラー:" . $e->getMessage();
      }
      /**
       * コメントの件数を取得
       *fetchColumn関数で 最初のレコードを取り出し、最初の列「id」のデータを取り出す
       * idは降順に設定されているため、コメントの件数が分かる
       * */
      $comments = $stmt->fetchColumn();
      $max_page = ceil($comments / $num);
      echo '<p>';
      for($i = 1; $i <= $max_page; $i++){
        echo '<a href="bbs.php?page=' . $i .'">' . $i .
        '</a>&nbsp;'; 
      }
      echo '</p>';
      ?>

    </body>
  </html>


下記はコメントを投稿すると、名前やパスワードのバリデーションチェックを行い、データベースへ情報を記録する為の、「write.php」です。

<?php
include 'includes/login.php'; 
error_reporting(E_ALL);
ini_set('display_errors', '1');

$err_message = [];

if(!empty($_POST)){

  $title = filter_input(INPUT_POST,'title',FILTER_SANITIZE_SPECIAL_CHARS);
  $token = filter_input(INPUT_POST,'token',FILTER_SANITIZE_SPECIAL_CHARS);

  if(!$name = filter_input(INPUT_POST,'name',FILTER_SANITIZE_SPECIAL_CHARS)){
    $err_message[] = '名前が入力されていません';
  }

  if(!$pass = filter_input(INPUT_POST,'pass',FILTER_SANITIZE_SPECIAL_CHARS)){
    $err_message[] = 'パスワードが入力されていません';
  }

  if(!$comment = filter_input(INPUT_POST,'comment',FILTER_SANITIZE_SPECIAL_CHARS)){
    $err_message[] = 'コメントが入力されていません';
  }

}


if(!preg_match("/^[0-9]{4}$/",$pass)){

  $err_message[] = 'パスワードを4文字で入力してください';

}

$pass = password_hash($pass,PASSWORD_DEFAULT);

if(count($err_message) === 0){
  //CSRF対策
  if(!password_verify(session_id(),$token)){
    header('Location:bbs.php');
    exit();
  }

  setcookie('name',$name,time() + 60 * 60 * 24 * 30);



  //データベースに接続
  $dsn = 'mysql:host=localhost;dbname=online_bbs;charset=utf8';
  $user = 'root';
  $password = '';

  try{
    $db = new PDO($dsn,$user,$password);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
    $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    $stmt = $db->prepare("
      INSERT INTO post (name,title,comment,created_at,password)
      VALUES (:name, :title, :comment, now(), :pass)");
    $stmt->bindValue(':name',$name,PDO::PARAM_STR);
    $stmt->bindValue(':title',$title,PDO::PARAM_STR);
    $stmt->bindValue(':comment',$comment,PDO::PARAM_STR);
    $stmt->bindValue(':pass',$pass,PDO::PARAM_STR);
    $stmt->execute();

  }catch(PDOException $e){
    die ('エラー:' . $e->getMessage());
  }

}

?>
<html>
<head>
  <meta charset="utf-8">
  <title>Page Title</title>

</head>
<body>
  <?php 
    echo implode("<br />",$err_message);
  ?>
  <h4>投稿に成功しました。</h4>
  <p><a href="bbs.php">戻る</a>  

</body>
</html>


下記はコメントの削除パスワードを入力すると、データベースから情報を削除する為の、「delete.php」です。

<?php
  include 'includes/login.php';
  error_reporting(E_ALL);
  ini_set("display_errors",1);

  //エラーメッセージ
  $err_msg = [];

  if(!empty($_POST)){

    if(!$pass = filter_input(INPUT_POST,'pass',FILTER_SANITIZE_SPECIAL_CHARS)){

      $err_msg[] = 'パスワードが入力されていません。';

    }


    $token = filter_input(INPUT_POST,'token',FILTER_SANITIZE_SPECIAL_CHARS);

    //POSTされたIDを取得
    $id = filter_input(INPUT_POST,'id',FILTER_SANITIZE_SPECIAL_CHARS);
    $id = intval($id);

  }

  //CRLF対策
  if(!password_verify(session_id(),$token)){
    header('Location:bbs.php');
    exit();
  };

  if(count($err_msg) === 0){


    $dsn = 'mysql:host=localhost;dbname=online_bbs;charset=utf8';
    $user = 'root';
    $password = '';

      try{
        $dbh = new PDO($dsn,$user,$password);
        $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
        $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        $stmt = $dbh->prepare("
          SELECT password FROM post where id = :id 
        ");

        $stmt->bindValue(':id',$id,PDO::PARAM_INT);

        $stmt->execute();

        $db_pass = $stmt->fetch();

        if(!password_verify($pass,$db_pass['password'])){

          die('パスワードが違います');
        }

        $stmt = $dbh->prepare("
            DELETE FROM post WHERE id = :id 
          ");

        $stmt->bindValue(':id',$id,PDO::PARAM_INT);
        $stmt->execute();

      }catch(PDOException $e){

        die( "エラー:" . $e->getMessage());
      }

    header('Location: bbs.php');
    exit();

    } 

?>


よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mts10806

    2019/03/13 21:41 編集

    そこはご自由に思ったら結構かと。自身が如何に人のアドバイスをちゃんと聞き入れてないか気づいてもらえたらそれで良かったのですが、そこにいかないなら仕方ないですね。
    ちなみにですが、私があなたの掲示板プログラムを1から、オブジェクト指向きちんとしっかり盛り込んで作ろうとした場合、1週間はかかると見てます(多少大袈裟だけどそれでもまあ1日2日でどうにかできるものではない。フレームワークを1から作るつもりですから)。既に回答がついているようにオブジェクト指向のメリット皆無な簡易掲示板システムですら、しっかり作りこむとあなたが作った程度のものでもそれなりにかかるものです。
    それはともかく、何とか1段ずつのぼってもらおうとそれなりに苦心してアドバイスしてきたつもりでしたが、無駄に終わることが分かったので、私はこれで。あとは勝手にしてください。

    キャンセル

  • tamoto

    2019/03/14 12:11

    回答ではないのでここに書きます。
    この質問は、極端なたとえで表現すると、「COBOLでプログラムを書きました!これをrubyに直すとどうなりますか?rubyは調べたので知ってます」みたいなものです。そんなもの「全部書き直してください」としか言えないですし、丸投げ質問でしかないです。まずは調べた内容に則って書いてみて、それでわからなかった部分を質問するのなら良いです。単なる手続き処理とオブジェクト指向は「全く異なる概念の元で書かれるもの」なので、ただ翻訳するということはできないことを「調べた」のであれば理解しているはずですよ。

    キャンセル

  • newyee

    2019/03/14 12:52 編集

    確かに、オブジェクト指向はすべて理解はできていなかったです。すべて書き直してくださいとの意味で、質問させて貰った訳でなく、どこから手をつけてよいか分からなかった為、ご助言頂ければと思い質問させてもらいました。

    キャンセル

回答 6

+6

既存のコードを無理にオブジェクト指向にするというのはかなり無理がありますね。
掲示板のように小さなものだと、オブジェクト指向のメリットは皆無だし。
まずは、ベタ書きしている処理を関数で切り分けしたらよいかと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/13 21:53

    はい、そこなんですよね。login.phpが何者かはさておき、
    まさかべた書きからいきなりクラスに移ろうとするとは思ってませんでした。
    私のオペミスもありますが、さすがに質問サイトでできることって少ないですからね。

    キャンセル

  • 2019/03/13 21:54

    まあ、春休み中の学生さんなんでしょうかね…

    キャンセル

  • 2019/03/13 22:05

    @newyee さん
    オブジェクト指向って、まず作りたいものは何か、それを作ることによって何を実現したいのか、という「要求」があって、それを「要件」に落とし込む(つまり設計の)ときに意識すべきことです。
    すでにあるコードをグレードアップする段階のことではないのですよ。
    すでにあるコードをスマートにする行為はリファクタリングと言います。

    キャンセル

+5

何かしらのフレームワークを使って、それに則って構築してみる、というのがわかりやすいかなと思います。

PHPでシンプルなフレームワークとしては、CodeIgniterなどがあります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/13 22:08

    確かに、自分でゼロから作って勉強するより、ある程度は出来合いのものを触るところから始めた方が、いろいろな概念はつかみやすいのかもしれません。

    キャンセル

  • 2019/03/14 11:33

    ご回答ありがとうございます。
    現状、オブジェクト指向を学習するにはまだ早かったということも、色々な方にご回答いただき分かりましたし、取り敢えず、基礎的なことをやり直し、ある程度身に付きましたら、フレームワークにも挑戦していこうと思います...

    キャンセル

+3

まだまだ、他人の書いたソースコードを読んで学習するフェーズなんだと思いますよ。
本1冊読んだだけでマスターできますか? 世の中にはもっといっぱい教材がありますよ。
掲示板を作れただけでマスターできたつもりですか? 簡易掲示板をもっと機能充実にするために改良することも学習の一つです。
自分の中からコードが湧き出してこないということは、学習が足りていない証拠です。

コードの読み方、もあると思います。
手を動かさずに黙読するだけでは理解できないこともあります。
写経(本などのソースコードを実際にタイプして動かす)を馬鹿にする人もいますが
タイプミスしたり、あるいは本のミスで間違いだったりして、
動かない場合もあって、それを動くように直せるようになったら一皮むけた自分になります。
(本のミスがないか正誤表などをネットで確認するのも大事なことです。)

最短ルートで習得できるなら苦労しないし、方法がわかったら教えてくださいね。(こっそり。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/13 21:41

    説教臭くなってしまって、気分を悪くしたらごめんなさい

    キャンセル

  • 2019/03/14 11:25

    いえいえ、ご助言頂きましてありがとうございます。
    確かに、学習が足りていない証拠ですよね...
    自分でも努力が足りていないとは思いますし、もっといろいろな教材などから、コードを写し、またそれを、書き直す、といったことを身に付くまではやっていこうと思います。
    現状の掲示板のコードに関しましては、「オブジェクト指向」の意味を理解できていなかったといのもありますし、取り敢えず、まずは「関数切り出し」を実装できるように学習していこうと思います。

    キャンセル

+1

隠蔽

PHP に慣れ親しんだ方はオブジェクト指向を理解しやすいのではないかと思います。

なぜなら PHP はバックエンドで使われることが多く、そこでは「大事なデータをユーザーに直接触らせることなく、抽象化された API によってのみデータを取得・設定できる」ことが求められているからです。

これはオブジェクト指向の「隠蔽」にほかなりません。

つまり、API を公開していること自体がオブジェクト指向と言うことができます。

ポリモーフィズムと継承

オブジェクト志向にはもう一つ(あるいは二つ)重要な概念があります。
それは「ポリモーフィズム」と「継承」です。

ポリモーフィズムは、あるオブジェクトが別のオブジェクトとして振る舞うことで、継承とは、ポリモーフィズムを容易に行うために親オブジェクト(基本オブジェクト)と互換性のある派生オブジェクトを作ることです。

掲示板に当てはめて言うなら、それぞれの環境に合わせて別のコードを書いても、それらが全て同じ API を用いて同じようにアクセスできるならポリモーフィズムと言うことができます。クライアントにとっては、掲示板 A と掲示板 B への同じ記事の書き込みをループで行うことができます。

コードの再利用

さて、ではオブジェクト指向を用いて掲示板を作るにはどうすればいいかということですが、複数の環境にそれぞれ同じ API を実装するときには、それら全てに共通するコードと、環境に合わせて書き換えなければならないコードがあるはずです。それらをごちゃ混ぜに使っていたのでは、保守が大変面倒なことになります。

そこで、共通するコードをそこから切り分ける必要が出てきます。この共通する部分が可能な限り大きく、環境毎のコードが可能な限り小さくなるよう工夫しましょう。

この共通するコードと、そこから呼び出されて環境の差を埋めるコードの切り分けができれば目的は達成します。

結論

現在のコードは、ある一つの環境に特化したものです。

例えば、データベースやユーザー ID やパスワードが固定で、コードに直接埋め込まれています。

また、ユーザーに表示される HTML も固定です。

これを一般化し、ファイルを一つ置き換えるだけでどのような環境でも対応できるようになればオブジェクト指向で作った掲示板と言えるでしょう。

そしてそれを実現するためには、PHP におけるクラスやオブジェクトについて熟知し、それを使いこなして正しく設計することが必要になります。

コード視点で言えば最初から、つまり設計からやり直してください。プログラマー視点で言えば、オブジェクト指向の基礎から勉強して設計してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/14 13:03 編集

    私が作るのであれば、まず root パスワードやデータベースの情報を保持する Settings クラスと、引数に従って HTML や CSS を作成する UI クラスを作ります。

    他の関数からこれらの情報が必要になった時には、必ず該当するオブジェクトを作ってそこから取得・設定するようにし、ハードコーディングや多重設定は認めません。

    よって、この二つのクラスを取り替えれば環境に合わせて好きな見た目の掲示板が作れるということです。

    キャンセル

  • 2019/03/14 14:38

    ご丁寧にありがとうございます。
    現状、自分にはご回答頂いた点に関しまして理解できない部分も多々ありますので、もう一度、オブジェクト指向につきまして、きちんと勉強してみたいと思います。
    そのうえで、理解できない部分があった場合には、ご回答頂いた点に関しまして、ご質問させて頂くことがあるかもしれないですが、その際はご返信頂けましたら幸いです...

    キャンセル

checkベストアンサー

0

参考までに。

  • bbs_class.php
<?php

class Bbs
{
    private $dbh;

    private $num;

    protected function __construct($dbh, $num)
    {
        $this->dbh = $dbh;
        $this->num = $num;
    }

    public static function create($dsn, $user, $password, $num)
    {
        $dbh = new PDO($dsn, $user, $password);
        $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
        return new static($dbh, $num);
    }

    public function comments($page)
    {
        $stmt = $this->dbh->prepare("SELECT id,name,title,comment,created_at,password FROM post ORDER BY created_at DESC LIMIT :page,:num");
        $page = $page * $this->num;
        $stmt->bindValue(':page', $page, PDO::PARAM_INT);
        $stmt->bindValue(':num', $this->num, PDO::PARAM_INT);
        $stmt->execute();
        while ($row = $stmt->fetch()) {
            yield $row;
        }
    }

    public function numberOfPages()
    {
        $stmt = $this->dbh->prepare("SELECT COUNT(*) FROM post");
        $stmt->execute();
        $comments = $stmt->fetchColumn();
        return ceil($comments / $this->num);
    }

    public function write($name, $title, $comment, $pass)
    {
        $stmt = $this->dbh->prepare("INSERT INTO post (name,title,comment,created_at,password) VALUES (:name, :title, :comment, now(), :pass)");
        $stmt->bindValue(':name',$name,PDO::PARAM_STR);
        $stmt->bindValue(':title',$title,PDO::PARAM_STR);
        $stmt->bindValue(':comment',$comment,PDO::PARAM_STR);
        $stmt->bindValue(':pass',$pass,PDO::PARAM_STR);
        $stmt->execute();
    }

    public function delete($id, $pass)
    {
        $stmt = $this->dbh->prepare("SELECT password FROM post where id = :id");
        $stmt->bindValue(':id', $id, PDO::PARAM_INT);
        $stmt->execute();
        $db_pass = $stmt->fetch();
        if(!password_verify($pass, $db_pass['password'])){
            throw new Exception('パスワードが違います');
        }
        $stmt = $this->dbh->prepare("DELETE FROM post WHERE id = :id");
        $stmt->bindValue(':id', $id, PDO::PARAM_INT);
        $stmt->execute();
    }
}

 

  • bbs.php
<?php
include 'includes/login.php';
include 'bbs_class.php';

error_reporting(E_ALL);
ini_set("display_errors",1);

$bbs = Bbs::create('mysql:host=localhost;dbname=online_bbs;charset=utf8', 'root', '', 10);

$page = ($_GET['page'] ?? 1) - 1;
?>
<html>
    <head>
        <title>交流サイト:掲示板</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h1>掲示板</h1>
        <form action="write.php" method="post">
            <p>名前:<input type="text" name="name" value="<?php echo isset($_COOKIE['name']) ? $_COOKIE['name'] : '' ?>"></p>
            <p>タイトル:<input type="text" name="title" size="60"></p>
            <textarea name="comment"></textarea>
            <p>削除パスワード(数字4桁):<input type="text" name="pass"></p>
            <input type="submit" name="submit" value="書き込む">
            <input type="hidden" name="token" value="<?php echo password_hash(session_id(),PASSWORD_DEFAULT); ?>">
        </form>
        <hr>
        <?php foreach ($bbs->comments($page) as $row): ?>
            <p>名前:<?php echo $row['name'] ?></p>
            <p>タイトル:<?php echo $row['title'] ? $row['title'] : '(無題)' ?></p>
            <p><?php echo nl2br(htmlspecialchars($row['comment'],ENT_QUOTES,'UTF-8'),false) ?></p>
            <p><?php echo $row['created_at'] ?></p>
            <form action="delete.php" method="post">
                <input type="hidden" name="id" value="<?php echo $row['id']; ?>">
                削除パスワード:<input type="password" name="pass">
                <input type="submit" value="削除">
                <input type="hidden" name="token" value="<?php echo password_hash(session_id(),PASSWORD_DEFAULT); ?>">
            </form>
        <?php endforeach; ?>
        <p>
            <?php foreach (range(1, $bbs->numberOfPages()) as $page): ?>
                <a href="bbs.php?page=<?php echo $page ?>"><?php echo $page ?></a>&nbsp;
            <?php endforeach; ?>
        </p>
    </body>
</html>
  • write.php
<?php
include 'includes/login.php';
include 'bbs_class.php';

error_reporting(E_ALL);
ini_set('display_errors', '1');

$bbs = Bbs::create('mysql:host=localhost;dbname=online_bbs;charset=utf8', 'root', '', 10);

$token = filter_input(INPUT_POST,'token',FILTER_SANITIZE_SPECIAL_CHARS);
$title = filter_input(INPUT_POST,'title',FILTER_SANITIZE_SPECIAL_CHARS);
$name = filter_input(INPUT_POST,'name',FILTER_SANITIZE_SPECIAL_CHARS);
$comment = filter_input(INPUT_POST,'comment',FILTER_SANITIZE_SPECIAL_CHARS);
$pass = filter_input(INPUT_POST,'pass',FILTER_SANITIZE_SPECIAL_CHARS);

if(!password_verify(session_id(), $token)){
    header('Location:bbs.php');
    exit();
}

$err_message = [];

if (!$name) {
    $err_message[] = '名前が入力されていません';
}

if (!$pass) {
    $err_message[] = 'パスワードが入力されていません';
} elseif (!preg_match("/^[0-9]{4}$/", $pass)){
    $err_message[] = 'パスワードを4文字で入力してください';
}

if (!$comment) {
    $err_message[] = 'コメントが入力されていません';
}

if(empty($err_message)){
    setcookie('name', $name,time() + 60 * 60 * 24 * 30);
    $pass = password_hash($pass,PASSWORD_DEFAULT);
    $bbs->write($name, $title, $comment, $pass);
}
?>
<html>
    <head>
        <meta charset="utf-8">
        <title>Page Title</title>
    </head>
    <body>
        <?php if (empty($err_message)): ?>
            <h4>投稿に成功しました。</h4>
        <?php else: ?>
            <?php echo implode("<br />",$err_message); ?>
        <?php endif; ?>
        <p><a href="bbs.php">戻る</a>
    </body>
</html>
  • delete.php
<?php
include 'includes/login.php';
include 'bbs_class.php';

error_reporting(E_ALL);
ini_set("display_errors",1);

$bbs = Bbs::create('mysql:host=localhost;dbname=online_bbs;charset=utf8', 'root', '', 10);

$token = filter_input(INPUT_POST,'token',FILTER_SANITIZE_SPECIAL_CHARS);
$pass = filter_input(INPUT_POST,'pass',FILTER_SANITIZE_SPECIAL_CHARS);
$id = filter_input(INPUT_POST,'id',FILTER_VALIDATE_INT);

if(!password_verify(session_id(), $token)){
    header('Location:bbs.php');
    exit();
};

$err_msg = [];

if (!$pass) {
    $err_msg[] = 'パスワードが入力されていません。';
}

if (!$id) {
    $err_msg[] = 'IDが入力されていません。';
}

if(empty($err_msg)){
    $bbs->delete($id, $pass);
    header('Location: bbs.php');
    exit();
}
?>
<html>
    <head>
        <meta charset="utf-8">
        <title>Page Title</title>
    </head>
    <body>
        <?php echo implode("<br />",$err_msg); ?>
        <p><a href="bbs.php">戻る</a>
    </body>
</html>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/16 19:36 編集

    ご親切にありがとうございます。
    どのように、処理を切り分けたり、クラスを作るのかが分からなかったのですが、ご回答いただきましたおかげでイメージが掴めました。
    自分のコードは、「write.php」「delete.php」「bbs.php」の全てでデータベースへの接続処理を記載していたんですが、クラス一つにまとめれば見やすいし、便利ですね!ご回答いただきましたおかげで、かなり、オブジェクト指向について、イメージが掴めたのですが、自分の知識不足で、理解できていない部分もあります...自分では、大丈夫であろうと思い、オブジェクト指向に取り掛かろうとしたのですが、そこに入る前に、もっときちんと勉強しなければならないと、痛感致しました...
    勉強する、段階を間違えてしまったと思っておりまして、現在は参考書にて、もう一度基本的なことを学び直しております。オブジェクト指向も含めすべての復習が終了しましたら、ご回答頂きました、掲示板のコードを参考にさせて頂き、掲示板のコードをオブジェクト指向に書き換えてみます。
    ご丁寧に教えてくださいまして、ありがとうございました。

    キャンセル

  • 2019/03/29 20:38 編集

    あれから、オブジェクト指向につきまして、書籍にて勉強をし、ご回答頂きましたコードを見直させてもらったのですが、まだ、何点か分からない所がございます...
    bbs_class.phpのcreate関数内の「return new static($dbh, $num);」とあるのですが、「new static」という書き方は初めてみました...これはどのような意味になるのでしょうか...?
    もしよろしければ、お手数かとは思いますが、教えて頂けましたら、幸いです。よろしくお願いいたします...

    キャンセル

0

別回答に書いたコメントそのまま再掲します。無視されたようなので。
これ聞かなかったら今後どうなろうと知りません。(元々ユーザー同士は他人なので無責任だし知ったこっちゃないわけですけど、アドバイス聞き入れないならそりゃ余計にね)


何が出来るかきちんと知らない内から「まとめる」ことを考えるのは早計ですよ。毎日何かしら考えたとしても「まとめる」ことを考えるまでに数年かかると言っていいです。
私でもそこまで全て把握しきれてるわけではないですし(一応、自分でフレームワークのようなものは作れますが、日々最適化を目指してます) 


まともに関数切り出しで共通化もできてないのにロジックもままならないのにオブジェクト指向なんて早計すぎますね。

数年かかるって書いたじゃないですか。
なんで1日くらいで出来る気になれるのか理解に苦しみますね。


ちなみに、
私もinclude、継承地獄から脱却するために
オートローダへの移行をやったときは結局ほぼ全て作り直しました。
名前空間を適切につける必要があったしphpのバージョンも上がってたから
それに合った書き方をしたかったし、実現のためにはディレクトリ構成もかえる必要もありました。
流用したのはほんの一部ですね。

オブジェクト指向からオブジェクト指向に移行するときですら
作り直しなのに、無からオブジェクト指向で作り直しにならないはずがないですね。
今のコードは全部捨てるつもりで、残すのはDBのデータだけとかですよ。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/13 20:13

    まとめるとお伝えしたことについてなのですが、自分では、オブジェクト指向というものは、クラスなどを作り、まとめることだと認識しており、そのように伝えてしまいました...
    自分の中ではクラスを作り関数切り出しを行うことも、オブジェクト指向設計に入るのではないかと思うのですが、そういったことではないのでしょうか?
    うまく、自分がどの程度理解できているかを、お伝えできなかったことや、適当にまとめるなどといってすみませんでした...

    キャンセル

  • 2019/03/13 20:27 編集

    私のコメント全部読み直して出直してください。
    質問してる暇があったらHello Worldからやり直してください。
    それもechoで出すだけじゃなく、オブジェクト指向をふんだんに使って。
    その様子だと継承すら理解してませんよね。意味、効果的な使い方。アクセス修飾子、適切に振り分けられますか?インターフェイス、使い分けできますか?
    モデル、コントローラ 適切に設置できますか?
    名前空間、オートローダはどうですか?

    など。
    これまでifやforなどをやってきたのと同じように基本があり、適材適所の使い方を覚え、ロジックから落とし込む必要がありますよ。
    それができてようやく「設計」です。機能をどうまとめたら効果的になるのか、速度やメモリを担保できるようになるのか、を考えられる段階になります。
    これでもだいぶ端折ってます。
    今、あなたはどうでしょうか?

    まだ気づきませんか?
    あなたは人間の成長過程で言うと寝返りも自分の意思では思うようにできないあかちゃんレベルです。
    やろうとしていることは、自ら仕事を遂行する行為です(よくて就活で自分に合う職場を探すくらい)。
    寝返りもままならない、歩けさえできないのに手を出せると思いますか?マニュアルさえまともに使えないのに。
    それだけの段階を省略すればできなくて当然。

    キャンセル

  • 2019/03/13 20:42

    継承の意味だったり、インターフェースやモデル、コントローラなどの単語の意味は参考書などで、学習しましたので、知ってはいますが、実際に、自分のコードでそれらを取り入れようとした際に、どのように組み込めばよいのかが分からないです。
    恐らくですがmtsさんの指摘されていることをすべて理解できていたら、ここに質問はしないと思います。

    キャンセル

  • 2019/03/13 20:49

    知ってるうちに入らないですよそれ。
    ifとかforとかどうやって使えるようになりました?というか、今でもちゃんと使えてるって言えますか?
    適切に的確に組み込める自信ありますか?
    「学習したから知ってる」は、プログラミングの世界では無知と同です。使えないなら知らないと同じ。
    使えるようになるにはコードを書いて書いてマニュアル読んでまた書いて失敗して、を繰り返すしかない。
    どこまでやりました?たった数日で知った気にならないでください。
    あらゆるエンジニアを舐めすぎです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.38%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • PHP

    25064questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • オブジェクト指向

    335questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。