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

More than 1 year has passed since last update.

posted at

updated at

【PHP】就職活動の為の、webアプリ(ポートフォリオ)設計図公開!|未経験からエンジニアへ

web系エンジニアを目指し、PHPを学習している初学者です。
就職活動の武器とすべく着手した、webアプリ(ポートフォリオ)作成。
MENTAを利用し、本格的に学習開始してから4ヶ月で、デプロイに漕ぎ着けました!
派手さもモダンな感じもないですが、バリデーションや不正アクセス防止など、地味な部分を丁寧にコーディングしました。
採用担当の方、同じエンジニアを目指す初学者の方、エンジニアを目指そうか迷っている方の目に留まれば幸いです。

記事の目的

  • 面接に備えた補助資料として
  • 同じ境遇の方の参考(になれば幸い)

作成した【内定者懇親サイト】について、
1. カタログ
2. 仕様書
3. 気を付けた点
4. 後悔している点
5. (追記)公開後、改善した点
をまとめました。

1.カタログ

作成したサイトの紹介。

〜内定者懇親サイト〜

内定承諾してから、入社するまでの期間。
「他の内定者は何人位?年齢は?どんな人?」
「内定式で会う前に知って欲しい・知っておきたい、話のネタを仕込んでおきたい。」
そんな願いを叶える、簡易的な懇親サイト。

概要

ユーザー種類

  • 管理者
  • メンバー

機能

  • 管理者|メンバー全員の編集、削除。他の管理者の新規登録、編集、削除
  • メンバー|自身の登録、編集、削除。他のメンバー 一覧、詳細の閲覧

開発環境

MAMPでローカル環境構築。
VScodeでコーディング→Githubでコード管理→herokuでデプロイ

  • PHP 7.3.11
  • HTML/CSS、Bootstrap4
  • MySQL 5.7.26

2.仕様書

サイトの設計図です。

機能一覧

  • メンバーのCRUD機能(新規登録、プロフィール編集、削除)
  • 管理者のCRUD機能
  • 管理者権限付与(メンバーの編集、削除)
  • メンバー 一覧表示機能
  • メンバー 詳細表示機能
  • レスポンシブ対応(Bootstrap)

DB

クリエイト文

  • jinjies
CREATE TABLE `jinjies` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(100) NOT NULL,
  `password` varchar(255) NOT NULL,
  `last_name` varchar(100) NOT NULL,
  `first_name` varchar(100) NOT NULL,
  `created` datetime NOT NULL,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4
  • members
CREATE TABLE `members` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(100) NOT NULL,
  `password` varchar(255) NOT NULL,
  `created` datetime NOT NULL,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4
  • members_info
CREATE TABLE `members_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `member_id` int(10) NOT NULL,
  `last_name` varchar(100) NOT NULL,
  `first_name` varchar(100) NOT NULL,
  `nick_name` varchar(100) NOT NULL,
  `school` char(10) NOT NULL,
  `prefectures_id` int(10) NOT NULL,
  `message` varchar(240) NOT NULL,
  `icon` varchar(120) DEFAULT NULL,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4
  • prefectures
CREATE TABLE `prefectures` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pre_name` char(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8mb4
  • members_interesting
CREATE TABLE `members_interesting` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `member_id` int(11) NOT NULL,
  `interesting1_id` int(11) NOT NULL,
  `interesting2_id` int(11) NOT NULL,
  `interesting3_id` int(11) NOT NULL,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4
  • interesting
CREATE TABLE `interesting` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `intere_name` char(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4

ER図

データベースの設計図。リレーションは慎重に決める。
NaiteiKonshinDB1.png

ステートチャート図

NaiteiKonshin_ステートチャート図.png

画面遷移図

NaiteiKonshin_画面遷移図.png
これらは無料で使えるLucidchartを利用し、作成しました。

3.気を付けた点

基本スキルを示す

  • フレームワークを使わない、スクラッチ開発(フロント部分はBootstrap使用)
  • CRUD
  • 一通りの入力形式(テキストボックス、チェックボックス、ラジオボタン、ファイルのアップロード)実装
  • 各項目に対するバリデーションを丁寧に
  • パスワードのハッシュ化 (PASSWORD_DEFAULT使用)
  • 不正アクセス防止

fraud_access.gif

ログイン

  1. メンバーログインと新規登録、管理者ログインを1つのログイン画面にまとめ、login_check.phpにて、移行画面を変更した
  2. バリデーションはメソッドを呼び出し、返り値はboolean型とした
login_check.php

class Login
    {
    public function __construct()
    {
        2.validation
        $email_validation = new emailValidation();
        $is_email = $email_validation->isEmail($this->clean['email']);
        //パスワードも同様に
        //validationエラーなら、エラーメッセージを取得し、ログイン画面へ戻る
    }

    public function main()
    {
        1.DB接続しメンバーテーブル管理者テーブルの情報と入力された情報を照合
            メール 一致なし              =>新規登録画面へ
            メールパスワード
                メンバーと一致           =>メンバーログイン
                管理者と一致            =>管理者ログイン
            メール 一致パスワード 一致なし =>エラーメッセージを取得しログイン画面へ戻る
    }
}
$login = new Login();
$login->main();

login.gif

新規登録

  1. パスワードの再入力は、ログインユーザーの邪魔にならないよう新規登録画面で行った スクリーンショット 2020-02-19 16.13.56.png
  2. 再入力が必要な(バリデーションエラー、やり直し選択)時、入力履歴を残し、ユーザー負担を減らした
    スクリーンショット 2020-02-19 16.16.36.png

  3. 入力値をhtmlspecialchars処理する為に、hsc.phpにデータを渡すが、配列(3つ選択させるチェックボックス)も同様の処理が出来るようにした

hsc.php
class Hsc
{
    public static function clean($posts)
    {
        foreach ($posts as $post => $value) {
            3.配列の場合
            if(is_array($value)) {
                foreach($value as $key => $val) {
                    $clean[$post][$key] = htmlspecialchars($val, ENT_QUOTES, 'UTF-8');
                }
            } else {
                $clean[$post] = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
            }
        }
        return $clean;
    }
}

アラート表示

$statusで、前画面での処理内容を表示した

list.phpの場合
<?php
    if(!empty($status)):
?>
<div class="alert alert-success" role="alert">
    <?php
        switch ($status) {
            case 'login':
                echo 'ログイン成功しました。';
            break;
            case 'new':
                echo '新規登録が完了しました。';
            break;
            case 'edit':
                echo '編集が完了しました。';
            break;
            case 'delete':
                echo '削除が完了しました。';
            break;
        }
    ?>
</div>
<?php endif; ?>

スクリーンショット 2020-02-19 16.09.42.png

4.後悔していること

  • 開発履歴を、Githubのブランチやissuesを使用して残せば良かった(ずっとmasterにpushし、コメントも「third commit」など無意味なものばかり^^;)
  • 自身の困りごとを元に、実用性の高いものにすれば良かった
  • クラスをあまり活用出来なかった
  • Twitter的な交流(コメント、イイね!)がない
  • ソートがない
  • 変数の付け方、仕様書を定めずに着手してしまった
  • 後から「アラート付けよう!」など追加していったので、無駄な修正作業や、抜け・漏れで新たなエラーを生み出してしまった

以上です。
Twitter的な機能やソートについては、追加実装するかもしれませんが、ひとまずはこれでデプロイ。
コーディングして画面が出来上がってからは、夢中で作成することが出来ました。
ぜひ、サイトにアクセスしてみてください!
https://github.com/kunitani920/BullentinBoard


5.(追記)公開後、改善した点

メンターさんを中心に改善案を頂き、一部アップデートしました。
その際、自身で感じた「後悔していること」も一部リカバリー出来たので紹介します。

PDOのトランザクション

DBへの新規登録、編集、削除時にトランザクションを追加。

イメージ
<?php

    try {

        //DB接続
        $db = new Db();
        $dbh = $db->dbconnect();

        // トランザクション開始
        $dbh->beginTransaction();

        新規登録編集削除処理

        // コミット
        $dbh->commit();

    } catch(PDOException $e) {
        // ロールバック
        $dbh->rollBack();

        // エラーメッセージ出力
        echo $e->getMessage();
        die();
    }
    $dbh = null;
}

期待できる効果

  • DB同時アクセスによるデータの行き違い防止
  • 処理速度の向上

コンフィグ

コンフィグディレクトリとdatabase.phpファイルを作成し、DB接続情報を移動した。

/confif/database.php
<?php
$db = parse_url($_SERVER['CLEARDB_DATABASE_URL']);
$db['dbname'] = ltrim($db['path'], '/');

return [
    'dsn' => "mysql:host={$db['host']};dbname={$db['dbname']};charset=utf8",
    'user' => $db['user'],
    'password' => $db['pass'],
    'options' => array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::MYSQL_ATTR_USE_BUFFERED_QUERY =>true,
    )
];
?>
Db.php
<?php

class Db
{
    public function dbconnect() {
        try {            
            $db = include(__DIR__ . '/config/database.php');
            $dbh = new PDO($db['dsn'], $db['user'], $db['password'], $db['options']);
        } catch(PDOException $e) {
            echo 'DB接続エラー:' . $e->getMessage();
        }
        return $dbh;
    }
}

期待できる効果

  • 管理者の負担軽減
  • 人的ミスの削減

DB定義とクリエイト文

DB定義を、GithubのREADMEに追加。
DBクリエイト文を、この記事の2.仕様書に追加。

issues、ブランチ活用(4.後悔していることより)

改善項目をissuesに設定。
スクリーンショット 2020-02-27 19.21.30.png
スクリーンショット 2020-02-28 0.01.57.png

Millestonesで期限設定も体験し、機能を少し把握できた。

修正で間違えても戻れるよう、新しいブランチを切って修正作業。
スクリーンショット 2020-02-28 0.34.08.png
ブランチ名がわかりづらく反省。しかし、コミットメッセージはマシになったと思う。

DB再設計

「1対1関係なのに、なぜテーブルを分けるのか?」
複数の方にご指摘いただいた。

作成当時、
「ID(メール、パスワード)とプロフィール(メッセージなど)を分けて管理したいな」
「3つ選択の趣味、それぞれにIDふるのは変かな?いや、でもそうしないと実現できない」
など考えがまとまらない中
「とりあえず、作ろう!」
と走ってしまった結果です。

ということで、DBの再設計を行った。
NaiteiKonshinDB1(修正版).png
(未反映)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
18
Help us understand the problem. What are the problem?