SlideShare a Scribd company logo
PHP版レガシーコード改善に 
役立つ新パターン 
ヤフー株式会社 
佐藤祐司 
2014/9/27 レガシーコード改善勉強会 #wewlc_jp
自己紹介 
佐藤 祐司 
• 2010年新卒入社 
• Webエンジニア 
• PHP 
@kuidaoring
今日話すこと 
• 私の業務とレガシーコード 
• パターンの紹介 
• これで幸せになれるのか
今日話すこと 
• 私の業務とレガシーコード 
• パターンの紹介 → 本日のメイン 
• これで幸せになれるのか
今日話すこと 
• レガシーコード改善の具体的な 
リファクタリングの具体的な方法 
• 今あるコードを何とかテストで保護して、 
自分が手を加える部分のテストを 
書けるようにしたい
今日話すこと 
• レガシーコード改善の具体的な 
リファクタリングの具体的な方法 
• 今あるコードを何とかテストで保護して、 
自分が手を加える部分のテストを 
書けるようにしたい
私の業務とレガシーコード
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
サービス 
サービス規模 
• 58.3億PV / 月 
• 1.4億UB / 月 
出典:Yahoo! JAPAN 媒体資料 2014年6月改訂版 (PDF) 
http://i.yimg.jp/images/marketing/portal/paper/media_sheet_open.pdf
サービス 
トップページを作る部署の中の一つ 
PJメンバー約40名 
• 開発約20名 
PCスマホアプリ… 
ここ
業務とレガシーコード 
こんなことありませんか? 
• 少ない自動テスト 
• リリース当時の開発メンバーはゼロ 
• どんどん開発メンバーが増える 
どうしてこんなふうになったのか
新規リリース時 
まずはローンチを目指す 
• ローンチ、リリース優先 
• ヒットするかはわからない 
ローンチだ!
リリース後 
サービスの成長を目指す 
• 機能を増やす 
• メンバーも少しづつ増える 
機能追加だ!
ある程度成熟して振り返ると 
• メンバーの入れ替わり 
• 歴史的経緯によるコード 
• 場当たり的な修正 
とりあえず 
直しました…! 
今⽇日からよろしく 
お願いします!
業務とレガシーコード 
• その時の判断が間違いだったかは 
わからない 
• 優先順位の話 
• ただしずっとそのままでいい 
というわけではない
業務とレガシーコード 
過去には一部似た状況になったが、 
• 有志による改善活動 
• 社内でもノウハウがたまってきた
ユニットテスト拡充 CI整備
開発フロー整備
業務とレガシーコード 
どうしたか 
• レガシーコードを地道に改善 
• レガシーコードを作りにくくする 
仕組みや体制を整備 
地道に少しづつ改善を進めた
パターンの紹介
パターンの紹介 
• レガシーコード改善の具体的な 
リファクタリングの具体的な方法 
• 今あるコードを何とかテストで保護して、 
自分が手を加える部分のテストを 
書けるようにしたい
PHPって 
• Webに特化 
• 置けば動く 
• HTMLに埋め込める 
• テンプレートエンジン 
• 標準関数が豊富
PHPにおけるレガシーコード 
• 環境に依存 
• 構造を持たない 
• スーパーグローバル変数 
• $_GET, $_POST, $_SESSION など 
• 不用意なexit
PHPにおけるレガシーコード 
サンプルコードを用いて説明 
• adminユーザと一般ユーザで見せる 
メニューを変更する
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
どう対応するのか 
1. テストを書けるようにする 
2. テストで保護する 
3. リファクタリング 
4. テスト、リファクタリングを繰り返す
どう対応するのか 
1. テストを書けるようにする 
2. テストで保護する 
3. リファクタリング 
4. テスト、リファクタリングを繰り返す
なにが問題になるか 
• DBに接続する 
• exitでスクリプトが終了 
• getパラメータが必要 
• ビューとロジックの混在
DBに接続
exitで終了
スーパーグローバル 
変数を参照して 
パラメータ取得
ビューとロジックが 
混在
どうにかしてテストを 
書けるようにするためのパターン
• 関数オーバーライド 
• ラップ関数
関数オーバーライド
関数オーバーライド 
• 名前空間を使って組み込み関数などを 
上書き 
• 実際には上書きしてない 
• 元ネタ 
PHPでネイティブ関数を含むコードのテスタビリティを上げる2つの方法 
- 絶品ゆどうふのタレ 
http://yudoufu.hatenablog.jp/entry/20110808/1312828535 
• 名前空間が接合部になる
関数オーバーライド 
index.php func() 
外部 
リソース 
プロダクトコード
関数オーバーライド 
index.php func() 
外部 
リソース 
プロダクトコード 
func() 
テストコード
接合部 
接合部とは、その場所を直接変更しなくて 
も、プログラムの振る舞いを変えることの 
出来る場所である 
レガシーコード改善ガイドより
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
コンストラクタで 
渡すオブジェクトによって 
振る舞いを変更できる
名前空間 
PHP5.3から導入 
PHP: 名前空間 ‒ Manual 
http://php.net/manual/ja/language.namespaces.php 
他の言語のパッケージやモジュールに相当
名前空間 
名前空間の影響を受けるもの 
• class 
• interface 
• trait(5.4以降) 
• 関数 
• 定数(const)
定義
参照
名前空間 
• 名前空間の中であれば、 
組み込み関数やグローバルな関数と 
同じ名前の関数を定義できる 
• 同じ名前空間内であれば、 
名前空間の指定を省略できる
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
組み込み関数と同じ 
名前で定義できる
名前空間内の関数が 
呼ばれる
関数オーバーライド 
どういう時に有効か 
• 上書きしたい対象が関数でしか 
用意されていない 
外部の影響を受ける組み込み関数を 
そのまま使っている場合など
ラップ関数
ラップ関数 
変数の参照などを直接行うのではなく 
関数を経由して行うようにする
どう対応するのか
なにが問題になるか 
• DBに接続する 
• exitでスクリプトが終了 
• getパラメータが必要 
• ビューとロジックの混在
どう対応するのか 
1. テストを書けるようにする 
• 環境の分離 
• スーパーグローバル変数の間接参照 
• exitの検討 
2. テストで保護する 
3. リファクタリング 
4. テスト、リファクタリングを繰り返す
どう対応するのか 
1. テストを書けるようにする 
• 環境の分離 
• スーパーグローバル変数の間接参照 
• exitの検討 
2. テストで保護する 
3. リファクタリング 
4. テスト、リファクタリングを繰り返す
環境の分離 
テスト実行時にもDBに接続しにいってしま 
う 
• DBに接続する関数をなんとかしたい 
• 関数オーバーライドを使う
環境の分離 
1. テスト対象のスクリプトに 
名前空間の定義を追加 
2. テストコードでテスト対象と 
同じ名前で名前空間の定義を追加 
3. 上書きしたい関数と同じ名前の 
関数をテストコードで定義
環境の分離 
1. テスト対象のスクリプトに 
名前空間の定義を追加 
2. テストコードでテスト対象と 
同じ名前で名前空間の定義を追加 
3. 上書きしたい関数と同じ名前の 
関数をテストコードで定義
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
環境の分離 
1. テスト対象のスクリプトに 
名前空間の定義を追加 
2. テストコードでテスト対象と 
同じ名前で名前空間の定義を追加 
3. 上書きしたい関数と同じ名前の 
関数をテストコードで定義
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
すでに他の名前空間が 
あればその下に追加
環境の分離 
1. テスト対象のスクリプトに 
名前空間の定義を追加 
2. テストコードでテスト対象と 
同じ名前で名前空間の定義を追加 
3. 上書きしたい関数と同じ名前の 
関数をテストコードで定義
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
関数オーバーライド 
プロダクトコード 
index.php db_get_user() 
DB
関数オーバーライド 
プロダクトコード 
index.php 
テストコード 
db_get_user() DB 
db_get_user()
注意 
名前空間を定義することで 
関数が呼び出せなくなる場合がある
名前空間の定義を 
追加
参照できなくなる
名前空間の影響 
どうするか 
• 関数を名前空間の外に再定義
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
どう対応するのか 
1. テストを書けるようにする 
• 環境の分離 
• スーパーグローバル変数の間接参照 
• exit, dieの検討 
2. テストで保護する 
3. リファクタリング 
4. テスト、リファクタリングを繰り返す
スーパーグローバル変数 
変数なので代入して書き換えが可能 
• 他のテストケースに影響してしまう 
• 変数を直接参照しなければいい 
• ラップ関数を使う
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
どう対応するのか 
1. テストを書けるようにする 
• 環境の分離 
• スーパーグローバル変数の参照 
• exitの検討 
2. テストで保護する 
3. リファクタリング 
4. テスト、リファクタリングを繰り返す
exitの検討 
exitのなにが問題になるか 
• スクリプトを終了 
PHPUnit自体も終了する 
• exitは関数ではない
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
実行されない
exit、dieの必要性の検討 
成功・失敗も 
わからず終了
exitの検討 
exitは言語構造、予約語 
• 名前空間内でも「exit」という 
名前の関数を定義できない 
• 「関数オーバーライド」が使えない
exitの検討 
どうするか 
• returnの代わりに使ってませんか 
• returnに変える 
• exitする部分をラップ関数にする 
• その後に関数オーバーライドを使う
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
どう対応するのか 
1. テストを書けるようにする 
2. テストで保護する 
3. リファクタリング 
4. テスト、リファクタリングを繰り返す
テスト 
• ビューとロジックが混ざっているので 
ロジックのみの検証はおそらく不可能 
• 条件によって変わるビューを検証する 
• assertRegex, assertContains 
• HTMLであればassertTagなど
どう対応するのか 
1. テストを書けるようにする 
2. テストで保護する 
3. リファクタリング 
4. テスト、リファクタリングを繰り返す
リファクタリング 
まずはベタなものを適切な単位に分離 
• ファイルを分離 
• 関数に分離 
• クラスに分離
課題 
globalが邪魔をする 
• グローバル変数ではなくなる 
ことによってうまく動作しなくなる 
• 「コンパイラまかせ」が使えないので 
動かすまでわからない
課題 
• 関数内でグローバル変数を参照している 
部分を引数に置き換えるように 
リファクタリングする 
• 地道に。。。 
• 参考 
テスト不能な PHP コードをリファクタリングするための戦略 
http:/www.ibm.com/developerworks/jp/opensource/library/os-refactoringphp/
これで幸せになれるのか
これで幸せになれるのか 
これだけで根本解決はできない 
• とりあえずテストは書けるようになった 
• 適用できるケースは 
それほど多くない(かも) 
• 今回は「今」できること
レガシー 
小改善 テストで 
保護 
リファクタ 
リング 
イケてる
これで幸せになれるのか 
全体を考えて設計の変更などを 
行う必要がある 
• フラットなPHPからフレームワークへ 
• 地道にテストコードを増やしていく 
継続的な改善が必要
ありがとうございました

More Related Content

PPTX
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
Tadahiro Ishisaka
 
PDF
『データ解析におけるプライバシー保護』勉強会 #2
MITSUNARI Shigeo
 
PDF
llvm入門
MITSUNARI Shigeo
 
PDF
AWSではじめるMLOps
MariOhbuchi
 
PDF
シリコンバレーの「何が」凄いのか
Atsushi Nakada
 
PDF
NVIDIA GPUで作るHeadless X11 Linux
Tomoki SHISHIKURA
 
PPTX
Phpcon2015
Hiroshi Tokumaru
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
Tadahiro Ishisaka
 
『データ解析におけるプライバシー保護』勉強会 #2
MITSUNARI Shigeo
 
llvm入門
MITSUNARI Shigeo
 
AWSではじめるMLOps
MariOhbuchi
 
シリコンバレーの「何が」凄いのか
Atsushi Nakada
 
NVIDIA GPUで作るHeadless X11 Linux
Tomoki SHISHIKURA
 
Phpcon2015
Hiroshi Tokumaru
 

What's hot (20)

PDF
『データ解析におけるプライバシー保護』勉強会
MITSUNARI Shigeo
 
PDF
ストリーム処理プラットフォームにおけるKafka導入事例 #kafkajp
Yahoo!デベロッパーネットワーク
 
PPTX
Reinforcement Learning(方策改善定理)
Masanori Yamada
 
PPTX
差分プライバシーとは何か? (定義 & 解釈編)
Kentaro Minami
 
PPTX
設計と実装で 抑えておきたい サービスクラスと例外
Takuya Sato
 
PPTX
MLflowで学ぶMLOpsことはじめ
Kenichi Sonoda
 
PDF
なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? -
健人 井関
 
PPTX
試して、比べて、使ってみる時系列における異常検知。
浩 陳
 
PPTX
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
NTT DATA Technology & Innovation
 
PDF
InternetWeek2022 - インターネット広告の羅針盤
MicroAd, Inc.(Engineer)
 
PPTX
分散トレーシングAWS:X-Rayとの上手い付き合い方
Recruit Lifestyle Co., Ltd.
 
PDF
機械学習で泣かないためのコード設計
Takahiro Kubo
 
PPTX
社会心理学者のための時系列分析入門_小森
Masashi Komori
 
PDF
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
Takuto Wada
 
PDF
爆速クエリエンジン”Presto”を使いたくなる話
Kentaro Yoshida
 
PPTX
がっつりMongoDB事例紹介
Tetsutaro Watanabe
 
PPTX
【DL輪読会】TrOCR: Transformer-based Optical Character Recognition with Pre-traine...
Deep Learning JP
 
PDF
Where狙いのキー、order by狙いのキー
yoku0825
 
PPTX
Redisの特徴と活用方法について
Yuji Otani
 
『データ解析におけるプライバシー保護』勉強会
MITSUNARI Shigeo
 
ストリーム処理プラットフォームにおけるKafka導入事例 #kafkajp
Yahoo!デベロッパーネットワーク
 
Reinforcement Learning(方策改善定理)
Masanori Yamada
 
差分プライバシーとは何か? (定義 & 解釈編)
Kentaro Minami
 
設計と実装で 抑えておきたい サービスクラスと例外
Takuya Sato
 
MLflowで学ぶMLOpsことはじめ
Kenichi Sonoda
 
なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? -
健人 井関
 
試して、比べて、使ってみる時系列における異常検知。
浩 陳
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
NTT DATA Technology & Innovation
 
InternetWeek2022 - インターネット広告の羅針盤
MicroAd, Inc.(Engineer)
 
分散トレーシングAWS:X-Rayとの上手い付き合い方
Recruit Lifestyle Co., Ltd.
 
機械学習で泣かないためのコード設計
Takahiro Kubo
 
社会心理学者のための時系列分析入門_小森
Masashi Komori
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
Takuto Wada
 
爆速クエリエンジン”Presto”を使いたくなる話
Kentaro Yoshida
 
がっつりMongoDB事例紹介
Tetsutaro Watanabe
 
【DL輪読会】TrOCR: Transformer-based Optical Character Recognition with Pre-traine...
Deep Learning JP
 
Where狙いのキー、order by狙いのキー
yoku0825
 
Redisの特徴と活用方法について
Yuji Otani
 
Ad

Similar to PHP版レガシーコード改善に役立つ新パターン #wewlc_jp (20)

PDF
MakeGoodで快適なテスト駆動開発を
Atsuhiro Kubo
 
PDF
関西Php勉強会のlimeの話
Hisateru Tanaka
 
PDF
PHPの今とこれから2019
Rui Hirokawa
 
PDF
徹底攻略!PHP5.4
Takuya Sato
 
KEY
EC-CUBE + PHPUnit で 実践テスト駆動開発
Kentaro Ohkouchi
 
PDF
PHPUnit でテスト駆動開発を始めよう
Yuya Takeyama
 
PDF
PHPの今とこれから2025 (PHP Conference Japan 2025)
Rui Hirokawa
 
PDF
8時間耐久PHPUnitの教室
Yusuke Ando
 
PDF
CodeIgniter東京勉強会 2011.05.14
Takako Miyagawa
 
PDF
レガシーコードとの付き合い方とテストでの話
H Iseri
 
PDF
Modern PHP Programming @ PFI Seminar
Sotaro Karasawa
 
PDF
PHPの今とこれから2021
Rui Hirokawa
 
PDF
International php conference 2016 参加レポート
Ryosuke Miyahara
 
PDF
ライバルに差をつけろ! カスタム○○○ 猛特訓ゼミ!!!+α
takashi ono
 
PPTX
PHP基礎勉強会
Yuji Otani
 
PDF
Introduction to Continuous Test Runner MakeGood
Atsuhiro Kubo
 
PDF
PHPの今とこれから2023
Rui Hirokawa
 
PPTX
Php development efficiency improvement
伸幸 茂木
 
PDF
PHPの今とこれから 2013
Rui Hirokawa
 
PDF
Getting Started with Testing using PHPUnit
Atsuhiro Kubo
 
MakeGoodで快適なテスト駆動開発を
Atsuhiro Kubo
 
関西Php勉強会のlimeの話
Hisateru Tanaka
 
PHPの今とこれから2019
Rui Hirokawa
 
徹底攻略!PHP5.4
Takuya Sato
 
EC-CUBE + PHPUnit で 実践テスト駆動開発
Kentaro Ohkouchi
 
PHPUnit でテスト駆動開発を始めよう
Yuya Takeyama
 
PHPの今とこれから2025 (PHP Conference Japan 2025)
Rui Hirokawa
 
8時間耐久PHPUnitの教室
Yusuke Ando
 
CodeIgniter東京勉強会 2011.05.14
Takako Miyagawa
 
レガシーコードとの付き合い方とテストでの話
H Iseri
 
Modern PHP Programming @ PFI Seminar
Sotaro Karasawa
 
PHPの今とこれから2021
Rui Hirokawa
 
International php conference 2016 参加レポート
Ryosuke Miyahara
 
ライバルに差をつけろ! カスタム○○○ 猛特訓ゼミ!!!+α
takashi ono
 
PHP基礎勉強会
Yuji Otani
 
Introduction to Continuous Test Runner MakeGood
Atsuhiro Kubo
 
PHPの今とこれから2023
Rui Hirokawa
 
Php development efficiency improvement
伸幸 茂木
 
PHPの今とこれから 2013
Rui Hirokawa
 
Getting Started with Testing using PHPUnit
Atsuhiro Kubo
 
Ad

More from Yahoo!デベロッパーネットワーク (20)

PDF
ゼロから始める転移学習
Yahoo!デベロッパーネットワーク
 
PDF
継続的なモデルモニタリングを実現するKubernetes Operator
Yahoo!デベロッパーネットワーク
 
PDF
ヤフーでは開発迅速性と品質のバランスをどう取ってるか
Yahoo!デベロッパーネットワーク
 
PDF
オンプレML基盤on Kubernetes パネルディスカッション
Yahoo!デベロッパーネットワーク
 
PDF
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
Yahoo!デベロッパーネットワーク
 
PDF
Persistent-memory-native Database High-availability Feature
Yahoo!デベロッパーネットワーク
 
PDF
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
Yahoo!デベロッパーネットワーク
 
PDF
eコマースと実店舗の相互利益を目指したデザイン #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
ビッグデータから人々のムードを捉える #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
サイエンス領域におけるMLOpsの取り組み #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
「新しいおうち探し」のためのAIアシスト検索 #yjtc
Yahoo!デベロッパーネットワーク
 
PDF
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
Yahoo!デベロッパーネットワーク
 
ゼロから始める転移学習
Yahoo!デベロッパーネットワーク
 
継続的なモデルモニタリングを実現するKubernetes Operator
Yahoo!デベロッパーネットワーク
 
ヤフーでは開発迅速性と品質のバランスをどう取ってるか
Yahoo!デベロッパーネットワーク
 
オンプレML基盤on Kubernetes パネルディスカッション
Yahoo!デベロッパーネットワーク
 
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
Yahoo!デベロッパーネットワーク
 
Persistent-memory-native Database High-availability Feature
Yahoo!デベロッパーネットワーク
 
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
Yahoo!デベロッパーネットワーク
 
eコマースと実店舗の相互利益を目指したデザイン #yjtc
Yahoo!デベロッパーネットワーク
 
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
Yahoo!デベロッパーネットワーク
 
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo!デベロッパーネットワーク
 
ビッグデータから人々のムードを捉える #yjtc
Yahoo!デベロッパーネットワーク
 
サイエンス領域におけるMLOpsの取り組み #yjtc
Yahoo!デベロッパーネットワーク
 
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
Yahoo!デベロッパーネットワーク
 
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
Yahoo!デベロッパーネットワーク
 
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
Yahoo!デベロッパーネットワーク
 
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
Yahoo!デベロッパーネットワーク
 
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
Yahoo!デベロッパーネットワーク
 
「新しいおうち探し」のためのAIアシスト検索 #yjtc
Yahoo!デベロッパーネットワーク
 
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
Yahoo!デベロッパーネットワーク
 

PHP版レガシーコード改善に役立つ新パターン #wewlc_jp