PHPを始めたばかりのころ自分なりにやってた工夫と、それこうした方がいいんじゃないのという提案

PHP Advent Calendar jp 2010 に参加しています。
PHP に関する記事を日替わりで書こうというイベントですね。
昨日の slywalker さんに続いて6日目。

さて PHP というかウェブに関することは何もかも独学で
始めたばかりの頃は特に
一般的なやり方というものがさっぱりわかっていなかったので
わかることの範囲内で自分なりの工夫をしてました。

そういう経験はとても大切だと思うんだけど、
かなり無駄な手間がかかっていたり
やらない方がいいことをやっていたりもしたので
導いてくれる人がいなかったその頃の自分に対して
こうやってはどうか、という提案を書いてみようと思います。

「なに、そんな愚かしいことしてたの」
と言いたくなるようなこともあるので
そんな話を晒すのもどうかと思ったんだけど
生まれたときはみんな赤子だったんだ。

同じような境遇の人はきっといると思うので
少しでも足しになればいいなと思いつつ。

設定ファイルの配置

最初の頃は設定ファイルと本体を切り分けることもしてなかった。
ドメインやサーバ環境に関する値も全部本体のコードにベタ書き。

でもそれだと
環境が変わったらすべてのファイルを書き換えないといけないし
どこに何が書かれてるかわからなくなるから
設定に関する部分は別ファイルにまとめた方がいいことに気がついた。

というわけで

  • 環境や時期によって変わる値などは設定用の別ファイルにまとめて書いて include / require する。
  • 他のファイルと混ざらないように、includes というフォルダを作ってその中に設定ファイルを入れる。
  • 設定ファイルは他の実行用 PHP ファイルと区別するため拡張子を .ini や .inc などにして、それらのファイルにはブラウザからアクセスできないように .htaccess で制限する。

ということをやってたんだけど
これはよろしくないですね。

設定ファイルはユーザーの手の届かないところに置きましょう

共用のレンタルサーバなんかだと
~/public_html あたりがドキュメントルートにしてあることが多いけど
そもそもドキュメントルートというものがわかってなかったので
とにかくファイルは public_html 以下に置くものだと信じて
それ以外の部分は一般人が触っちゃダメなんだと思ってた。

けど “public” の名のとおり
public_html は一般のユーザーがアクセスしてもいいものを置く場所なので
それ以外のものはできるだけ public_html の外に置いた方がいいですね。
その方が安全だしわかりやすい。

上の例で言えば、こうじゃなくて

.
`-- public_html
    `-- includes

例えばこんな感じ。

.
|-- public_html
`-- includes

レンタルサーバの中には
ドキュメントルート以下しか触らせてくれないのもあるけど
少なくともウェブのサービスを置くならそこは使わない方がよさそうです。

拡張子について言えば、
設定ファイルだからといって他のものに変えたりせず
中身が PHP なら .php でそろえた方がいいんじゃないかな。
(中身が PHP なら、です。設定といっても php.ini とかそういうことではなくて)

もし他の言語も使うことになった場合
.ini ではいったい何のファイルなのかわからなくなるから。

制御構文の書式

PHP の制御構文は
対象となる文が1つしかなければ
こういう具合に

if (!$id) $id = 1;  

式の後にそのまま続けて書いてもいいし、
複数の文が続く場合と同じようにブレスでくくってもいい。

if (!$id) {
	$id = 1;
}

最初は前者のやり方をとってた。
省略できるものは省略した方が楽だし
状況に応じて書式を自由自在に操る俺かっこいい!

でもこれは逆。
長い目で見たらたぶん後者の方が楽です。

制御構文は1行でもブレスでくくりましょう

理由はいくつか。

{ } で明示しておくと
制御構文であることがわかりやすいからというのがひとつ。
自分が後で見直すときも、他の人が見るときも
ぱっと見で何やってるのかわかりやすいというのは大事ですね。

しかもこの方があとで書き直すときに楽です。

後から構文内でやりたいことが増えるかもしれないし、
処理を関数やクラスのメソッドに移したくなるかもしれない。
そしたら return が入るんですよ大抵。
だからきっと行が増える。

そんなときにわざわざ (式) の後に { を加えて
改行して閉じ } を付けて
その間に文を入れてなどとするのはあまりにめんどくさい。

1行で済むことは少なくなってくるので、
最初からブレスでくくって複数行対応しておきましょう。

1行だろうが複数行だろうが同じ書式にするもう一つの理由は
ルールが少ない方が楽だからです。
このときはこう、そのときはこうという約束は
できるだけシンプルにしたい。これだいじ。

横長くなる文の扱い

例えば SQL を書いてるとどんどん横長くなって見づらいので

$query = "SELECT * FROM posts WHERE userid={$user_id} ORDER BY created_at DESC LIMIT 10";

これは行を分割してやればいいんじゃないかと思いついて
こんな風に書いてた。

$query = "SELECT * FROM posts";
$query .= " WHERE userid={$user_id}";
$query .= " ORDER BY created_at DESC";
$query .= " LIMIT 10";

確かに横長くなるよりはいくぶん見やすいかもしれないけど
これはめんどくさい。
改行するごとに $query .= って書かないといけないし
文末にはクォーテーションマークを閉じてセミコロンつけないといけないし。

また .= というのは文字列を結合してねという命令なので
その都度結合のために無駄な処理が発生する。

素直に改行しましょう

こんな感じですかね。

$query = "
	SELECT * FROM `posts`
	WHERE `user_id` = {$user['id']}
	ORDER BY `created_at` DESC
	LIMIT 10;
";

これならよそから SQL 文をコピペするときも
何の加工も必要ないので楽ちん。

追記: ヒアドキュメントにしない理由

長くなるので補足記事にしました。

変数の扱いについて

ユーザーの ID や名前や URL を扱うのに
最初は短く $id, $name, $url などという変数名を使ってたんだけど
これだと何の ID か何の名前かわからなくなるので
なら変数名に接頭辞をつけて統一しようと思った。

$user_id, $user_name, $user_url など。

最初のよりはわかりやすくていいんだけど、
これは後々ものすごくめんどくさい事態に繋がる。

例えばテンプレートエンジンの Smarty を使うとして、
変数を渡すのにいちいち

$smarty->assign('user_id', $user_id);
$smarty->assign('user_name', $user_name);
$smarty->assign('user_url', $user_url);

などとやっていたので、数が増えたら実にめんどくさい。
compact 関数を使ってもいいけど

$smarty->assign(compact('user_id'));
$smarty->assign(compact('user_name'));
$smarty->assign(compact('user_url'));

いやめんどくささ変わってないですよ。

配列にまとめよう

こんなのこうすれば一発ですね。

$user = array(
	'id' => 1,
	'name' => 'msng',
	'url' => 'http://www.msng.info/',
);
:
:
$smarty->assign(compact('user'));

同じ対象に属する情報はひとつの変数にまとめて
配列で持っておきましょう。
関数やクラスのメソッドに渡すときの手間が一気に減りますね。

追記: Smarty に連想配列をそのまま渡さない理由

長くなるので補足記事にしました。

などなど

昔書いたソースを見ていたら
ああそんなことやっちゃって・・・
と思うことが続々と出てくるんだけど
全部書いてたらきりがないのでこのへんで。

そのように思えるということは
そのぶん成長しているということなので
喜ばしいことと受け止めるのがよさそうですね。

いま書いているコードを半年後ぐらいに見て
「ああ、あの頃はこんなふうにやってたんだな」と
甘酸っぱい思いができるようにしたいところ。

ただそうなると、半年後の自分も今の自分に対して
「あなたがもうちょいお利口なコード書いてくれてりゃ今頃・・・」
と思うんだろうか。ごめんなさいごめんなさい。

明日は

Advent Calendar の担当、明日は sotarok さんの登場。
かの『パーフェクトPHP』の著者に名を連ねる方ではないですか。


パーフェクトPHP (PERFECT SERIES 3)

楽しみにしてます。

関連エントリ

  • このエントリーをはてなブックマークに追加

7 Responses to “PHPを始めたばかりのころ自分なりにやってた工夫と、それこうした方がいいんじゃないのという提案”

  • 通りすがり

    2010/12/07 18:30

    改行込みの長い文字列の記述方法は、「ヒアドキュメント」というのも一般的です。http://www.php.net/manual/ja/language.types.string.php#language.types.string.syntax.heredoc
    この「ヒアドキュメント」は、スクリプト系言語だと大抵使えたりします。
    また、PHP 5.3.0以降は、Nowdoc構文というのも追加されてます。
    http://www.php.net/manual/ja/language.types.string.php#language.types.string.syntax.nowdoc

  • 2010/12/07 19:03

    ありがとうございます。「ヒアドキュメントにしない理由」を追記しました。

  • とおりすがり

    2010/12/08 10:27

    最後の箇所は
    $smarty->assign($user);
    とした方がすっきりする気がします。

  • 2010/12/08 12:46

    ありがとうございます。理由を追記しました。

  • shin

    2010/12/08 13:58

    ダブルクォートにしてもヒアドキュメントにしても、先頭のブランクが気に入らないという人もいそうですよね。
    無駄といえば無駄ですが、改行でexplodeしてtrimしてimplodeしてたころもありました。SQLログに改行入れたくない気分だったんです。

  • 2010/12/08 14:23

    確かに無駄ですが、おもしろいですね。正規表現で置換するのとどっちが軽いかな。

  • 2010/12/09 11:58

    SQLの書き方の変遷(最終的に落ち着く先も含めて)が自分と全く一緒で思わず頷いてしまいました。
    素直に改行方式はSQLを考えながらそのまま書いていけるのでよいですね。