Strings of Life

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

2013年03月

PHPのタイプヒンティング

PHP5では、関数・メソッドのパラメーターの型を指定する、タイプヒンティングが利用できます。
例:
function type_test(array $array) {}
type_test(1);
これを実行すると、「PHP Catchable fatal error: Argument 1 passed to type_test() must be of the type array, integer given」というエラーが表示されます。

array型を想定しているパラメーターにスカラー型(この場合は整数)を与えているからです。

以下、PHPのタイプヒンティングにおいて使える型・使えない型を整理します。なお、前提とするPHPのバージョンは5.4です。

タイプヒンティングに使える型

PHPでタイプヒンティングに使えるのは、「オブジェクトもしくはインターフェイス、配列 (PHP 5.1 以降)、callable (PHP 5.4 以降) 」です(PHPマニュアル - タイプヒンティング)。

「オブジェクト」は任意のクラスのオブジェクトのこと。「インターフェイス」は、任意のインターフェイスを実装したクラスのオブジェクトのことです。
例:
// インターフェイスを定義
interface UserInterface
{
    public function ui();
}

// UserInterfaceを実装
class MyUserInterface implements UserInterface
{
    public function ui() {}
}

class MyClass
{
    // UserInterfaceの実装をパラメーターとして受け取るメソッド
    public function test_interface(UserInterface $ui)
    {
        echo get_class($ui);
    }
}

$myui = new MyUserInterface();
$myc = new MyClass();
$myc->test_interface($myui); // MyUserInterface
// $myc->test_interface($myc); // MyClassはUserInterfaceの実装ではないのでFatal Error
配列はそのまんま配列(array型)のことですね。

callableに関しては、ちゃんとした説明の自信はありませんが、以下の例のような動きをします。
class MyClass
{
    public function test_callable(callable $callback)
    {
        call_user_func($callback);
    }
}

function test() {
    echo 'test() is called';
}

class TestClass
{
    public static function test()
    {
        echo 'TestClass::test is called';
    }
}

$mc = new MyClass();
$mc->test_callable('test'); // test() is called
$mc->test_callable(array('TestClass', 'test')); // TestClass::test is called
引数として与えた文字列や配列を元に関数を探し、その関数を呼び出し可能であればcallableということになるようです。

タイプヒンティングに使えない型

まず、スカラー型が使えません。スカラー型とは、論理値(boolean)・整数(integer)・浮動小数点数(float/double)・文字列(string)のことです。

また、任意のトレイトを継承するオブジェクトか否かはタイプヒンティングで指定することはできません。

ここまで、継承について、再利用(サブクラスがスーパークラスのメソッド及び変数を利用すること)及び拡張(サブクラスが独自のメソッド及び変数を定義すること)を学んだ。

次に、再定義に移る。再定義とは、サブクラスがスーパークラスで定義されたものの別バージョンを提供することである。

(再利用、拡張、再定義は、相互に排他的な関係ではないことに注意。サブクラスは3つの技術を全て使うこともできる)

再定義によって、既存のクラスを、特定の目的にそって、拡張したり、強化したり、無効化したりすることができる。メソッドを再定義することを「オーバーライド(overriding)」と呼ぶ。

ActionScript3.0では、インスタンスメソッドのオーバーライドは可能だが、インスタンス変数・静的変数・静的メソッドのオーバーライドはできない。

スーパークラスのインスタンスメソッドをオーバーライドするには、サブクラスの中で同名のインスタンスメソッドを定義し、overrideキーワードをメソッド定義の前に置く。
例:
public class A {
    public function m () {
        trace("A's m() was called");
    }
}

public class B extends A {
    override public function m () {
        trace("B's m() was called");
    }
}
この例では、Aのメソッドm()を、Aを継承するBの中でオーバーライドしている。

オーバーライドが成功するのは、オーバーライドするメソッドが、オーバーライドされるメソッドと、以下の4点で同じになっている場合だけである。
(1) 名前
(2) アクセスコントロール修飾子
(3) 引数の数
(4) 返り値のタイプ


今日の進捗:2735→2787/20168

基本的には、Zero-configuration Web Application Debugging with Xdebug and PhpStormという、PhpStormの開発元・JetBraingの解説記事を読んでもらえればOK。ですが、要点だけ訳してメモしておきます。

1. Xdebugをインストール

XdebugはPHP拡張(PECL)のうちの一つです。インストール済みか確認するには、コマンドラインから「php -i | grep xdebug」を実行するか、phpinfo()でxdebugの項目があることを確認してください。

インストールされていない場合は「pecl install xdebug」でインストールできます。

インストールされていることを確認したら、「php -i | grep xdebug.remote_enable」を実行するか、phpinfo()でxdebug.remote_enableを探してください。xdebug.remote_enableがOffになっていたら、php.iniを編集します。

「xdebug.remote_enable = off」といった記述があったら、これを「on」又は「1」に変えます。記述自体ない場合は、「xdebug.remote_enable = on」を付け足します。

また、xdebugのバージョンも確認しておきましょう。PhpStorm6の推奨バージョンは2.2.1又は2.1.3です。


2. PhpStormを準備

ツールバーを表示した状態で(View > Toolbarにチェックを入れる)、受話器のような形のアイコンをクリックします。

Menubar-1





↑の図のようになっていれば、リモートデバッグの受け入れモードに入っています。


3. ブレークポイントをセット

行番号の右をクリックすると、オレンジ色の丸が表示されます。これがブレークポイントで、任意の地点でプログラムの実行を止めることができます。


4. サーバーのデバッガーを有効化する

デバッガーを有効化するには、特別な値のGET/POSTあるいはCOOKIEパラメーターを渡す必要があります。手動でも設定できますが、ジェネレーターで生成した、Cookieを設定するJavaScriptコードをブックマークレットに登録しておくのが便利です。


5. デバッグの対象ページをブラウザーで開いた状態で、「Start debugger」ブックマークレットを実行

6. 現在のページをリロード

7. パスの初期値を設定

PhpStormに切り替え、ローカルに保存してあるデバッグ対象のファイルを選択して、パスの初期値を設定する(訳注:この部分の訳は怪しい)。設定すると、「Incoming Connection From Xdebug」というダイアログが自動的に現れるはず。


8. デバッグする

ブレークポイントを設定したり、変数の値を覗いたりして、効率的にデバッグを行えます。

独習PHP 第2版
独習PHP 第2版

PHP5は、本格的なオブジェクト指向の構文を備えたプログラミング言語です。しかし、PHPの書籍には、オブジェクト指向を初歩から解説したものが少ない。

よくわかるPHPの教科書』『初めてのPHP5 増補改訂版』等の入門書では、「オブジェクト指向というものが存在する」という程度で終わり。一方、『プロになるための PHPプログラミング入門』や『パーフェクトPHP』のような中級レベルの書籍では、オブジェクト指向については理解しているのを前提に話が進んだりします。

(『パーフェクトPHP』には「PHPのオブジェクト指向構文はこうなっている」という解説は載っていますが、オブジェクト指向を初歩から学べるわけではありません)

私の知る限り、(1)PHP5.3(名前空間等)に対応 (2)オブジェクト指向を基礎から解説している という条件を満たす和書は本書だけです。初歩的なオブジェクト指向の解説は『やさしいPHP 第2版』にも載っていますが、インターフェースやマジックメソッドまで載っているのは『独習PHP 第2版』だけ。


そういうオンリーワンな価値を持つ書籍なのですが、いくつかイケてない部分もあります。

(1) Windows環境を前提とした記述

Linux向けの解説も併記されています。が、PHPでの開発ならLinuxを前提とすべきでしょう。VirtualBox等を使えば、Linux環境の構築はさほど難しくありません。

(2) サンプルが退屈

チュートリアル形式の、アプリを作る過程で学ぶ本ではなく、構文単位で小さなサンプルを動かして学ぶ形式です。小さなサンプルがダメってことはないのですが、さすがに500ページもあるとダレます。

(3) ベストプラクティスから外れていることがある

例えば、クラスのオートローダーは本書では__autoload()で実装していますが、spl_autoload系の関数の方が高機能です。もっとも、明らかなバッドプラクティス(例えば、文字列連結によるSQL組み立て)はないと思います。

(4) 若干古い

2010年4月に出た本なので。とはいえ、5.3に対応しているので、致命的に古い部分はないと思います。


オブジェクト指向を初歩から学びたいPHPerにはオススメです。オブジェクト指向の章だけ(第7章と第10章)読むとか、目次を見て知らないところだけ読んでいく、といった読み方でも良いと思います。

インスタンスメソッドとインスタンス変数とは異なり、サブクラスはスーパークラスの静的メソッド・静的変数を継承しない。静的メソッドをサブクラスから呼んだ場合、エラーが発生する。

例:
public class A {
    public static function s () {
        trace("a.s() was called");
    }
}

public class B extends A {
    public function B () {
        B.s(); // エラー:A.s()への無効なアクセス
    }
}
しかし、AかBのいずれかの中で定義されている静的メソッド・静的変数は、A.s()ではなく、クラス名抜きのs()と書けば、呼び出すことができる。とはいえ、静的メソッド・静的変数の呼び出し時にクラス名を含んでおくのが賢明である。クラス名が含まれていれば、そのメソッド・変数の出処が明らかだからだ。


今日の進捗:2715→2724/20168

このページのトップヘ