Help us understand the problem. What is going on with this article?

PHP バージョン別 新機能 メモ

More than 3 years have passed since last update.

5.3

名前空間

名前の衝突を避けるのにつかう。

宣言

宣言
<?php
// namespaceより上はdeclareしか許されない
namespace Sample;
宣言(階層あり)
namespace Sample\Hoge;

考え方
namespace付のクラスなどは、ファイルシステムと同じ考え方ができる。

namespace Sample; // ここはSampleディレクトリですよー的な気持ち

function test() {} //[1]

class Hoge
{
  public static function test() {} // [2]
}

test();  // [1]になる(Sample\test関数を実行)
Hoge::test();  // [2]になる(Sample\Hogeクラスのtest関数を実行)

グローバルなものへのアクセス

\test();

現在の名前空間を表す定数とキーワード

namespace Sample;

function hoge(){}

$str = __NAMESPACE__ . '\' . 'hoge'; // Sample\hoge

namespace\func(); // Sample\func関数を実行

※5.6にて、ClassName::classで完全修飾子が取得できる

エイリアス

namespace Sample;

use Hoge\Fuga\Bar as Another;  // Anotherというエイリアスになる
use Hoge\Fuga\Bar; //「use Hoge\Fuga\Bar as Bar;」と一緒

use ArrayObject;  // グローバルクラスのインポートになる

※5.6では関数や定数のエイリアスもできる

use function Hoge\Fuga\Bar\func;
use const Hoge\Fuga\Bar\CONS;

※7.0ではuseをグループ化できる

// 7.0以前
use Hoge\Fuga\ClassA;
use Hoge\Fuga\ClassB as B;

// 7.0以降
use Hoge\Fuga\{ClassA, ClassB as B};

遅延静的束縛

「static::」のこと。

静的継承において、親で子クラスを参照できる。

「直近」の「非転送コール」時に、
「明示されたクラス名を保持」する機能!!!!!!!

↑ 意味わからないので、わかりやすくする ↓

[1]非転送コールとは
クラス名やオブジェクトを明示的にした関数呼び出し。

非転送コール例
Hoge::test1();  //Hogeってクラスだと明示してるよね
$hoge->test1(); //$hogeオブジェクトだと明示してるよね

※ちなみに転送コールは「self::」などのクラス内での呼び出しらしい

[2]遅延静的束縛とはこういうこと

class Hoge
{
  static protected $txt = 'Hogeですよ';

  public static function test1() {
    return self::txt;
  }
  public static function test2() {
    return static::txt;  // 遅延静的束縛
  }
}

class Fuga extends Hoge
{
  static protected $txt = 'Fugaですよ';
}

/*
 * test2関数はHogeクラスに存在するが、
 * 非転送コール的にはFugaクラスになる。
 * 
 * ので、static = Fugaになる
 */
Fuga::test1();  // Hogeですよ
Fuga::test2();  // Fugaですよ

[3]「直近」の「非転送コール」
「static::」にたどり着く道のりで、
複数回の非転送コールがあった場合、
「直近」の非転送コールのクラスが使用されるということ。

class Hoge
{
  static protected $txt = 'Hogeですよ';

  public static function test1() {
    return Hoge::test2();
  }
  public static function test2() {
    return static::txt ;  // 遅延静的束縛
  }
}

class Fuga extends Hoge
{
  static protected $txt = 'Fugaですよ';
}

/*
 * [1]Fuga::test1();
 *     → static = Fuga
 *     
 * [2]return Hoge::test2();
 *     → static = Hoge
 *     
 * [3]return static::txt;
 *     → [2]が直近として適用される
 */
Fuga::test1(); // Hogeですよ

参考:PHPを愛する試み 〜self:: parent:: static:: および遅延静的束縛〜

ジャンプラベル

goto文のこと。

goto a;  // aっていうラベルに飛ぶぜ
echo 'Foo';

a:
echo 'Bar';
Bar

無名関数(クロージャ)

コールバックに使ったり、変数に関数をセットできたり。

$func = function($txt) {
  echo $txt;
};

$func('Hello');

use
親のスコープの変数を引き継ぎたいときに使う。

通常のパターン
$hoge = 'hoge';
$func = function() use($hoge) {
  echo $hoge;
}

$func();  // hoge
$hoge = 'fuga';
$func();  // hoge(宣言時の値が必ず使われる)
参照渡しにすると
$hoge = 'hoge';
$func = function() use(&$hoge) {
  echo $hoge;
}

$func();  // hoge
$hoge = 'fuga';
$func();  // fuga

this
5.4以降のはなし。
現在のクラスにバインドされる。

Nowdoc

ヒアドキュメント→ダブルクォートで囲った扱い
Nowdoc→シングルクォートで囲った扱い(パースしない)

$txt = <<<'EOD'
hoge
fuga
EOD;

constがクラス外でも使える

<?php
const HOGE = 'Hoge';

5.4

トレイト

多重継承ができないPHPに、水平方向でメンバー(関数、プロパティ)を追加する方法。

トレイトはクラスの装備みたいなもの。
※トレイトにトレイトを装備もできる

クラスに似ているが、クラスでない。
よってインスタンス化はできない。

trait Sample
{
  function hoge() {}
  function fuga() {}
}

class Test
{
  use Sample;
  // 複数ならカンマ区切りで→「use Sample1,Sample2;」
}

優先順位
現在のクラスのメソッド > トレイトのメソッド > 継承したクラスのメソッド

名前の衝突を回避

使うもの 説明
insteadof 使うメソッドを一つに限定する
as エイリアスをつける、可視性も変更できる
class Sample
{
  use A,B {
    B::Method insteadof A;  //Aのかわりに、BのMethodを使う
    A::Method as MethodA;   //MethodAという関数名で呼び出す
    // A::Method as protected MethodA;
  }
}

クラスのメンバーを強制させる

trait Sample
{
  public function sampleFunction() {
    return $this->hello();  // [1]helloがないならエラーになってしまう
  }

  abstract public function hello();  // [2]ので、helloを強制
}

class Test
{
  use Sample;

  public function hello() {}  // [3]実装しなければならない
}

トレイトの存在意義

トレイトは、PHPの「多重継承ができない」ことによるデメリットを補う為に生まれた。
 -> 多重継承(複数の親を持つ)のメリットは、「ソースコードの再利用性」
  -> トレイトを使わない = ソースのコピペが増えがち
   -> 再利用性の高いコードはトレイトにしよう!

配列の短縮構文

$array = [
  'key1' => 1,
  'key2' => 2,
];

(7.1)取り出した値の代入でも

[$a, $b] = [1, 2];

foreach($data as [$c, $d]) {}

関数の戻り値を配列として扱える

個人的に重要だったので。

hoge()[0];

5.5

ジェネレータ

シンプルなイテレータを実装できる。

「returnではなく、yieldで結果を返す関数を作ること」
と覚えればいいかも。

メリット
Iteratorオブジェクトを作るより楽で、
配列作ってまわすよりメモリが節約できる。
いいことづくめ。

デメリット
前にしか進めない。
戻れないので、またジェネレータ関数を使って・・みたいなことをする必要がある。

/*
 * foreachでイテレータオブジェクトとして指定されたら、
 * $valueに値がセットされるようにyieldを
 */
function yieldTest($num) {
  for($i = 0; $i < $num; $i++) {
    yield $i;  // foreachの$valueに1,2,3・・とセットされる
  }
}

// yieldTestはジェネレータオブジェクト
foreach(yieldTest(10) as $value) {
  echo $value;
}

(7.0)return
7.0からreturnもかけるようになった。
returnの値を取得して、ごにょごにょ~みたいなことができるように?

$gen = (function gen() {
  yield 1;
  yield 2;
  return 3;
})();

foreach($gen as $val) {}

echo $gen->getReturn(); // 3

(7.0)yieldに配列やオブジェクトを指定し、順番に処理させる

yield from [1, 2]; // 1,2と順番に返却

finally

try~catchでfinallyもかけるようになった。

foreachとlistのコンボ

$array = [
  [1, 2],
  [3, 4]
];

foreach($array as list($a, $b)) {
  echo $a . $b;
  //loop1 → 12
  //loop2 → 34
}

5.6

可変長引数リスト

引数で...を使う

function hoge(...$args) { // $argsは配列として扱われる
  foreach($args as $val) {
    echo $val;
  }
}

hoge(1, 2, 3); // $args = [1, 2, 3];

関数呼び出しで...を使う

function hoge($a, $b) {
  echo $a . $b;
}

hoge(...[1, 2]);

7.0

型宣言(タイプヒンディング)の強化

関数に渡す引数の型を強制させる仕組みは古くからあったが、
7でようやくスカラー型宣言が可能に!

さらに7からは戻り値の型宣言も可能。
戻り値の型がそぐわない場合、暗黙的な変換が行われる。

引数
function hoge(int $num) {}
戻り値
function hoge(int $num): string {
  return $num;
}

var_dump(hoge(1)); // string(1)
指定 利用最低バージョン
クラス/インターフェイス 指定したクラスやインターフェイスのインスタンスを強制 PHP 5.0
self そのメソッドが定義されているクラスと同じクラスのインスタンスを強制 PHP 5.0
array 配列を強制 PHP 5.1
callable callableを強制 PHP 5.4
bool booleanを強制 PHP 7.0
float floatを強制 PHP 7.0
int integerを強制 PHP 7.0
string stringを強制 PHP 7.0
iterable 配列かイテレータを強制 PHP 7.1

厳密化
ファイル単位で以下を記述すると、
宣言された型以外ではエラーとなる。

厳密化
<?php
declare(strict_types=1);

(7.1)nullable
型の前に?を書くと、nullも許容する。

function hoge (): ?string {}

(7.1)戻り値の型宣言にvoid
戻り値の型宣言に
「reutrn;」、もしくは何も記載しない
voidを指定できるようになった。

無名クラス

「new class」を用いて、その場限りのオブジェクトを用意する。

%obj = new class {};

7.1

クラス定数にアクセス修飾子が使える

public const HOGE = 1;

保留

OPCache(5.5)

phpdbg(5.6)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away