Strings of Life

PHP/Phalcon/MySQL/JavaScript/RegExp/Ruby/Perl/ActionScript

2013年04月

はじめてのフレームワークとしてのFuelPHP

FuelPHPは、PHP5.3以降に対応した、軽量・高速のPHPフレームワークです。ライセンス問題で失速したCodeIgniterの後釜と目されている(?)ようです。

本書・『はじめてのフレームワークとしてのFuelPHP』は、2012年の7月に達人出版会から電子書籍として刊行されました。対応しているFuelPHPのバージョンは1.2です。一方、2013年4月現在の最新バージョンは1.5.3。この間、機能の改廃やディレクトリ構造の変更等が入っています。

バージョン変更に対する対応は全てGitHub上のサポートサイトで網羅されているので、現在でもサンプルコードはちゃんと動きます。欲を言えば、章ごとのスナップショットが欲しいですね。リファクタリングの章だけやり直したい、みたいな需要もあるので。


本書、とにかく気合を入れて書いたんだろうなというのは伝わってきます。環境構築は手厚く、Win/Mac/Linux(Ubunutu)の3パターンで詳述されています。また、チュートリアル形式で、セキュリティにも手を抜かず、テストを書いてリファクタリングまで体験できます。

ただ、前述したように、サポートサイトを見ながらでないと進められない面倒さがあるので、「何でもいいからフレームワークを学びたい」人にはオススメしません。フレームワーク入門者なら、CakePHPが、日本語情報の充実度の点でオススメです。(書籍としてのイチオシはありませんが、ドットインストールのCakePHP入門をやったあと、公式のチュートリアルをやってみると良いと思います)

「FuelPHPを学びたい」という目的意識があって、なおかつ、フレームワークを使ったことが無い人にならオススメできます。(他のフレームワークを使ったことがある人なら、公式のドキュメントを読めばいいと思います)

入門git
入門git

入門Git』とは別物。バージョン管理システム・gitの入門書です。

htmlファイルを編集しながら、チュートリアル形式でgitのコマンドを使っていきます。本文だけなら150ページと薄めですが、頻繁に使うコマンドは網羅されているし、「いざというときのために知っておくべきコマンド」なんかも解説してます(git reflog, git bisect)。

ひと通り読了した現在でもモヤモヤした部分は残っているのですが、「どういうコマンドがあるか」「それぞれのコマンドにどのような効果があるか」という部分についてはそれなりにわかってきたかな、と。



おまけ・訂正系コマンド逆引き

☆対象:コミット

直前のコミットを訂正する:git commit HEAD --amend
直前のコミットを訂正する(ログメッセージは既存のものを使う):git commit -C HEAD --amend

直前のコミットを取り消す(取り消しと同時にコミット):git revert HEAD
直前のコミットを取り消す(コミットはしない):git revert -n HEAD

☆対象:作業状態

1つ前のコミットの状態に戻す:git reset --hard HEAD^

インスタンスメソッドとインスタンス変数の継承における関係について学んできた。次に、コンストラクターメソッドに移る。

コンストラクターメソッドは、クラスのインスタンスをセットアップするメソッドを呼び、そのオブジェクトに必要な変数を作成する。

クラスを継承した際には、サブクラスは独自のコンストラクターメソッドを定義できる。サブクラスのコンストラクターメソッドは、サブクラスに関連するセットアップと、サブクラスで必要な変数の定義を行い、スーパークラスのコンストラクターメソッドも実行する。

サブクラスのコンストラクターメソッドを定義する場合には、スーパークラスのコンストラクターをsuperキーワードで呼び出す必要がある。さらに、スーパークラスのコンストラクターメソッドは、インスタンス変数又はインスタンスメソッドへのアクセスよりも先に呼ばなければならない。もし、このような呼び出しがされなかった場合、コンパイラーは引数無しでスーパークラスのコンストラクターを自動的に呼び出す。最後に、superはコンストラクターメソッドの中で1回しか使えない。

インスタンス変数又はインスタンスメソッドにアクセスした後でのsuperの使用を禁止することには、以下のメリットがある。
  • 初期化が完了していないオブジェクトのメソッドが呼び出されるのを防ぐ
  • 初期化が完了していないオブジェクトの変数へのアクセスを防ぐ
  • スーパークラスへのコンストラクターへの変数の代入が、サブクラスのコンストラクターへの変数の代入を上書きしないようにする
super()と、super.methodName()の違いに注意。super()はスーパークラスのコンストラクターメソッドの呼び出しで、サブクラスのコンストラクター内で1回だけしか使えない。一方、super.methodName()は、サブクラスのどこでも、何回でも使える。

superを使って、スーパークラスのコンストラクターメソッドを呼び出してみる。
例:
public class A {
    public function A() {

    }
}

public class B extends A {
    // サブクラスのコンストラクター
    public function B () {
        // スーパークラスのコンストラクターメソッドを呼び出し
        super();
    }
}
今日の進捗:2823→2891/20168

JavaScriptには、arguments.calleeという、自分自身を再帰的に呼び出すプロパティがあります。arguments.calleeを使うと、以下のようなコードが書けます。
function factorial(n) {
    if (n > 1) {
        return n * arguments.callee(n - 1); // 自分自身(factorial()を呼び出し)
    }
    return 1;
}
console.log(factorial(5)); // 120
arguments.calleeの部分で自分自身を明示的に呼び出すように書いても、出力は同じです。しかし、arguments.calleeを使えば、関数名を変更した際などに再帰呼び出しの箇所を変更する必要がありません。また、無名関数内で再帰呼び出しをする際には、arguments.calleeを使う必要があります。

これと同じ事をPHPでやってみたのが、以下のコードです。
function callee($arg) {
    $backtrace = debug_backtrace();
    return $backtrace[1]['function']($arg);
}

function callee54($arg) {
    $backtrace = debug_backtrace()[1]['function']; // PHP5.4以上ならこの書き方でもOK
    return $backtrace($arg);
}

function factorial($n) {
    if ($n > 1) {
        return $n * callee($n - 1);
    }
    return 1;
}

echo factorial(5); // 120
debug_backtrace()を実行すると、PHPの実行状況についてのログ(バックトレース)が入った配列が返ってきます。PHPでは、変数内に格納された関数名文字列にカッコ演算子をつけると、その名前の関数が呼び出されます。この場合は、$backtrace[1]['function']に'factorial'という文字列が格納されているため、$backtrace[1]['function']で、factorial()が呼び出されています。

callee54()の方は、PHP5.4以上で利用できる、関数の返り値を配列として扱う記法を利用しています(参考:PHP5.4の新機能)。

なお、ここで定義したcallee()関数は、引数を1つ受け取る場合にしか対応していません。実用的なcallee()関数定義は、@anatooさんのブログ記事を参照して下さい。

JavaScriptで、配列の比較の際に==又は===演算子を用いると、その配列が参照しているメモリ上のアドレスが同じかどうか、でtrue/falseを返します。したがって、
var array1 = [1, 2, 3];
var array2 = [1, 2, 3];
console.log( array1 == array2 ); // FALSE!!!
という結果になります。配列の値と値の順番が等しいか比較する方法として一番簡単なのは、toStringメソッドで文字列に変換して比較することです。
var array1 = [1, 2, 3];
var array2 = [1, 2, 3];
console.log( array1.toString() == array2.toString() ); // true

// ↑の3行目の処理を詳しく書くと、以下のような流れ。
var string1 = array1.toString(); // 配列[1,2,3]を文字列"1,2,3"に変換
var string2 = array2.toString(); // 配列[1,2,3]を文字列"1,2,3"に変換
console.log( string1 == string2 ); // "1,2,3"と"1,2,3"は同値なのでtrue
配列を頭からループで回して、値を比較するというのもOKです。
var ary1 = [1, 2, 3];
var ary2 = [1, 2, 3];
var isEqual = true;
for (var i = 0; i < ary1.length; i++) {
    if (ary1[i] !== ary2[i]) {
         isEqual = false;
    }
}
console.log( isEqual ); // true
オブジェクトの比較の際も同様の問題が発生しますが、オブジェクトの場合はより事情が複雑なので、機会があればまた今度。。。

オブジェクトの比較で参考になりそうなリソース:http://blog.livedoor.jp/dankogai/archives/51859373.html

このページのトップヘ