2014年11月2日日曜日

PHPデータ設計の基礎中の基礎「なし」の扱い方

PHPで空や偽など、データ無しの扱い方

PHPはWebアプリ用言語なので、フォームから値を受け取ったり、MySQLからデータを受け取ったりなどを前提とした言語となっています。
そこで、データが空だという事を簡単に判別するための関数が用意されています。

empty(); です。

これで入力データを判別できるようにデータ設計をするのが、拡張性が高くて不具合が発生しにくい設計になるでしょう。

"" (空文字列)
0 (整数 の 0)
0.0 (浮動小数点数の 0)
"0" (文字列 の 0)
NULL
FALSE
array() (空の配列)
$var; (変数が宣言されているが、値が設定されていない)

上記は全て『同じ』として扱います。

悪い設計例としては
1:なし
2:あり

正しい設計は
0:なし
1:あり

もし「なし」が無く全て有効な値だった場合は、1から開始してください。
0はデータ無しで統一すると、将来的に助かる場面がきっと出てきます。

プルダウンリストから選択する場合のインデックスは
0:不正 or 未選択
になります。
選択肢に0が無いのに0が来れば不正として処理。
選択肢に0があって0がくれば未選択となります。
有効なデータは必ず1番目以降を指定してください。


■未定義と空を区別したいケース

空の場合は空で上書きし、未定義の場合は変更無しというケースがあります。
その場合は、 isset(); を使ってください。
未定義とnullのみ同じとなります。

さらに未定義とnullを分けるような設計は複雑化しすぎなので、見直したほうが良いかもしれません。
is_null()を使うことで、nullかどうかの判別は可能です。

■MySQLの場合

nullは可能な限り使わないでください。 nullは特殊なオブジェクトなため、SQL文が面倒なことになります。
たとえば、 'foo' = null とは書けません。 'foo' IS NULL という特殊構文となってしまいます。
これは、nullを使うことで多くの制限が発生することを意味します。
デフォルト値はnullではなく0や空文字を使うようにしましょう。

初心者がPHPではまる3大ケース

PHP初心者がやりがちな間違ったコーディング方法を紹介します。

■文字列の比較

型を自動変換してくれる全ての言語で言える事ですが、文字列を比較する場合は「===」を使わなければなりません。
言語により微妙にこの部分の動作は異なります。

文字列を扱える言語で型が無い言語なんてのはありえません。
自動変換が行われる場合、どう変換されるのかを頭に入れておかないと意図しない結果を招きます。
PHPの比較構文による自動変換では、文字列の1文字目が数字になっていれば数値型に変換されます。
比較のどちらかが数字ならば、全て数値型で統一されます。このとき数字から開始していない文字列は「0」に変換されます。
すなわち、何も考えずに 「===」を使いなさいということになります。

基本的に「===」は変換処理が無いため高速処理されます。「==」を使わなければならない理由が無い限り「===」を使ったほうが良いでしょう。

特に注意したいのは swich文も自動変換が行われるという点です。
swich文のcaseには数値型と文字列型を混ぜないように注意しましょう。

■ && と and

&& と and は同じと勘違いして説明している人が非常に多いです。
両者は動作が異なりますので、結果も異なる事が多いです。
違いは、処理の優先度です。

$g = true && false;
$h = true and false;

上の2つは、結果が異なります。 if文でよく使われる構成ですよね。
ちょっと式が複雑化しただけで、異なる結果になってしまうのです。

「()」をつけて書き直すとこうなります。

$g = (true && false);
($h = true) and false;

上のような動作となります。 処理の優先度が異なります。

and や or は使う必要性が無いため、ソース上に見かけたら理解していない人が書いたと思って間違いありません。
普通は混乱を避けるため、使いやすさのため、 && || で統一されます。

■ソースファイルの最後に「?>」

ソースファイルがPHPで終わる場合、?>を書いてはいけません。
?>はphpの終わりではなく、htmlの開始タグと覚えましょう。
phpの処理では、htmlの出力がされる前でしか実行不可能な処理もあります。
?>の後に空白改行等が意図せず入り込み、PHPがエラーとなるケースがよくあります。


2014年10月26日日曜日

PhpStormの導入手順

最強と名高いPhpStormの導入手順。バージョン8 Windows版で説明いたします。

始めにPhpStormとは、どんなものかを簡単に紹介します。
PhpStormは有料のPHP統合開発環境(IDE)で、今最も人気があるだろうIDEとなります。
IDEの代表格と言えばEclipseなので、EclipseのPHP統合開発環境であるPDTと比較してみます。

基本時にPDTとPhpStormは同じと思って問題ありません。比較的スムーズに乗換えができると思います。
大きな違いは、PhpStormのソースコード静的解析能力になります。この解析能力が抜群な為に最強と言われているのです。EclipseのJava解析と同等レベルと言えば素晴らしさがわかると思います。
秀でているのはこの1点のみですが、これが素晴らしすぎる為に一押しIDEとなっています。

簡単に言いますと、Eclipseから細かな機能を削除して、PHPソースコード解析機能をしっかり作ったといった感じです。
不具合を減らすのに非常に有効なIDEとなっています。業務では必須と言っても過言ではないでしょう。


SVNを使う場合は、適当なコマンドラインクライアントを用意しておいてください。
http://www.visualsvn.com/downloads/
ここの1番目にあるApache Subversion command line toolsで動きます。
バージョンに注意してください。
適当なフォルダにSVN一式を入れたらPhpStormのDLとインストールします。


インストールが終わって起動した初期画面になります。
デフォルトの設定は使い物にならないと思いますので、まずは設定をしましょう。
Settings を選んでください。(プロジェクトを作ってからプロジェクトごとに設定もできます)


いくつかの設定は、最上位にScheme(スキーマ)というのがあります。
これは設定を別ファイルに保存していつでも呼び出せる物です。
まず始めにこのSchemeを設定してから、そこに各種設定を保存しましょう。

では変更が必要な設定を紹介します。
※重要としている物は、通常は行う必要があるでしょう。

■SVN設定(超重要)
SVNを使う場合は先にDLしたコマンドラインクライアントを指定する必要があります。
Version Control > Subversion
1番目のUse command line clientをDLした物にしてください。
svn.exeがコマンドラインクライアントとなります。

■改行コードをLFにしたい(重要)
Code Style > General
Line separator を Unix and OS X (\n) にしてください。

■インデントでタブを使いたい(任意)
Code Style > General > Default Indext Options
タブによるインデントを使いたい場合は、Use tab character をチェックしましょう。

■true/false/nullを小文字にする(重要)
これは変更必須です。
Code Style > PHP > Other
Convert True/False Constant to:
Convert Null constant to:
両方とも Lower case にセットしてください。

■自動改行をOffにしたい(重要)
Code Style > PHP > Wrapping and Braces
3行目あたりの Line breaks のチェックを外してください。
これをチェックしたままにすると、ひどいことになります。

■ファイルの文字コードをUTF-8にしたい(重要)
File Encodings
Project Encodingを UTF-8 にしてください。

■行表示をしたい(重要)
Editor > Appearance
Show line numbers をチェックしてください。

■タブとスペースを可視化したい(任意)
Editor > Appearance
Show whitespaces

■smartyがプロジェクトに含まれてる (任意)
PHP > Smarty
smartyタグの設定をしてください。静的解析の対象となります。

■フォントを変更(重要)
Colors & Fonts > Font
初期設定だと文字幅がガタガタになってしまうので、等幅フォントを指定してください。
Show only monospaced fontsにチェックを入れたままで好きなフォントを指定すると良いでしょう。
Source Code Proあたりになるでしょうか。

■変更したファイルをわかりやすく(任意)
Colors & Fonts > File Status
Modified の色を変更してください。 太字にできたらもっとよかったのにね。
gitやsvnといったバージョン管理を行う場合に重要となります。(ただし不安定)
ファイルを編集したのに色がかわらない場合、PhpStorm再起動で直ります。

■ショートカット(キーマップ)を変更したい(重要)
Keymap で変更できます。
初期設定でEclipseを選んでもEclipseとは異なるものがチラホラあるので、よく使うものはここで設定してください。


いよいよプロジェクトをインポート!(新規の場合は飛ばして Create New Project)
PhpStormでは、gitもsvnもその他も全て VCS(バージョン管理システム) と呼びます。


リポジトリにある物からプロジェクトを作る場合は、Check out from Version Control を選びます。
そこで使うVCSの種類、リポジトリの設定を行い、チェックアウトでDLします。

SVNを使う場合はSVNのバージョンに注意してください。プロジェクトで指定されているバージョンを必ず使ってください。 バージョン間の互換性は基本ありません。(チェックアウトだけなら大丈夫)

プロジェクトを作ったら、そのプロジェクトを開いて最後の設定を行いましょう。

■SFTP/FTPの設定



自分専用のテスト環境がある場合は、Automatic Upload にチェックしておくと楽です。
保存と同時にアップロードをしてくれ、アップロードもれを防げます。

■画面に表示しておくボタンを増やそう
ショートカットを全て設定して覚えて使うのは大変です。表示できるボタンは表示しておきましょう。



■ファイルツリーとエディタを同期
ファイルが大量にある場合は同期させると楽な場面が多いと思います。



エディタ側でアクティブなファイルを自動で選んでくれるようになります。


以上で必須とも言える設定が完了したと思います。
お疲れ様でした!





2014年10月18日土曜日

JavaScriptで文字コード指定

初心者がつまづきやすい所の1つとして、外部JavaScriptファイルにマルチバイトが含まれている場合のエラーがあると思います。
ファイルを読み込む前に文字コードを指定しないと文字として認識されずにエラーとなります。
古いIEで発生する問題となります。

例1
×<script type="text/javascript" src="hoge.js" charset="UTF=8"></script>
○<script type="text/javascript" charset="UTF=8" src="hoge.js"></script>

例2
×b.setAttribute("src",a);b.setAttribute("charset","UTF-8");
○b.setAttribute("charset","UTF-8");b.setAttribute("src",a);

上記のように、文字コードを指定する順序が重要となります。

コーディング規約を紐解く

コーディング規約とは、コーディングする際のルールの事です。こういう風に書きなさいという決まりごとです。これは、問題を解決するためのTipsでもあります。
では、どのようにして規約が作られていっているかを見てみることにします。

PHPコーディング規約の標準化を勧めている www.php-fig.org に参加メンバープロジェクトの統計がありますので、これを使って解説いたします。

・インデントの種類

タブ:7
スペース2つ:1
スペース4つ:14

タブはインデント作成機能そのものなのですが、エディタによってタブの幅が統一されていないのが嫌われている原因です。スペース2つ分だったり、4つ分だったりです。
そしてスペースを使ってしまう人が居るとガタガタになってしまいます。
メンドクサイから設定無しで統一できるスペースを使おうという流れが主流であります。

タブ幅の問題が無視できる身内完結型プロジェクトでしたら、タブを使ったほうが遥かに効率的です。
なのでタブ派も非常に多いと思います。
有名どころでさえ1/3もタブ利用を規約に入れていますね。

スペース2つはDelphiがそうでした。 4つだと疲れるので2つにしようということですかね。
問題点は、2つだけだとインデントが分りにくい場合があるということです。

ちなみに私は、幅4のタブ派です。 これになれるとスペース4はストレスがたまります。
スペースのプロジェクトでよくあるのはスペースの数を間違える人。統合開発環境を使わない人は必ずミスりますね。これがストレスなのです。

・1行の長さ制限(なるべくこれ以下に)

無し/未指定:2
75文字:4
80文字:6
85文字:1
100文字:1
120文字:4
150文字:1

75文字、80文字が多いのは、横幅が640ピクセルだったDOS時代の名残りです。
当時は1行80文字までしか表示できなかったので、それに慣れている人が多いということです。

120文字がいくつかあるのは、現在の状況に合わせた結果です。
120文字を表示できない環境はまず無いと言えます。
80文字は短すぎて、非常にみにくいソースとなりやすいです。
しかしあまりにも横に長すぎるのもみにくいです。
なので、見易さを考慮して120としています。

・1行の長さ制限(これ以上は禁止)

無し/未指定:13
85:4
100:3
120:2

多くの人は、状況によっては非常に長い行も許容するということですね。
臨機応変にということです。

・クラスの規則

無し:1
小文字:1
小文字とアンダーバー:1
単語1文字目大文字:19

大文字開始はクラス名だということを一目でわかるようにするための工夫です。
クラスが無かった時代は、ユーザー関数名が大文字開始というのが一般的でした。
これは標準関数ではないということを一目でわかるようにし、解析を楽にするための工夫でした。
昔は統合開発環境のような解析補助機能なんか無く人力による解析でしたからね。

・クラスの「{」を書く場所

次の行:16
同じ行:6

これはメソッドでの規則と連動していると思います。
プログラミングを長年していると、誰でも自然と次の行に書くようになります。
一目で境界がわかるようにするための工夫となります。 パラグラフと同じですね。

・定数の規則

全て大文字:22

昔から変っていない定番です。定数という事を明確にわかるようにします。

・true false nullの規則

小文字:19
大文字:3

定数なので例外なくこれも大文字って人が少なからず居ます。
しかしこれら定番の定数は大文字で書かなくても定数だと誰もがわかります。
小文字で書くほうが楽なので、
PHPStormの初期設定は何故か大文字開始というマイナー設定ですが。

・メソッド名途中の単語区切り

大文字開始:21
アンダーライン:1

クラスとの違いは、名前の1文字目は小文字開始ってだけです。
この差別で見分けやすくですね。

・メソッドの「{」を書く場所

次の行:15
同じ行:7

理由はクラスのと同じです。

・制御構造(ifなど)の「{」を書く場所

次の行:4
同じ行:18

長くやっている人は同じ行で定着しやすいです。制御構造は同じ行にしないと非常に見にくいと感じます。
まとめると、クラスとメソッド(関数)は次の行、制御構造は同じ行にしてコーディングを楽にします。
どうすれば楽にコーディング&解析できるかを工夫していくと、これにたどり着くと思います。(他のブログを見ても、ファイナルアンサーでこうなる人が多く感じます)

・制御構造の後のスペース(「if ()」 と書くか、「if()」 と書くか)

無し:2
あり:20

これの理由は忘れました。 おそらく関数ではないよってことくらいでしょうか。

・制御構造の括弧{} 省略を許容するか

許容:3
省略不可:19

本番で省略はありえないと私は感じます。 省略を許可しているプロジェクトは不具合発生率が半端ではないです。あたりまえだと思います。
後から見る/編集することを前提に、必ず{}を書く必要があります。
不具合を減らすための知恵です。
省略形は基本的にテスト等の一度使って消す物でしか使ってはいけません。
よく悩まされるのでここは強く言います。

・elseやelseif 

次の行:6
同じ行:16

おそらく、ifの「}」と同じ行に書くかどうかですよね。
制御構造の「{」の理由と連動するはずです。異なるプロジェクトもあるみたいですが。

・switch構文内のインデント(case/break)

0/1:4
1/1:4
1/2:14

0/0派の人も見たことがあります。
インデントを少なくする人の主張は、インデントが深くなってしまうのを防ぎたい。
そもそも問題になるほど深くなってしまうようなコーディングに問題があると思います。
特別な事を考えずスラスラ書ける1/2が多いですね。
例外的な書き方をなるべく減らすのも大切です。

・関数名の後のスペース

無し:22

説明不要ですね。関数は()まで含んで1つです。 制御構造とは違うのです。

・php閉じたタグ(?>)を書くか

禁止:19
書く:3

書くのは、はるかいにしえの時代からのプロジェクトで改正していない所って感じがあります。
PHP公式マニュアルにも、「省略するように」と注意書きがあります。
省略しないプロジェクトでよくある不具合は、閉じたタグの後に空行スペースが入り込んでしまい動かなくてはまるという問題です。 私も何ども経験しました。 誰だスペース入れたのは!って。

「?>」は終了タグと思ってはいけません。 html文書の開始タグです。


・改行コード

未指定:5
LF:17

大抵は未指定でも問題にならないのですが、問題になることもあるので統一したほうが良いです。
エディタによっては改行が壊れます。(改行の重複問題)
一番無難なのは、エディタをLFに設定してソース編集して、そのまま変換無しにコミットすることです。

・制御構造の頭にスペースを入れる

?:1
無し:19
入れる:2

スペースを入れるなという規約を見るのは、入れる人がいるのですね。
そういうコードは見たことが無かったのでカルチャーショックです。

・phpタグの後に空行を入れるか

?:1
無し:13
入れる:8

ばらばらだと汚らしいから統一しようという程度ですね。

・クラス/メソッド/制御構造の「{」位置  (まとめです)

次/次/次:4
次/次/同:11
次/同/同:1
同/同/同:6


以上が調査内容ですが、これはあくまで基本事項だけですね。
後はプロジェクトによってもっと細かい規約が存在するって感じでしょうか。

2014年10月13日月曜日

お手軽シンタックスハイライト

本ブログで使うシンタックスハイライトのスクリプトを探していました。
よく見かける物は高機能だが使いにくいという物ばかりという印象を感じていたので、マイナー探しでしょうか。(特定ブラウザで問題あったり、コピーがまともにできなかったり面倒だったり)

シンプルで手軽な物を探した結果、「highlight.js」を採用しました。
あまり見かけませんが、けっこう評判が高い感じです。

サンプル
function inherit(parent, obj) {
  var result = {};
  for (var key in parent)
    result[key] = parent[key];
  if (obj)
    for (var key in obj)
      result[key] = obj[key];
  return result;
};

・良い点
手軽。 なんといっても手軽軽量。めんどくさがり屋にうってつけです。
対応現言語が大量で、言語指定しなくても自動認識し、ごちゃまぜにしても問題なし。とても賢く動きます。
なので、コードをはりつけるのが大変楽です。

・悪い点
行番号がつけられない?何行目という解説をする時に不便そうですね。


本家マニュアルが少々分りにくいと思いますので、解説いたします。
簡易マニュアル
詳細マニュアル

■基本的な使い方

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>


上記が全てデフォルトで動作させるための最小設定です。
cssやjsファイルは、カスタムダウンロードを行わなければリンクするだけです。

initHighlightingOnLoadは、ブラウザの表示が完了したらシンタックスハイライトを実行します。
シンタックスハイライトの対象ブロックは、デフォルトでは「<pre><code></code></pre>」となります。
ちょっとこれは面倒ですね。普通は「<pre></pre>」で充分だと思います。
なので動作指定を行いましょう。

■<pre>要素を対象にする方法

<link href='//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/styles/default.min.css' rel='stylesheet'/>
<script src='//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'/>
<script src='//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/highlight.min.js'/>
<script>
  $(function() {
    $('pre').each(function(i, block) {
      hljs.highlightBlock(block);
    });
  });
</script>
jQueryを使う場合は、これで完了となります。
ブラウザの読み込みが終わったら、全 pre 要素にシンタックスハイライトを適用します。
initHighlightingOnLoadでやっている事をjQueryで書き直しただけですね。

2014年10月12日日曜日

rootのメールを定期的に削除

rootには色々とメールがたまっていきます。
しかし重要なログ系なので停止するわけにもいきません。

手軽にローテーションさせる方法

mv -f /var/spool/mail/root /var/spool/mail/root_2

メールファイルをリネームするだけです。
既にリネームされたファイルがある場合、上書きされます。
これをcronで月1とかでまわせばメールが肥大化しないというわけです。

簡単ですね!

動的にドメインを追加する方法

バーチャルドメインの設定で毎回 httpd.conf を編集するのはめんどくさいですよね。
なのでDNSの設定のみで httpd.conf をいじらずバーチャルドメインを自動で追加していく方法を簡単に解説します。

httpd.conf で最初に設定を書くだけです。
apache2系はmod_vhost_alias、apache1系はmod_rewite を使います。
ここでは apache2系の mod_vhost_alias を対象にした解説を行います。

mod_vhost_aliasは、バーチャルホストの設定で変数を使えるようにするための機能で、最初からONになっていると思います。
変数の中身はアクセスしたドメイン名となります。

例)http://www.buglabo.com/ でサーバーにアクセスした時の変数の中身

%0hoge.croftcraft.com全て
%1hoge1番目
%1+hoge.croftcraft.com1番目以降
%2croftcraft2番目
%2+croftcraft.com2番目以降

単純にドット区切りで何番目かなので注意してください。
単純にバーチャルドメインを使う場合は気にする必要はないでしょう。

では httpd.conf を設定します。

UseCanonicalName Off

Off:名前ベースのバーチャルホスト設定にします。 変数にホスト名が入ります。
On:IPベースにします。変数は名前ではなくIPが格納されます。
変数の中身が違うだけで、通常は Off で良いと思います。

バーチャルドメインの設定

VirtualDocumentRoot /var/www/%0/html

アクセスしてきたドメインごとにディレクトリを自動で選ぶようになります。実際のパスは好きにしてください。
最低限の設定はこれでおしまいとなります。


ただしこれだけですと、PHPの$_SERVER['DocumentRoot']の中身が httpd.conf の DocumentRoot のままなので困る場合があります。
解決方法は、バーチャルドメインを普通に組んだ時と同じです。

VirtualHost ディレクィブにて DocumentRoot を指定してください。


<VirtualHost *:*>
DocumentRoot /var/www/%0/html
</VirtualHost>

もう一つやっかいな問題があります。 SSLの設定です。
マルチドメインタイプの証明書ならば問題ありませんが、IPごとに証明書が違う場合はそれぞれ設定しないとなりません。こればかりは設定のみで自動化はできません。
私が楽だと思う方法は、ドメインごとにSSL設定ファイルを分けることです。
そうすれば、ファイルをアップロード or 削除するだけで設定が可能で間違いを減らせます。

yumによる自動アップデートの注意点2つ

自サバでyumの自動アップデートをonにしている人も少なくないと思います。
個人レベルならば自動アップデートによるデメリットよりもメリットのほうが遥かに高いですもんね。

デメリット:いきなり不具合実装でおかしくなる場合あり。
メリット:脆弱性を自動的に修正してくれて安全を確保しやすい。

しかし、自動アップデートを使っていれば自動的に適用されるというわけではありません。
ここが落とし穴ですね。

・1つ目

アップデートを行うにはboot領域に空きが無ければいけません。
空きが無ければアップデートは失敗に終わります。
しかもアップデートに使ったファイルは自動的には削除されません。
何もしなければどんどん容量を圧迫していくのです。

※さくらのクラウドなど、boot領域が非常に小さい所は2・3回のカーネルアップデートでパンパンです。

解決するには cron で定期的に古いカーネルファイルを削除してあげましょう。

package-cleanup --oldkernels -y

・2つ目

アップデートしたカーネルを走らせるにはサーバーの再起動が必要となります。
しかし yum はサーバーを再起動してくれません。
これも cron で定期的にサーバーを再起動させてあげましょう。

自動アップデートをさせている時は、上記の2つを忘れないように注意ですね。

PHPのキャッシュを行うAPC

キャッシュシステムを搭載している最新バージョンのPHPは不要ですが、そうでない古いPHPを使っている場合はAPCが非常に有効です。めちゃくちゃ速くなりますよ。

仕組としては
・通常
PHPファイルを読み込み、コンパイルして、実行。

・APCを入れると
ファイル読み込みとコンパイルを行いメモリに保存。コンパイル済みのメモリ上のキャッシュを使いまわす。
PHPファイルが更新されると再コンパイルが実行されます。(デフォルト設定)

ファイル読み込みとコンパイルが省略できるので非常に快適になります。

■注意点
コンパイル済みをキャッシュするという仕組上、注意点がございます。

1.動的に拡張ライブラリを読み込めない
PHPソース内から拡張ライブラリを読み込んでいる場合、これは失敗します。
php.iniで静的に読み込ませましょう。

2.ソースの中身を動的にいじれない
動的にメソッドの内容を変更したりはできないということです。
すなわち runkit 系は使えないということです。  変更はコンパイルが必要ですからね。

3.実行本体は破棄されずキャッシュとして残るので、PHPの終了処理が微妙に違う。
終了時(インスタンス開放時)に自動的に処理されるはずの処理が処理されなくなる物があります。
たとえばセッションを独自実装している場合、明示的にセッションの保存を呼び出さなければなりません。
セッションはインスタンス解放後に自動保存されるようになっていますが、この解放後の処理がされなくなるため、セッションの保存が自動実行できなくなります。
ということで、デストラクタでセッションを保存してあげましょう。

4.include_onceの動作も変ります
デフォルト設定では、処理の高速化のためinclude_onceの処理がAPC独自処理に置き換わります。
そのために制限が色々とでてきます、
動的にパスを指定できないや、相対パスが駄目だったりなど。
PHP5.3以降は高速にinclude_onceが実行されるのでAPC側の機能を使う意味がほとんどありません。
なので OFF にしてあげましょう。

apc.ini に
apc.include_once_override=0
を追加してあげてください。

include_onceが高速化されているといっても、遅いのに変りはありません。
大量にinclude_onceをしている場合は切り分けてなるべく include で済むようにすると体感できるほど速くなります。
と言っても時代はオートローダーですか。

PDT(Eclipse)のショートカットキー7選

Eclipseとは、フリーの開発統合環境です。
Java開発用に作られた物なので、Java開発をサポートする機能は非常に素晴らしいです。
他言語でも同等の機能が使えたらどんなに楽なことか・・・とたまに思います。

私がメインで使っている言語はPHPです。EclipseではPDTプラグインを入れてPHPに対応させています。

そこでまず最初に覚えたほうが良いショートカット(キーアシスト)と機能を紹介します。
これを知らなければPDT(Eclipse)を使う意味がありません。


  1. F3
    これは頻繁に使うショートカットです。カーソルがある変数や関数の定義元へファイルを超えてジャンプします。ソース解析の必需品ですね。
  2. Shift+F2
    カーソルのある関数のマニュアルを開きます。正確な仕様を確認したい時や、知らない関数が書かれていた時に使います。
  3. Ctrl + スペースキー
    入力補完機能の呼び出し/切り替えです。通常は自動的に候補が出てきますが、編集の仕方によっては出てこない時があり、これで呼び出します。
    また、スニペットと関数補完の切り替えもこれで行えます。
  4. 範囲指定して Tab / Shift + Tab
    インデントの操作を1行ずつなんてやっていられません。
  5. Ctrl + /
    コメントアウトします。もう一度押すとコメント解除です。
    指定範囲を一気に行いたい時が特に楽で良いです。
  6. Ctrl + H
    ファイル検索窓を出します。大量のソースを横断して検索はよくあることです。
  7. Ctrl + Alt + L
    SVNを使っている場合、これでローカルとSVN最新との差分を見ることができます。
    何をしたのか忘れてしまった時によく使っています。大量のファイルを同時に編集しているとよく忘れるのです。
これだけ覚えておけば、快適にプログラミングを行えると思います。
ただ、変にプラグインを入れているとショートカットが競合して動かなくなりますのでご注意ください。

WebアプリにおけるMVC

初心者にとっての難関の一つがMVCの考え方だと思います。
作るものやフレームワークによって微妙に定義が異なりますが、Webアプリにおける基本と思えるMVCを解説いたします。

上記の図は、命令の流れです。
各セクションを解説いたします。

・Model
アプリケーション本体と言える部分です。 広い意味でのCore部分となります。
サービスの処理内容(ビジネスロジック)を書くところですね。すなわちデータ操作部分であり、データを格納している部分でもあります。

・View
UIを構築する所です。すなわちhtmlを構築するテンプレート部分ですね。

・Controller
ブラウザから送られてきた内容や、処理結果によって処理を分岐させる所です。
図には描かれていませんが、Modelからの結果をControllerが受け取り、その内容によってViewへ命令を出します。


ViewがブラウザにUI表示命令を出し、ブラウザからControllerへ操作実行命令を出し、Controllerが命令内容に従いModelやViewに命令をだし、ControllerがModelから受け取った結果によってもViewに命令をだしとなります。


MVCを他にたとえて見ますと
Model→街
View→地図
Controller→標識
こんな関係に近いかもしれませんね。


しかしMVCだけでは全ての処理を含める事はできないので、他にHelperやUtilityといった分類も登場します。

・Helper
MVCに振り分けられない処理を書きます。たとえばViewのためにデータを整形する場合ですね。
Mに含めてもよさそうですが、Mは汎用的な処理内容にとどめないとどんどん肥大化していってしまいます。
特定ページのみの処理などはHelperに書くとすっきります。 後で探すのが楽になるというのは非常に重要です。


・Utility

1つのメソッドで完結しアプリからは独立した汎用的なロジックを置く所です。どこにも依存しないので通常はstaticとなります。
Helperと違うのは、完全に独立した処理で、アプリのどこからでも使えるどころか、他のアプリでも未改造で使いまわせる所にあります。
たとえば、日にちの差を求めるメソッドなどですね。
スニペット集みたいなもので、昔は汎用ライブラリと呼ばれていた部分です。


以上の分類方法を身につけると、拡張性が高く見やすいソースになりやすいと思います。
手抜きしてごちゃまぜにすると、後で修正に苦労してさらにバグだらけになりとカオスになっていきます。
継続してアップデートしていくWebアプリで一番重要なポイントは、後で修正しやすいかどうかとなります。一言で言うと拡張性です。

Tracから外部へのリンクにクッションページを挟む

リンク元をあまり知られたくない場合、リファラーを上書きするページを間に挟みますよね。
tracなんか特にあまり存在を知られたくない場合が多いと思います。

クッションページの作り方は置いておいて、tracの改造方法を書いておきます。


tracが出力しているhtmlを見ると、外部リンクのclassが「ext-link」となっています。
これは簡単に改造ができます。これで検索すれば良いだけとなります。

私の環境では「/usr/lib/python2.6/site-packages/Trac-1.1.2dev_r11693-py2.6.egg/trac/wiki/formatter.py」に該当の文字がありました。
外部リンクの a 要素を構築している部分です。

href属性の中身を書き換えて、クッションページへ飛ぶようにすれば完成となります。

例)class_="ext-link", href="http://xxxxxxx.com/jumper.php?u=" + url, title=title or None, target="_blank")

Tracのwikiを自動改行対応化

Tracのチケットは自動改行されるのに、wikiはいちいち[[BR]]と書かないといけなくて不便ですよね。
特に記事をコピペする時は大変です。
なのでwikiも自動改行に対応させてさくさく書き込めるようにしましょう。

※注意:tracのバージョンによって細かな内容は異なります。以下の内容は1.1.2に基づきます


どこにあるか?
tracのファイルを眺めていると、formatter.pyというのを発見しました。
formatter・・・書き込んだソースをhtmlに変更しているっぽいファイル名ですね。
フルパスですと、私の環境では「/usr/lib/python2.6/site-packages/Trac-1.1.2dev_r11693-py2.6.egg/trac/wiki/formatter.py」になります。

しかしソースが巨大なので目視で解析なんかしていられません。
wikiは空行を入れると自動で<br />を挿入してくれるので、そこを改造して文末は片っ端から挿入させるようにすればいけそう。

そこで <br />でソース中を検索していきます。

ありましたありました。 formatというそれらしいメソッドの中でhtmlの構築を行っています。
意図したとおりに動くよう、軽くこのメソッドを解析します。

if not(self.in_list_item or self.in_def_list or self.in_table):
リストやテーブルの中ではない場合とあります。(バージョンによってここら変の内容が異なります)

さらに

if escape_newlines and self.paragraph_open and \
       not result.rstrip().endswith('<br />'):
\は次の行に続きますという意味です。なので2行を1行にまとめると。
パラグラフの開始(paragraph_open)で、前行末(endswith)に<br />タグが無い場合でしょうか。

wikiの改行を2連続で入れると改行されるという部分だなと分ります。

てことで、ここを変更します。

if not result.rstrip().endswith('<br />'):
単純に、「行末が<br />で終わってない場合」にしました。

後に続く sep = '<br />' + sep で、改行が入ります。

まとめると

- if escape_newlines and self.paragraph_open and \
- not result.rstrip().endswith('<br />'):
+ if not result.rstrip().endswith('<br />'):

となります。
何か忘れている気がしますが、これで快適にwikiを編集できるようになりました。