パーフェクトPHP 読書メモ 5章 クラスとオブジェクト


p.127で、「定数に用いることができるのはスカラーの値のみです。式を用いたり、配列やリソースなどを定数に用いることはできません」と記載されているが、PHP5.6では定数定義に式を用いることができるようになっている(constant scalar expressions)。ここに限らず、古く感じられる説明が出てきている。そろそろ改訂版が欲しいところ。

標準クラスからオブジェクトを生成する

<?php
$obj = new stdClass(); // 空のオブジェクトを生成
$obj->member = 'hoge'; // PHPでは未定義メンバに値を入れてもエラーにはならない
$obj->method = function(){echo $this->member;}; // 未定義メソッドの定義はエラーが出ないが…
$obj->method(); // 実際に呼び出すとエラーが出る

遅延静的束縛(staticキーワードによる呼び出し)

<?php

class Foo
{
  public function getClassNameGateway()
  {
    echo self::getClassName(); // 必ず Foo::getClassName() が呼ばれる
    echo static::getClassName(); // 呼び出されたコンテキストに応じて解決される(Fooが呼べばFoo::getClassName()、Barが呼べばBar::getClassName()が呼ばれる)
    echo PHP_EOL;
  }

  public static function getClassName()
  {
    return 'Foo';
  }
}

class Bar extends Foo
{
  public static function getClassName()
  {
    return 'Bar';
  }
}

$foo = new Foo();
$foo->getClassNameGateway(); // FooFoo

$bar = new Bar();
$bar->getClassNameGateway(); // FooBar

オートローダの仕組み(__autoload()を使う場合)

<?php
$obj = new Foo(); // 未定義クラスを呼び出すと、__autoload()が自動的に呼び出される

function __autoload($name) {
  echo $name, PHP_EOL; // ここで $name を元にPHPファイルを読みこめば、オートローダになる
}

ただし、__autoload()にはオートロード処理を1種類しか登録できないため、実際のオートローダはほとんどspl_autoload_register()で実装されている。

名前空間

<?php
namespace Acme; // 名前空間の宣言の前には、PHPタグとコメント以外の出力や文が存在してはいけない

class stdClass {}; // \Acme\stdClass
function file_get_contents(){}; // \Acme\file_get_contents()
const E_ALL = 0x01; // \Acme\E_ALL
$var = 0x01; // 変数に名前空間は適用されない