2013年4月28日日曜日

XMLをPOSTで送る/受け取る

先日仕事で使用したのでメモです。

要求仕様で「XMLデータをPOSTで送ってほしい/受け取って欲しい」との依頼が来ました。

サンプルコード

送る側 受け取る側 実行結果 このようになります。
ポイントは、送信側ではヘッダ情報の付与を忘れないようにすることと、
受信側ではPOSTが配列でないため$_POSTでは取得できないのでphp://inputを使用することです。

Iterator

Iteratorとは反復処理を行うための機能のことです。
今回はこの機能を用いてforeachについて学んでみます。

サンプルコード 実行結果
string(18) "myIterator::rewind"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
0 => firstelement
string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
1 => secondelement
string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
2 => lastelement
string(16) "myIterator::next"
string(17) "myIterator::valid"
この結果から分かるように、foreachは
  1. 最初の要素に戻る
  2. (現在の要素が有効か)チェックする
  3. 要素を返す
  4. キーを返す
  5. 次へ
といった順序を辿っていきます。

ちなみに、オブジェクトへのforeachがこのようにクラス内メソッドを決められた順序で辿っていくのは
Iteratorインタフェースを実装したクラスの時のみです。

2013年4月20日土曜日

例外の使い方

PHPも他のプログラミング言語同様に例外モデルを持っています。
例外処理はコードを書く上でも重要な要素の一つでしょう。
いかに簡単な例を紹介します。

サンプルコード と、このように不正な処理が起きた時に対応するのが例外の主な役割です。

また、例外は拡張することができます。
私も以前は例外を拡張したコードを書いていましたが、例外処理が複雑化するのと
実際にはそこまで分類する必要性のないことに気づいて今は拡張は最小限に留めています。

PHP5.5からはtry - catch構文にfinallyが加わりました。
これは、例外が起きても起きなくても必ず実行されるというものです。
これで、今までtryとcatchの両方に書かざるをえなかった冗長な文が一つにスッキリとまとめられそうですね。

2013年4月17日水曜日

名前空間 その5

名前空間内で、PHP が未定義のクラス名や関数、定数に出会った場合、
それぞれに応じて異なる優先順位で解決を行います。
  • クラス名:常に現在の名前空間での名前として解釈する
  • 関数、定数:名前空間内にその関数や定数が見つからなければ
    グローバル関数/定数を探す
では、サンプルコードを見ていきましょう。

サンプルコード

2013年4月14日日曜日

useの使い方

名前空間においてuseは重要な要素です。
useを使うことで外部の完全修飾名をエイリアスで参照したりインポートすることができます。

まずはエイリアスで参照を行う例です。

サンプルコード 実行結果
TEST
TEST
続いてインポートを行う例です。

サンプルコード このuseで重要な点は「コンパイル時に実行される」ということです。
そのため、動的なクラス名、関数名や定数名には適用されません。

サンプルコード 実行結果
Parse error: syntax error, unexpected '$f' (T_VARIABLE), 
expecting identifier (T_STRING) in C:\xampp\htdocs\test.php on line 11
さらにインポートの影響が及ぶのは非修飾名および修飾名のみです。
完全修飾名は絶対的なものであり、インポートの影響を受けることはありません。

サンプルコード 実行結果
Fatal error: Call to undefined function hoge\test() in 
C:\xampp\htdocs\test.php on line 10

2013年4月13日土曜日

forを使おう

再帰的な処理を行うにはforとwhileの2通りがあります。
どちらを使うかは個人の自由ですし、その時の状況に応じてというのもあるかもしれません。
ただ、私はどちらかと言えばforを使うことをオススメします。

forの利点としましては一行に
  • 初期化
  • 再帰の終了条件
  • 終了条件に至るプロセス
をまとめることができます。
つまり、このような処理は と一行にまとめることができます。 さらに、$iの値にはこだわらず、10回ループさせたいだけなら、 と書くことも可能です。

ちなみに、forとwhileのベンチマークです。

サンプルコード 実行結果
BenchMark 1 average:0.0053820133209229
BenchMark 2 average:0.0054374217987061
と、わずかばかりforの方が速いようです。

2013年4月12日金曜日

名前空間 その4

名前空間内でnamespace演算子を使うことで現在の名前空間
あるいはサブ名前空間内の要素を明示的に指定することができます。

サンプルコード 実行結果
1

名前空間 その3

名前空間も動的なアクセスが可能です。

サンプルコード 実行結果
1

コード短縮手法5

今回はコード短縮手法というよりコーディングルールのようなものです。
ネストを極力深くしないようにするため、if文の条件を && で繋ぎましょう。

サンプルコード 実行結果
BenchMark 1 average:0.0039301872253418
BenchMark 2 average:0.003798246383667
と、後者のほうが早かったりします。

2013年4月9日火曜日

名前空間 その2

今回も名前空間の規則について確認していきましょう。

file1.php file2.php 実行結果
namespace1
namespace2
2
subnamespace1
subnamespace2
1
namespace1
namespace2
2
このように、名前空間はファイルの相対パス・絶対パスのような扱いができます。

2013年4月6日土曜日

名前空間 その1

まず、名前空間とは何でしょう?
広義の名前空間とは、項目のカプセル化のことです。

PHPの名前空間は、以下の2つのことを解決するために提供されています。
  1. あなたが作成したコードと PHP の組み込みのクラス/関数/定数
    あるいはサードパーティのクラス/関数/定数の名前が衝突する
  2. 最初の問題を解決するためには、Extra_Long_Names のような
    長い名前をつけなければならない
では、サンプルコードを見てみましょう。

サンプルコード 実行結果
1
2
と、このようにnamespace <name> {} でくくった領域では独立した関数名を持つことができます。
また、<name>を省略すると名前空間の名前を指定しないグローバルなコードとして扱われます。
このnamespaceの規則について、次回はもう少しだけ詳しく確認してみましょう。

遅延静的束縛 その2

遅延静的束縛では気をつけなければならないことがあります。
それは、publicやprotectedといったプロパティしか参照できないということです。

以下の2つのサンプルコードを例に見てみましょう。

サンプルコード1 実行結果
$this->:B
static:B
サンプルコード2 実行結果
self:A
static:
Fatal error: Call to private method B::who() from context 'A' in 
C:\xampp\htdocs\test.php on line 13
このように、プロパティがprivateとなりますとstaticは遅延静的束縛ができずにエラーを起こしてしまいます。
staticを使う際のアクセス権にも十分注意が必要です。