フレームワークに頼らず素のPHPでオブジェクト指向を意識しながらコードを書いてみる(1)

2019/01/03

普段、フリーランスのエンジニアとして客先常駐している管理人のSです。

エージェントから仕事を紹介されて現場に赴くという、いわゆるSESな案件に携わっております。

この記事を書いたきっかけ

この記事を書いているのは、現在の契約があと3カ月ぐらいで更新(年度末まで)、というタイミング。

このまま行けば、相当やらかさない限りは、継続になると思われる、のですが・・。

現在の環境はあまりにも心地よくて、基本は定時で終了、負荷も低くて、たまーに忙しくなるだけ、という感じ。

しかも月の稼働を130時間ぐらいに設定していただいているので、週1ぐらいで休みを取りつつ、自宅で自分のWebサービス開発に勤しんでおります。

・・とは言え、案件内容が技術的にまっっっったく大したことしていないので、これは環境を変えないと落ちぶれていく一方では!?と悩みつつ、ずるずる来ています。

年齢的にもアレなので、このまま行くと、「いやー、Javaとか.NETは経験だけ長かったんですけど、(PHP|Ruby)は業務経験ないんですよねー、テヘ♪」って言ってるだけのオッサンになってしまいそう。

これは相当やばい…。

理想としては、フルリモートである程度単価の高いお仕事が頂けるようになりたいのですが、となるとそれを満たせる言語は PHP か Ruby になると思われます。

が、さすがに業務経験ゼロで「いやー、プログラミングなんて結局は代入/ループ/条件分岐の組み合わせだし、言語なんてどれも一緒ですよ~」なんて能天気なこと言えません・・。

と言う訳で、ちょうど欲しいプログラムがあったので、実務経験のないPHPで書きつつ、記事としてアウトプットしてみようと思ったのでした。

ショボさがばれる可能性は大いにありますが、ここしばらくフルスクラッチでコード書いてないし、ともあれやってみましょ。

特定の言語を業務上で経験していないとしても、クラス設計の考え方やメンテナンス性を考慮したコーディングが出来れば、エンジニアとしての価値を見出してくれる組織はあったりするかも・・?「業務経験なくても、それくらいのスキルがあるなら、ゼヒうちの仕事手伝ってほしい!」ってお声掛けいただけないかしら、という希望をひそかに抱きつつ作ってみるのです。

余談:「業務経験」ってなんなの?

よく、業務経験のアリ/ナシが問われますが、この言葉の定義自体も結構あやふやな気はします。

僕の場合だと、期間だけでいえば、Javaを使ったプロジェクトに10年以上携わった、という実績だけはあるんです。(Java 1.4 の時代にSwing使ってました。間が空いて、今のプロジェクトでは Java 8 。)

でもその実、「君はチームリーダーとしてマネジメントできる人間を目指しなさいね」と暗黙のレールが敷かれていたので、コーディング経験としては密度がスカスカなんです。特に後半は Microsoft Project でプロジェクト管理+Excel仕様書で徹夜・・みたいなのが多かったり…。

逆にPHPに関しては、フリーランスになってから(SESではなく)クライアントさんとの直案件で、

  • WordPress + Welcart で有料メルマガを販売
  • 課金時のフックでMailChimpと連携させて配信先に登録

なんていう外部APIとの連携なんかを有償でやっていたりします。

コーディングはもちろん、クレカの洗い替えが自動でできずに「キーッ!」ってなってその場しのぎのスクリプト組んだり、はたまたメルマガ購入したお客さんからの問い合わせやクレーム対応なんかの顧客サポートまで、全部一人でやっていた、なんていう経験もあります。

はたまた、とある社長さんから

「うちのECシステム、むかーしフルスクラッチで作ってもらったんだけど、作ってもらった会社に改修の見積もり出したらさー、こっちの予算と桁が違ったんだよね。なんとかならん?」

って言われて、3万円で対応したこともありました。(多分、時給500円以下)

が、これらを「業務経験アリ」にカウントできるかというと、どうなんでしょね・・?

欲しいプログラム

さて、欲しいプログラムというのは、複数のRSSフィードから記事を引っ張ってきてくれる、というもの。RSS Aggregatorとでも言うんでしょうか。

  • RSS URL(複数可)を登録しておくと一定期間ごとにFeed確認→1Feedにつき最新記事数件を取得してくれる。
  • 自分が読むためのものではなく、最近の記事一覧として自サイトで紹介したい。(もちろん詳細は「続きはこちら→」で元のサイトに飛ぶようにする)
  • このサイトのTech系ポッドキャスト一覧のページに使用予定。

といった内容です。

現在はWordPressのプラグインを使っていて、もともと公式サイトにアップされていたものに手を加えたんですが、アクセスがあるたびにFeed更新をチェックしに行くのでメチャ遅いのです。(というのに加え、ソースコードもOOPを意識していない作りになっていたので修正も大変だったのです。)

なので、n時間毎にデータを取得して、表示する際には全てキャッシュ済みFeedデータを見に行くようなモノが欲しいのでした。

クラスを考える

取りあえず登場するオブジェクトを挙げつつ、UML的に書いてみます。

登場する主要クラスは、

  • Channel
    • 1つのRSSに関する情報を保持するクラス。1つのRSS Feed(=ブログが吐き出す1つのFeed)を1番組として扱う。
  • Episode
    • 1つのエピソード(=1回分の配信コンテンツ)に関する情報を保持するクラス。1Channelが複数のEpisodeを出力する。
  • Storage
    • Feed 情報を保存しておくクラス。DBやファイルを想定。
  • Aggregator
    • RSS Feed を取得して、Channel や Episode の最新情報を取得するクラス。

というぐらいで、まずはシンプルに。(あとで不足プロパティーが発見されて、いろいろ追加/修正する羽目に…)

コーディングで悩む…

にしてもいろいろと悩みまして、調べるのにとっても時間がかかりました。

例えば namespace の命名規則。

単数形にすべきか複数形にすべきか・・と悩んで “php namespace plural singular" と検索してみても、余計に混乱するだけだったり。

さらに namespace と フォルダの関係は・・と調べて読んでいたのがこちら。

でも、フォルダ名が models なのに namespace では Models\* ってなってて、気持ち悪い・・。

こういうものか?と PSR-4 の原点を当たってみたら、事例では両方とも先頭大文字で揃えてあったので、そこだけ変更してみました。

という訳で、namespace についてはPascalケース(アッパーキャメルケース)にして、フォルダ名もそれに合わせる方式を採用。

それからデータを保存/読み出すための Store クラスをどこに置くべきか、についても悩んだり。

データのやり取りは MVC の Model に責務を持たせるのが一般的なようです。

とは言え、DBへのアクセスは1つのクラスに任せたいし・・。

一番納得感があったのは、こちらでの回答。

Remember, the responsibilities of each layer are thus:

  • Controller – bridge between the model and view. Decides where to go next.
  • View – displays the data, gathers user input
  • Model – business logic, interface to data store.

One of the biggest gains is in maintenance and (later) expansion. In general:

  • If you need to change business logic, you should not need to modify your controller or view.
  • If you change your visual display, you should not need to modify your model or controller.
  • If you change your workflow, you should not need to modify your view or model.

さらには、getter/setter は必要か?問題とか。これに関してもいろいろと意見があるようで・・。

「カプセル化はしたいが、面倒なのは嫌だっ!」ということで、

  • とりあえず private でプロパティを用意しておく。
  • 必要が出てきたら考える。

ってことで後回し。

ついでにこれに関連して、メソッド内でクラスのメンバー変数(プロパティ)に対して更新を行うときの変数命名規則にも悩みました。

class Channel {
    private $title;
    public function __construct( $title ) {
        $this->title = $title
    }
}

にするか、$this 毎回つけるのだるいので、

class Channel {
    private $title;
    public function __construct( $p_title ) {
        $title = $p_title
    }
}

みたいなプレフィックス/サフィックスつけるか・・。

今回は $this-> つける方を選択。(記述量増えても分かり易い方向に振ってしまう、というのはJavaの経験が長いから・・?)

さらに言えば、変数宣言で型指定しないPHPだと、ハンガリアン記法の方が良いんだろうか?というのも迷うところ。

ずいぶん昔、Javaのプロジェクトで strMessage とかって書いてる人を見た時には、「今どきIDEの機能でマウスオーバーしたらClass定義分かるし、型を表す str って先頭の文字列、いらなくない?」って思ってたんですけど、PHPだとこれは当てはまらないようだし。

が、まぁハンガリアン記法は覚えきれなくてそのうち表記に揺らぎが出るので却下、としました。 (VB6とかの時代に、GUIのチェックボックスオブジェクトの命名が chkDelete になったり cbDelete になったり、ってのはありがちで、気持ち悪さの温床になるんですよね…。)

といった辺りで、長くなりそうなので2に続きます・・・。

ソースは Github に上げましたので、そちらをご覧ください。

実際の動きはこちらでご覧いただけます。

「一応は動いて、ひとさまに見て貰える」状態まで作ってから、振り返りつつこの記事を書いていますので、記事の説明と実際のソースが乖離している可能性が高いです。その点、ご了承ください・・。

ゆる募

冒頭に書いたように、お仕事環境を変えようと目論んでおります。

もし「この記事のレベルでもOK!」という懐の深い会社さんがありましたら、お仕事募集の案内をこちら↓のページに記載しましたので、ご覧頂ければ幸いです。m(_ _)m

次回はDB接続周りのお話を書く予定です。→書きました。

フレームワークに頼らず素のPHPでオブジェクト指向を意識しながらコードを書いてみる(2)