PHP5.5はこんなふうになるかも！？


*これは[What PHP 5.5 might look like](http://nikic.github.com/2012/07/10/What-PHP-5-5-might-look-like.html)の翻訳です。誤訳などあればコメントくださいm(_ _)m*

PHP5.4が4ヶ月前にリリースされました。なので、次のPHPのバージョンを見るのはちょっと早すぎるかもしれません。ですが、[Internalsメーリングリスト](http://php.net/mailing-lists.php)をフォローしていないすべての方に、PHP5.5がどのようになるかについて紹介したいと思います。


ただし、この点は理解して下さい: PHP5.5は初期開発の段階にあります。なので、誰も最終結果がどのようになるか知りません。私がここで話すものはすべて *提案(proposal)* のものについてです。以下に挙げるすべてのものがPHP5.5に盛り込まれるとは限りません。


ですので、これについてあまり盛り上がりすぎないでください :)


この新機能/提案のリストは大きく、重要度順ではありません。なので、すべてを読みたくない人には、ここに4つの機能をあげておきます。私が個人的に面白いと思った機能です。

   * パスワードハッシュ化のためのシンプルなAPI
   * スカラータイプヒンティング
   * ゲッターとセッター
   * ジェネレーター

では、前置きはこれくらいにして、PHP5.5で取り組まれているもののリストを見てみましょう。


## 非上位互換 

まず、既にmasterに取り込まれている2つの非上位互換の変更からはじめましょう。

### Windows XP と 2003 のサポート終了

Status: landed; Responsible: Pierre Joye

PHP 5.5 はこれ以上Windows XPと2003をサポートしません。これらのシステムは10年ほど前のものです。なので、PHPはそれらの対応を終了します。


### `/e` 修飾子が非推奨になる


Status: landed; Responsible: myself


`e` 修飾子は `preg_replace` 関数に対し、単純な置換をする代わりに、置換文字列をPHPコードとして評価するよう命令するものです。予想できると思いますが、この挙動は問題が絶えず、セキュリティ的にも問題があります。これが、PHP5.5でこの修飾子を使うと非推奨警告を投げるようになる理由です。代替手段としては ` preg_replace_callback` 関数を使うといいでしょう。この変更についてもっと知りたい場合は[こちらのRFC](https://wiki.php.net/rfc/remove_preg_replace_eval_modifier)を御覧ください。


## 関数とクラスの追加

次に追加予定の関数とクラスを見てみましょう。

### boolval()

Status: landed; Responsible: Jille Timmermans

PHPはすでに `strval`, `intval` そして `floatval` 関数を実装しています。首尾一貫するために、 `boolval` 関数が新たに追加されます。この関数自体は `(bool)` でキャストするのと同じものですが、コールバック関数で使えるようになります。

### hash_pbkdf2()

Status: landed; Responsible: Anthony Ferrara

[PBKDF2](http://en.wikipedia.org/wiki/PBKDF2)はPassword-Based Key Derivation Function 2の略で、名前が語っているように、パスワードから暗号化キーを取得するためのアルゴリズムです。これは暗号化アルゴリズムに必要ですが、パスワードのハッシュ化にも使うことができます。詳しい説明と使い方については[RFC](https://wiki.php.net/rfc/hash_pbkdf2)を御覧ください。

### 国際化関数(intl)の追加

Status: landed; Responsible: Gustavo André dos Santos Lopes


intl拡張には多くの改良があります。例えば、新たに `IntlCalendar` , `IntlGregorianCalendar`, `IntlTimeZone`,  `IntlBreakIterator`, `IntlRuleBasedBreakIterator`, `IntlCodePointBreakIterator` クラスが追加されます。残念ながら私はintl拡張についてよく知りませんので、メーリングリスト上の[Calendar](http://markmail.org/thread/b7sldwebskmhbxmx)と[BreakIterator](http://markmail.org/thread/ulnm3hhist5ygido)のアナウンスへのリンクを紹介する程度にしておきます。興味があれば御覧ください。


### array_column()

Status: proposed; Responsible: Ben Ramsey

これは `array_column` (または `array_pluck`) 関数についての[提案](https://wiki.php.net/rfc/array_column)です。この関数は次のような動作をします。

```php
<?php

$userNames = array_column($users, 'name');
// は次と同じ
$userNames = [];
foreach ($users as $user) {
    $userNames[] = $user['name'];
}
```

これはデータベースからカラムを取得するような感じでしょうが、配列に対して使うものです。

### パスワードハッシュ化のためのシンプルなAPI

Status: proposed; Responsible: Anthony Ferrara

最近のパスワード漏洩事件(LinkedInなど)は、大きなウェブサイトでさえ適切にパスワードをハッシュ化する方法を知らないということを示しています。中には数年前から bcrypt を使うべきと主張する人がいましたが、まだ多くの人が完全に安全でない `sha1` ハッシュを使っています。

私たちは、この原因に `crypt` 関数のAPIの使いにくさがあるのだろうと気づきました。そこで、私たちは安全なパスワードハッシュのための新しくシンプルなAPIを紹介したいと思います。


```php
<?php
$password = "foo";

// ハッシュを作る
$hash = password_hash($password, PASSWORD_BCRYPT);

// パスワードをチェックする
if (password_verify($password, $hash)) {
    // 正しいパスワード
} else {
    // 間違っているパスワード
}

```

この新しいハッシュAPIは他にもいくつかの機能がついています。詳細は [RFC](https://wiki.php.net/rfc/password_hash) にアウトラインがあります。

## 言語仕様の変更

実に興味深い項目にやってきました。言語の新仕様と強化についてです。

### コンスタント・デリファレンス(Constant dereferencing)
Status: landed; Responsible: Xinchen Hui

「コンスタント・デリファレンス」は文字列や配列リテラルに対して、直接的に配列操作できるというものです。ここに2つの例があります。

```php
<?php

function randomHexString($length) {
    $str = '';
    for ($i = 0; $i < $length; ++$i) {
        $str .= "0123456789abcdef"[mt_rand(0, 15)]; // 文字列のダイレクトデリファレンス
    }
}


function randomBool() {
    return [false, true][mt_rand(0, 1)]; // 配列のダイレクトデリファレンス
}

```

私はこの機能が実際にたくさん使われるとは思いませんが、これが言語仕様をより首尾一貫したものにすると思います。これについても[RFC](https://wiki.php.net/rfc/constdereference)を参照してください。

### empty()が関数コールで動くようになる

Status: landed; Responsible: myself

現在、`empty()` 言語構造は変数に対してのみ使用可能です。他の表現には使用できません。たとえば `empty($this->getFriends())` のようなコードはエラーが投げられます。PHP5.5ではこれは正しいコードになります。詳細は[RFC](https://wiki.php.net/rfc/empty_isset_exprs)を御覧ください。

### クラスの完全名を取得する

Status: proposed; Responsible: Ralph Schindler


PHP5.3では、クラスにエイリアスをつけることができる機能と共にネームスペースが追加されました。しかし、このエイリアスは文字列のクラス名には適用できません。

```php

<?php
use Some\Deeply\Nested\Namespace\FooBar;

// これはグローバルの FooBar クラスを使おうとするので、動きません。
$reflection = new ReflectionClass('FooBar');
```


これを解決するために、新しく `FooBar::class` シンタクスが提案されています。これは、クラスの完全名を返すものです。


```php
<?php

use Some\Deeply\Nested\Namespace\FooBar;

// FooBar::classは "Some\\Deeply\\Nested\\Namespace\\FooBar" と解釈されるので動きます。
$reflection = new ReflectionClass(FooBar::class);
```


詳しい例については[RFC](https://wiki.php.net/rfc/class_name_scalars)を御覧ください。


### パラメータスキップ

Status: proposed; Responsible: Stas Malyshev


現在は、複数の任意引数を受け取る関数で、最後のひとつだけを変更し、他の引数をデフォルトのままにする方法がありません。

[RFC](https://wiki.php.net/rfc/skipparams)からの例を見てみましょう。下記のような関数で、

```
function create_query($where, $order_by, $join_type='', $execute = false, $report_errors = true) { ... }
```

他の2つのデフォルト値をコピーせずに `$report_errors = false` をセットする方法がありません。これを解決するために、パラメータスキップの方法が提案されています。

```
create_query("deleted=0", "name", default, default, false);
```

個人的にこの提案はあまり好きではありません。この機能が必要なコードは単に設計が悪いからだと思うからです。関数は 12個もの任意パラメータを持つべきではありません。


### スカラータイプヒンティング

Status: proposed; Responsible: Anthony Ferrara

スカラータイプヒンティングは本来5.4で取り込まれる予定でした。しかし、合意が間に合わず取り込まれませんでした。なぜスカラータイプヒンティングがまだPHPに取り込まれていないか知らいたい方は [Scalar typehints are harder than you think](http://nikic.github.com/2012/03/06/Scalar-type-hinting-is-harder-than-you-think.html) を御覧ください。

PHP 5.5では討論が再度行われました。[キャスト付きスカラータイプヒンティングの提案](https://wiki.php.net/rfc/scalar_type_hinting_with_cast)がだいぶいいのではないかと思います。

これは入力値を特定の型にキャストするものですが、データのロスなしでキャストできる場合に限ります。例えば `123`, `123.0`, `"123"` は `int` パラメータの入力値として正しいということになりますが、 `"hallo world"` は正しくない入力値になります。これは、内部関数の挙動と同じです。

```
function foo(int $i) { ... }

foo(1);      // $i = 1
foo(1.0);    // $i = 1
foo("1");    // $i = 1
foo("1abc"); // not yet clear, maybe $i = 1 with notice
foo(1.5);    // not yet clear, maybe $i = 1 with notice
foo([]);     // error
foo("abc");  // error
```

### ゲッターとセッター

Status: proposed; Responsible: Clint Priest

もしあなたが `getXYZ()` や `setXYZ($value)` のようなメソッドをいちいち書くことが面倒だと感じているのであれば、この変更はあなたにとって歓迎すべきものでしょう。この提案は、プロパティがセット/ゲットされたときに、何が起こるかを定義するためのシンタクスを追加します。

```php
<?php

class TimePeriod {
    public $seconds;

    public $hours {
        get { return $this->seconds / 3600; }
        set { $this->seconds = $value * 3600; }
    }
}

$timePeriod = new TimePeriod;
$timePeriod->hours = 10;

var_dump($timePeriod->seconds); // int(36000)
var_dump($timePeriod->hours);   // int(10)
```

他にも read-only プロパティのような機能もあります。より詳しく知りたければ[RFC](https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented)を御覧ください。

### ジェネレーター

Status: proposed; Responsible: myself

現在、カスタムイテレータはあまり使われません。実装が多くのひな形コードを必要とするためです。ジェネレーターは、イテレータを作るためにひな形コードいらずの簡単な方法を提供してこの問題を解決します。

たとえば、これはイテレータとして `range` 関数がどのように定義できるかの例です。


```php
<?php

function *xrange($start, $end, $step = 1) {
    for ($i = $start; $i < $end; $i += $step) {
        yield $i;
    }
}

foreach (xrange(10, 20) as $i) {
    // ...
}
```

上の `xrange` 関数はビルトイン関数の `range` と同じ動きをしますが、ひとつの違いがあります。すべての値を含んだ配列を返す代わりに、値をその都度生成するイテレータを返します。

より深い紹介については[RFC](https://wiki.php.net/rfc/generators)のトピックを御覧ください。


### リスト内包表記とジェネレーター表現

Status: proposed; Responsible: myself


リスト内包表記は小さな配列操作に簡単な方法を提供します。

```
$firstNames = [foreach ($users as $user) yield $user->firstName];
```

上のリスト内包表記は次のコードと等価です。

```
$firstNames = [];
foreach ($users as $user) {
    $firstNames[] = $user->firstName;
}
```

また、次の方法で配列をフィルタすることもできます。

```
$underageUsers = [foreach ($users as $user) if ($user->age < 18) yield $user];
```

ジェネレーター表現と似ていますが、配列を返す代わりにイテレータを返します。

もっと例をご覧になる場合は[メーリングリストのアナウンス](http://markmail.org/thread/uvendztpe2rrwiif)を御覧ください。


## まとめ

ご覧のとおり、PHP5.5のための素晴らしい提案が沢山あります。しかし、上で言ったとおり、PHP5.5はまだ初期段階です。なので、どれが採用され、どれが採用されないかはまだわかりません。

新機能について最新情報を受け取りたい、ディスカッションや開発を手伝いたいという方は、internalsメーリングリストを購読してみてください。