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とかでまわせばメールが肥大化しないというわけです。

簡単ですね!