8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

テコテックAdvent Calendar 2019

Day 17

フレームワークと管理ツールを自作してプロトタイプ開発してみた

Last updated at Posted at 2019-12-16

本投稿は TECOTEC Advent Calendar 2019 の17日目の記事です。

RDBとフレームワークを連携して、プロトタイプ作成するWebツール「project-manager」を個人的に作成しているので紹介します。

  • CRUD処理やら Viewとか毎回手で書きたくない
  • DBを設計しながらプロトタイプレベルである程度自動化したい(scaffold、artisan などを拡張)
  • ファイル設計をある程度可視化&管理したい

最近では、Scratchプログラミングなど「コードを書かないプログラミング」もちらほら世に出ていたり、会社によっては既に自社システムを運用していたりしているかと思います。

詳細なロジック段階に入ると、やはり人の記述が必須となりますが、出来るだけプログラムを書かなくても良い部分もあるとは思い作成しています。

注意

  • 自作フレームワークを勧める記事ではないので、セットアップや使い方は割愛
  • 個人開発中で未搭載処理や、一切情報公開していないため動作保証しません
  • なので未実装&バグなどはご了承ください

とりあえずCRUD処理画面を作成してみる

「project-manager」でブラウザをぽちぽちして、プロトタイプ(プログラムテンプレート)を作成してみます。

  1. プロジェクト設定
  2. DB作成
  3. Model&テーブル定義作成
  4. Controller/View作成
  5. フレームワークにファイルエクスポート(今回はPHP)

結果

登録・一覧・編集画面が出来ました。(コーディングは一切していません)
pm_edit.png
(「せい」「めい」の入力間違えてました・・・)
school_student_list.png
pm_edit2.png

CRUD処理におけるリクエスト、セッション、バリデーション、リダイレクトなどなど、とりあえずやってくれます。
(これはどちらかというと「php-work」の方ですが)
項目の追加・修正・削除が発生した場合は、MVC設定を修正して上書きエクスポートを繰り返して作成します。

書き出した Controller ファイルの中身はこんなの感じです。

vscode_controllers.png
...
class StudentController extends AppController {

...
    function action_list() {
        $this->student = DB::model('Student')->all();
    }
...

    function action_edit() {
        $this->student = DB::model('Student')->editPage();
    }
...

    function action_update() {
        $this->redirectForUpdate($this->updateByModel('Student'));
    }

...
    function action_delete() {
        $this->redirectForDelete($this->deleteByModel('Student'));
    }

...
    function action_update_sort() {
        $this->updateSort('Student');
    }
...
}

命名規則の重要性

本題ではないですが、命名規則について
上記はかなり横着過ぎる記述ですが、命名規則やルールが決まっていると、Contoller をある程度汚さずに書くことができます。

  • プログラム開発をする前に「命名規則」は一番重要な項目
  • 命名規則に則り、DB連携やプログラム自動・効率化する事が可能

[参考]
https://qiita.com/softark/items/63e68a0172a1d2f92b5c
https://qiita.com/genzouw/items/35022fa96c120e67c637
https://qiita.com/Ted-HM/items/7dde25dcffae4cdc7923

「project-manager」の概要

pm_flow.png ### project-manager * 管理ツール * Github:https://github.com/yoo16/project-manager * PHP7以降 * PostgreSQL9以降 * mod_rewirte 起動

php-work

  • Github:https://github.com/yoo16/php-work
  • PHPフレームワーク
  • PHP7以降
  • PostgreSQL9以降
  • mod_rewirte 起動
  • MVC、ORM、ActiveRecord設計
  • Railsベースでもともと先人はいたのですが、一から作り直しました

スキーマ作成

  • PostgreSQL(以降DB)に対して「createdb」コマンド実行1
pm_db_list.png

プロジェクト & 作業スペース設定

  • プロジェクト作成でメインDBを登録2
  • フレームワークにファイルエクスポートできるよう設定3
  • Webサーバユーザのパーミッション設定が必要
pm_index.png pm_user_project_setting.png

Model作成・管理(SQL連動)

Model作成すると同時にCREATE TABLE します。4

pm_model_list.png

Modelカラムの修正をすると「ADD COLUMN」「DROP COLUMN」「RENAME」「COMMENT」etc... のSQLを発行しながら管理します。
pm_intro.png
その他、リレーションによる外部キー、制約 etc...

DBとModelの比較同期

「project-manager」は単に名称だけでDB管理するだけでなく、「pg_class」や「pg_attribute」などにアクセスしてDB情報を取得します。

  • DB → Model 差分更新
  • Model → DB 差分更新

といった処理も行えます。

ただし、「pg_class_id」「attnum」などはデータが再構築された場合、仕様上復旧できません

内部の pg_class アクセスの一例


SELECT origin.*,
       pg_class.oid as foreign_class_id,
       pg_class.relname as foreign_relname,
       pg_attribute.attnum as foreign_attnum,
       pg_attribute.attname as foreign_attname
       FROM 
       (
       SELECT 
            pg_constraint.conrelid
            , pg_constraint.conname
            , pg_class.oid as pg_class_id
            , pg_class.relname
            , pg_attribute.attnum
            , pg_attribute.attname
            , pg_constraint.confrelid
            , pg_constraint.confkey
            , pg_constraint.contype
            , pg_constraint.confupdtype
            , pg_constraint.confdeltype
        FROM  pg_constraint
        LEFT JOIN pg_attribute ON pg_constraint.conrelid = pg_attribute.attrelid 
        AND pg_attribute.attnum = ANY(pg_constraint.conkey)
        LEFT JOIN pg_class ON pg_constraint.conrelid = pg_class.oid
                    WHERE pg_constraint.contype = 'f' AND pg_constraint.conrelid = '16848'
                ) AS origin
                LEFT JOIN pg_attribute ON origin.confrelid = pg_attribute.attrelid 
                AND pg_attribute.attnum = ANY(origin.confkey)
                LEFT JOIN pg_class ON origin.confrelid = pg_class.oid;

PHPファイル書き出し

Modelを設定したら「PHP Export > PHP Model」で、Model定義ファイルをエクスポートします。
pm_export_window.png
Model以外にもエクスポートでき、「All Files」するとMVCの基本プログラムを全て書き出します。
ちなみに、Model定義ファイルだけは必ず上書きします。

Model定義ファイル書き出しの例

「php-work」の場合「app/models/vo/」に書き出す
vscode_vo.png
モデル定義ファイルの内容 ※このファイルは人間は書きません

...
class _Report extends PwPgsql {

    public $id_column = 'id';
    public $name = 'reports';
    public $entity_name = 'report';

    public $columns = [
        'created_at' => ['type' => 'timestamp'],
        'report' => ['type' => 'text'],
        'reported_at' => ['type' => 'timestamp', 'is_required' => true],
        'sort_order' => ['type' => 'int4'],
        'student_id' => ['type' => 'int4', 'is_required' => true],
        'updated_at' => ['type' => 'timestamp'],
    ];

    public $primary_key = 'reports_pkey';
    public $foreign = [
            'reports_student_id_fkey' => [
                                  'column' => 'student_id',
                                  'class_name' => 'Student',
                                  'foreign_table' => 'students',
                                  'foreign_column' => 'id',
                                  'cascade_update_type' => 'a',
                                  'cascade_delete_type' => 'c',
                                  ],
    ];

    public $index_keys = [
    'reports_pkey' => 'CREATE UNIQUE INDEX reports_pkey ON public.reports USING btree (id)',
    ];

....

}

Controller/View作成

ここからはまだ、未実装な機能がたくさんありますが・・・
「Quick Create」を利用すると、Modelから、Controller、Viewを自動作成します。

Controller作成

  • Model を起点に Controller情報を作成
  • 継承ファイル(親)指定可能
pm_page.png

View(Action)作成

「Quick Create」を利用すると、デフォルトで「edit」「list」を作成します。
これらは、Controller では Action であり View ではテンプレートにあたります。
pm_view_list.png

pm_view_item_list.png

書き出したViewファイルの例

action: edit が存在すると、「new.phtml」「edit.phtml」「form.phtml」テンプレートファイルがエクスポートされます。
pm_view_file.png

「list.phtml」の例

...
  <? if ($this->student->values): ?>
  <? foreach ($this->student->values as $values): ?>
  <tr row-id="<?= $values['id'] ?>">
    <td><?= $this->student->linkEdit([], $values) ?></td>
    <td><?= $values['birthday_at'] ?></td>
    <td><?= $values['last_name'] ?></td>
    <td><?= $values['last_name_kana'] ?></td>
    <td><?= $values['first_name'] ?></td>
    <td><?= $values['first_nam_kana'] ?></td>
  </tr>
  <? endforeach ?>
  <? endif ?>

「form.phtml」の例

...
    <tr>
      <th><?= LABEL_STUDENTS_CODE ?></th>
      <td>
        <?= $this->student->formInput('code', ['class' => 'form-control']) ?>
      </td>
    </tr>
    <tr>
      <th><?= LABEL_STUDENTS_FIRST_NAME ?></th>
      <td>
        <?= $this->student->formInput('first_name', ['class' => 'form-control']) ?>
      </td>
    </tr>

このように、Model, View, Controller をフレームワークに対してプログラムソースを書き出します。
(現時点では「php-work」専用)

##その他もろもろ

CSV管理

  • 「db/recoreds/」内に、CSVファイルをエクスポート
  • アプリの設定項目など静的マスターなどで利用
  • ローカライズ対応

SQLファイルエクスポート

Model定義ファイルから、DB全定義のSQLをエクスポートできます。
(フレームワーク内でスクリプト実行することも可能)
pm_export_sql.png
ちなみに、Migrateファイルは現在対応してません(ぽちぽちする度にバージョン管理は大変なので・・・)

  • 「PHP Export > SQL」で書き出し
  • 「php-work」の scripts/sql/create_sql_from_model.php を実行
  • エクスポート先は「php-work」の「db/sql/DB名.sql」

簡易DB定義書Excel書き出し

PostgreSQLのDBから、簡単なDB定義書をExcelでエクスポートできます。
(composer phpoffice/phpexcel が必要)
pm_php_excel.png

DB簡易閲覧

ざっとDBの定義を見ることもできますが、ER図作成機能は現状ありません。
pm_db_detail.png

とりあえず、ざっと紹介してみましたが、

自作してみた感想

  • 他のフレームワークの中身が想像できたり、今まで知らなかった発見がある
  • PostgreSQLの内部をちょっと垣間見た
  • 実際に案件で長年回してたので、それなりには使える(自称)
  • レイアウト作成やJSフレームワーク未対応だったり、テンプレートが柔軟性にかける
  • プログラム自動化を解放するタイミングが難しい(Modelは永続的に使える)
  • もっと効率を上げるには、設計・アルゴリズムの勉強が必要
  • 自作フレームワークは諸刃の剣なので、基本汎用フレームワークを使いましょう

プログラムメソッド解析

プログラム内のメソッドやパラメータの視覚化機能を旧バージョンで作ってましたが、現在は作成中・・・

今後は・・・

今回は、自作フレームワークの管理でしたが、将来的に「Laravel」「iOS/Android」「Python」対応も考えてはみたい(気持ちだけ・・・)

そのうち優秀な人が何かしら作って利用している可能性の方が高そうです。
ゆくゆくは全自動プログラム!・・・いや多分当分無理だと思います。

  1. Webサーバユーザの権限設定や、pg_hba.confなどの設定が必要

  2. ModelでDBスキーマが異なる場合は、Model毎に設定

  3. php-work を、git clone 処理機能あり

  4. Railsの設計を基本に「id」「created_at」「updated_at」「sort_order」を自動追加(必須項目)

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?