2019年11月28日、PHP7.4.0がリリースされました!
https://www.php.net/archive/2019.php#2019-11-28-1
公式ドキュメントで発表された新機能のうち、この記事ではPHPコア部分の機能について詳しくみていきたいとおもいます✨
※ 各コードは公式ドキュメントから引用の上、一部編集しています。
型付きプロパティ
クラスのプロパティに、型を宣言できるようになりました。
class User {
public int $id;
public string $name;
}
宣言した型以外の値を代入しようとすると、エラーが教えてくれます。
$user = new User();
$user->id = 2; // エラーなし
$user->id = 'test'; // Fatal error: Uncaught TypeError: Typed property User::$id must be int, string used in...
これまで通りに宣言なしでも動くので、上手く使い分けていきたいですね!
// これも動く
class User {
public $id;
public $name;
}
個人的には、宣言するのを基本として、動的型付けをしたいプロパティだけ宣言なしにするのが良いとこ取りできて良いのではと思っています。
アロー関数
アロー関数は、ざっくり言うと”function”を記述せずに関数を定義できる書き方です。
function 関数名(引数) {
処理
}
fn(引数) => 処理
例えば、コールバック関数を指定すべきところにこのアロー関数を使うと大幅にコード量を減らすことができます。
function cube($n)
{
return($n * $n * $n);
}
$a = array(1, 2, 3, 4, 5);
$b = array_map("cube", $a);
print_r($b);
$a = array(1, 2, 3, 4, 5);
$b = array_map(fn($n) => $n * $n * $n, $a);
print_r($b);
結果はどちらの書き方でも変わらず、以下のようになります。
Array
(
[0] => 1
[1] => 8
[2] => 27
[3] => 64
[4] => 125
)
返り値の型を狭めたり、引数の型を広げたりする
型の変位指定が行えるようになりました。
<?php
class Water {}
class Wine extends Water {}
class Glass {
public function pour(): Water {}
}
class WineGlass extends Glass {
public function pour(): Wine {}
}
WineクラスはWaterクラスを継承しているので、型の広さはWater > Wineとなります。
従来であれば、WineGlassクラスのpour()メソッドではGlassクラスのpour()メソッドと同じ返り値の型を指定する必要がありましたがが、PHP7.4 からは型を狭めることができるようになったので、上記のコードが成り立つようになりました。
私もまだ 変位指定についての知識が浅いので、使いどころ等詳しいことが分かり次第また更新したいと思います(参考文献などございましたら、 @muchoco_dev 宛に教えていただけると大変嬉しいです!)。
Nullの場合の代入演算子
「値がNullの場合、とある値を代入する」という処理が日常的に行われているかと思いますが、代入演算子を使って1行で書くことができるようになりました!
if (!isset($array['key'])) {
$array['key'] = 1;
}
$array['key'] ??= 1;
これは地味に嬉しい……。
今後使う人が増えると予想されるので、コードリーディングのときに「これなんだっけ?」とならないようにしっかりと覚えておきたいです。
配列内での値のアンパック
配列の任意の場所に、別の配列の要素をまとめて追加できるようになりました。
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// $fruitsの中身
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
上の例のように、別の配列の要素を追加したい場所に「…(ドット3つ)」と変数名を記入するだけで、中身を展開して追加してくれます。
便利かつ直感的に分かりやすい記法ですね!
数値リテラルのセパレータ
数値の間にアンダースコアを挿入できるようになりました。
6.674_083e-11; // float
299_792_458; // decimal
0xCAFE_F00D; // hexadecimal
0b0101_1111; // binary
内部ではアンダースコアがないものと同等に扱われ、おそらく人間が見やすくするためのものだと思います。
var_dump(299_792_458);
// int(299792458)
弱参照
弱参照のWeakReferenceクラスを使えるようになりました。弱参照を使用することで、 オブジェクトの破棄を防がない参照を保持することができます。
https://www.php.net/manual/ja/class.weakreference.php
例えば次のように使用します。
$obj = new stdClass;
$weakref = WeakReference::create($obj);
var_dump($weakref->get()); // object(stdClass)#1 (0) { }
unset($obj);
var_dump($weakref->get()); // NULL
このコードは、下記のような処理を行っています。
$weakref = WeakReference::create($obj);
$objの新しい弱参照を作成の上、$weakrefに代入。
$weakref->get();
弱参照されたオブジェクトを取得。
unset($obj);
$objを破棄。
弱参照は既に他のいくつかの言語でサポートされており、主にキャッシュモジュールの実装などに活用されています。PHPでも今後同様に活用されていくことと思われます。
__toString()から例外をスロー可能に
__toString()メソッドは、クラスが文字列に変換される際の動作を定めるマジックメソッドです。
https://www.php.net/manual/ja/language.oop5.magic.php
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
public function __toString()
{
return $this->foo;
}
}
$class = new TestClass('Hello');
echo $class;
Hello
$classはTestClassオブジェクトが代入されていますが、文字列として扱われた場合は__toString()メソッドでコンストラクタの引数として受け取った値を返すと定義してあるので、Helloが出力されます。
ただし、これまでは__toString()メソッド内で例外をスローすることはできないという制限があり、次のようなコードでは致命的なエラーが発生していました。
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
public function __toString()
{
if (!$this->foo) {
throw new Exception('文字列が空です');
}
return $this->foo;
}
}
$class = new TestClass('');
try {
echo $class;
} catch(Exception $e) {
echo $e->getMessage();
}
Fatal error: Method TestClass::__toString() must not throw an exception, caught Exception: 文字列が空です in ...
この制限がPHP7.4からはなくなり、上記のような例外処理つきコードが動くようになりました。
文字列が空です
以上が、PHP7.4のPHPコアに関するアップデート内容です。