今回は Drupal 8 (ドルーパル 8 )入門の一環として「 Drupal 7 から 8 に変わるにあたって新たに使えるようになった PHP の機能」をご紹介したいと思います。

他の Drupal 8 入門では Drupal 自体に馴染みの薄い方を対象としていますが、今回のものはどちらかというと Drupal 7 ですでに Drupal に馴染んでいる開発者の方が対象です。

はじめに

この記事をお読みの方であればご存知のとおり、 Drupal はマイナーバージョン( 7.34 であれば 34 の部分)のアップデートでの変更点は少なめですが、メジャーバージョン( 7.34 であれば 7 の部分)のアップデートによる変更は概して大がかりです。

こと Drupal 7 から 8 へのアップデートでいうと、そのままの形で使えるモジュールはほとんど存在しないといってもよいぐらいに大きな変更が加えられています。

また、 Drupal はすべて PHP ベースで書かれていますが、 Drupal のメジャーバージョンが上がごとに動作するのに必要な PHP のバージョンが少しずつ上がっていきます。 具体的には次のとおりとなっています。

  • Drupal 7: PHP 5.2.5 以上が必須( 5.4 以上を推奨)
  • Drupal 8: PHP 5.4.5 以上が必須

ですので、開発者視点でいうと Drupal 7 では PHP 5.2 も想定してコードを書く必要があったのに対して Drupal 8 では 5.4 以上を前提にコードを書くことができます。 PHP は 5.3 5.4 あたりでも着実に進化しているので、このあたりは Drupal 開発者としてはとてもうれしいポイントです。

では以下では、 PHP 5.3 と 5.4 とで新たに導入された機能をダイジェストで見ていきましょう。 網羅的なリストは公式のリリース文書に載っているので、ここでは Drupal の開発者 / テーマ制作者にとって特に注目のポイントだけ見ていくことにします。

PHP 5.3 の新機能

名前空間

PHP 5.3 ではようやく PHP にも名前空間が導入されました。 Drupal 8 でも至るところに名前空間が使われています。

// 名前空間 Otsu 内に Cat を定義
namespace Otsu;
class Cat {
  static function says() {
    echo 'nyao' . PHP_EOL;
  }
}

// 名前空間 Hikone 内に Cat を定義
namespace Hikone;
class Cat {
  static function says() {
    echo 'nyan' . PHP_EOL;
  }
}

// 異なる名前空間 Shiga に変更
namespace Shiga;

Otsu\Cat::says();  # エラー  <- Otsu は Shiga 内に存在しないため
\Otsu\Cat::says();  # => nyao  <- \ でルートからたどると Otsu が見つかる

use Otsu;
Otsu\Cat::says();  # => nyao  <- use を使えば Shiga 内で Otsu が使える

use Hikone as h;
h\Cat::says();  # => nyan  <- use as で名前空間の名前を変更することも可能

無名関数 / クロージャ

PHP 5.3 では無名関数とクロージャも使えるようになりました。 PHP では無名関数とクロージャが同じ意味のものとして使われている傾向があるように思いますが、厳密にいうと概念としては別物かと思います。

無名関数

// 無名関数を利用してフィルタリング
$result = array_filter(array(1,2,3,4), function($e) { return $e % 2 === 0; });
var_dump($result);  // => array(2, 4)

クロージャ

宣言時の周りのスコープの変数への参照を保持した関数、クロージャも作成することができます。 クロージャを定義するには function use シンタックスを使います。

function gen_print_with_prefix($prefix) {
  return function ($message) use ($prefix) {
    print "$prefix$message";
  };
}

$my_print = gen_print_with_prefix('I say: ');
$his_print = gen_print_with_prefix('He says: ');

$my_print('こんにちは' . PHP_EOL);
$his_print('こんにちは' . PHP_EOL);
$my_print('晴れましたね' . PHP_EOL);
// => 以下のとおりに出力
// I say: こんにちは
// He says: こんにちは
// I say: 晴れましたね

三項演算子の短縮形 ?:

三項演算子の短縮形である ?: が使えるようになりました。

$a = 5;
$b = 7;
$c = 0;

// 三項演算子の短縮形
$d = $a ?: $b;
$e = $c ?: $b;

print $d;  // => 5
print $e;  // => 7

クラスの外での const の使用

定数を定義するために、クラスの外で const キーワードが使えるようになりました。 クラスの外で const をつけて定義された変数は define() 関数で定義した場合と同様にその空間での定数となります。

const Shiga = 10;
// define('Shiga', 10) と同義

定数もきちんと各名前空間に所属します。

namespace Kansai;
const Shiga = 10;

namespace Wakayama;
echo \Kansai\Shiga;  // => 10

nowdoc

文字列型のリテラルとして nowdoc と呼ばれるものが新たに導入されました。 従来のヒアドキュメントとほとんど同じですが、ヒアドキュメントがダブルクォート( " )で囲われた文字列に相当するのに対し、 nowdoc はシングルクォート( ' )で囲われた文字列に相当します。 文字列内の変数が展開されない点がヒアドキュメントとのちがいです。

$romeo = '小野妹子';

// ヒアドキュメント
$mypoem =<< Oh, 小野妹子...
echo $mypoem_original;  // => Oh, $romeo...

つづいて PHP 5.4 の方を見ていきましょう。

定数 __DIR__ __NAMESPACE__

マジック定数に次の 2 つが追加されました。

  • __DIR__: 現在の実行中のコードがあるファイルのディレクトリ
  • __NAMESPACE__: 現在の名前空間
namespace Kansai;
echo __NAMESPACE__;  // => Kansai

echo __DIR__;  // => 現在のコードがあるファイルのディレクトリ
// PHP 5.2 以前の dirname(__FILE__) と同じ

PHP 5.4 の新機能

配列リテラルの短縮形

ついに! PHP にも!他のスクリプト言語ではメジャーな配列リテラル [] が導入されることになりました。 既存の array() にかえて [] を使うことができます。 インデックス配列も連想配列もどちらも [] が使えます。

$a = [3, 5, 7];
$b = ['bass' => 'ブラックバス', 'bbc' => 'びわ湖放送'];

ただし本記事執筆時点での Drupal コアのコードでは依然 array() が優勢のようです。

Traits

新しい概念として Traits というものが導入されました。 こちらはいわば「定数がない mix-in 」といった感じの仕組みです。 キーワード trait で定義して、 use でクラスに取り込みます。

// traits を定義
trait Walk {
  function walk() {}
}

trait Fly {
  function fly() {}
}

// traits をクラスに取り込む
class Bird {
  use Walk, Fly;
}

$b = new Bird();

// 以下のいずれもエラーにならずに呼び出せる
$b->walk();
$b->fly();

PHP 組み込み Web サーバ

PHP コマンドに組み込みの Web サーバが追加されました。 -S オプションでアドレスとポートを指定してローカルの簡易サーバを走らせることができます。

$ php -S localhost:8080  # 簡易サーバを localhost:8080 で走らせる
$ php -S localhost:8080 -t /drupal/root/dir  # ルートディレクトリの指定も可

Drupal の場合でいうと、この組み込みサーバを走らせる Drush のサブコマンドがすでに用意されています。

$ drush rs  # port 8888 で Drupal サーバを起動

関数の戻り値である配列の要素への直接アクセス

関数が返す戻り値が配列だった場合に、その要素に直接アクセスすることができる機能です。 英語では「 array dereference 」ということばで呼ばれている概念です。 こちらも PHP 5.4 から利用できるようになりました。

/**
 * 滋賀県内の JR の駅一覧を返す
 */
function get_stations() {
  return [
    '大津',
    '膳所',
    '石山',
  ];
}

// 関数の戻り値の配列を直接操作できる
// echo get_stations()[0];  // => 大津

この機能を使うとメソッドチェーンの間に配列があってもチェーンを繋ぐことができるようになります。

class Station {
  function __construct($name) {
    $this->name = $name;
  }

  function getName() {
    return $this->name;
  }
}

function get_station_objects() {
  $otsu = new Station(['大津', 'おおつ']);
  $zeze = new Station(['膳所', 'ぜぜ']);

  return [$otsu, $zeze];
}

// 戻り値に配列が入っていてもメソッドチェーンがつなげられる
echo get_station_objects()[0]->getName()[1];

同様に、コンストラクタでオブジェクトを生成した直後に直接そのメソッドにアクセスすることもできるようになっています。

echo (new Station('大津'))->getName();

echo のショートカット表記

short_open_tag の設定によらず常に <?= が使えます。 次の 2 つのコードは同義です。

<h1><?= $title ?></h1>  



<h1><?php echo $title; ?></h1>  

Drupal 8 の場合でいうとデフォルトのテンプレートエンジンが Twig に代わるためこの変更点の恩恵を得る機会はあまり多くはないかもしれません。

おわりに

以上です。 いかがだったでしょうか?

今回は Drupal 7 から 8 にバージョンが上がるにあたって新たに使えるようになる PHP の機能( Drupal の中でサポートされると思ってよい機能)をいくつかピックアップしてご紹介しました。 今回ご紹介したものの他にも PHP 5.3 、 PHP 5.4 で新たに導入された機能や記法はたくさんあります。 興味のある方はぜひ参考リンクの PHP の公式ページなどもご覧になってみてください。


共に働く新しい仲間を
募集しています

スタジオ・ウミは「Drupal」に特化したサービスを提供する Drupal のエキスパートチーム。
フルリモート&フレックス制だから、働く場所を選ばず時間の使い方も自由です。
そんなワークライフバランスの整った環境で、当ブログに書かれているような
様々な技術を共に学びながら、Drupalサイト開発に携わってみたい方を募集しています。
まずはお話だけでも大歓迎!ぜひお気軽にご連絡ください。