【PHP】ORM Idiormの導入を決意するまで
久々になっちゃいました 最近はインフラっぽいこともせず、とにかくOJTとデザインパターンについて コーディング規約やら書き方を教え、コードレビューをする毎日になっていました。
人が増え、それに対して今後こういうソースの書き方をしていこうと話すのは重要でもあり 骨の折れる作業です。
さて、冒頭はこの辺にしておいて 今回はOR/Mのお話です。
今使っているFWについてはもしかしたらちょろっと書いたかもしれませんが Monobitエンジン付属のMWFフレームワークというものを使っています。
また、別会社への移管をしていた関係もあり、FWののソースがどこで どこに手を入れたのかわからない状態です。 ※正確にはSVNのログを追えばわからなくはないとは思うのですが・・・
そんなFWの中で少しでも綺麗に見やすいソースに。 そんな感じでリファクタリングもしていきつつ、テスト書きつつmigrationを入れたり色々揃えてきたわけです。
最近は一人開発から人数も増えてきて 開発チームっぽくなってきたのですが、やはり問題は山積みです。
軽量FWに近いのでOR/Mというものがありません。 どうしているかというと、PDOで接続をして直接queryを投げています。
何が悪いか?何も悪くないのですが、取得する方法が色々あるのです。 多分色んな人が便利だとうろ思って同じようなmethodを追加していったのでしょう。 聞くこともなく、忙しいからを理由に。 なのでDBからのデータ取得に関するフォーマットが決まっておらず、transaction処理も(これはまた別の話ですが)適当になっていたり。
そんな中、どれを使えばいいのだろう?このソースではこれ、あっちのソースではあれを使って、でも取得結果は一緒で。。。 ということで今後今まで使っていた資産を使わずにQueryを投げる用の新しいmethodを用意しました。
こういう事するからそうやって増えていくんだよ。ってわかっていながらも。 色々試行錯誤してQueryを投げるためにエラーチェックも入れ、環境に考慮した形で組んだつもりだったのですが 色々と問題も起きます。
PDOでQueryを投げて取得するときはfetchするのですが、fetchAllしている関係でそのmethodを使った結果 単一のデータを取得したくても配列の0番目に返ってきてしまうのです。
期待している返り値
array [ ["id"] => "1", ["hoge"] => "hogehoge", ["created"] => "2015-10-22 10:00:00" ]
実際の返り値
array [ [0] => [ ["id"] => "1", ["hoge"] => "hogehoge", ["created"] => "2015-10-22 10:00:00" ] ]
もちろん単一データを取得するときは期待している返り値のほうが扱いやすいですよね。 ということで単一データでも取れるようにしようかと色々思考錯誤したのですが、これ以上取得methodを増やしていけば同じような歴史を繰り返すに違いないと また、便利に色々とできるようにしたほうが使い勝手もいいだろうし、今はSelectについて考えてるけど、insertは?updateは?どうすんの? みたいなのが頭を過ぎります。
正直これ以上増やす事を考えるなら各エンジニアにPDOで投げてfetchでもfetchAllでも自由に使ってくれって思ったのですが あまりにも投げやりだと。
そこでOR/Mがなんとかしてくれるかなと思いました。
正直エディタの宗教戦争もありますが、OR/Mも一つの宗教戦争だと思います。 使う事が悪いわけではないですし、知識があればOR/Mなんて使わずにQueryを書いて投げたほうが速度は早いです。 学習コストもかかりますしね。
どっち派みたいなものはないので適材適所だとは思っていますが、今回のように開発をしていくうちにソースに統一性、一貫性がなくてなっていく場合は有効かなと思っています。 もちろん今まで作ったソースについてもリファクタリングが必要にはなってくるのですが。
OR/Mを入れる事におけるメリットとしてはSQL混入による視認性の低下を回避する事ということがあります。
SQL言語というのは非オブジェクト思考言語になります。細かい話は一旦置いときましょう。んじゃPHPはどうなんだよとか色々出てくるので。 要は継承やカプセル化ができない言語をソースに交える事により、オブジェクト思考言語と非オブジェクト思考言語が混ざることによる視認性の低下が懸念されます。 その点OR/Mは拡張性を持ち、永続化することが可能です。更にSQLの混入を回避できます。もちろん拡張性や視認性も上がります。
もちろんいいことだけでもないです。 正直OR/Mこそ、通常のSQLでのセキュリティ対策やSQL言語を知っている人こそ使うべきなのかな(道具として)と思っています。 OR/Mを使うことによってプレースホルダの問題を意識しなくても良くなり、むしろOR/Mで書いている人は極端な話SQL言語を覚えなくてもある程度のことはできてしまいます。 本当にこれで大丈夫か等考えずに組めてしまう部分がある。 更にSQL言語を知っていたとしてもOR/Mによって仕様が違うので、それぞれに学習コストがかかるのもデメリットと言えます。
結構前の話ですが、ORMがアンチパターンである11の理由とか結構有名になりましたよね。
今でももちろん賛否両論あるのですが、とにかく適材適所でもあり、チームのレベルや言語、デザインパターンやコーディング規約等色々な状況に対して導入すべきかをチームで考えればいいと思います。
ということで今回はMWFフレームワークにOR/Mを入れてみました。 この記事は別途書いていきますね。
因みに今回入れたOR/MはPHPで使えるidiormというものになります。 最近OR/M ActiveRecordをIdiorm & Parisで作るのが流行っているみたいですが 必要だったのはOR/MのみだったのでIdiormを入れてみました。
ただやはりMWFフレームワークで現在のソースに対応させるのに苦悩しながら組み込みをしましたので、別途ブログで共有できればと。
今回は長い話になり、技術的な要素が少ないですが、この辺にしておきたいと思います。