記事内にはプロモーションが含まれています

【PHP】型宣言の完全ガイド!引数・戻り値・プロパティでの書き方

【PHP】型宣言の完全ガイド!引数・戻り値・プロパティでの書き方 PHP

PHPはもともと「動的型付け言語」として知られ、変数の型を意識せずにコードを書ける柔軟さが魅力でした。

しかし、大規模な開発やチーム開発においては、その柔軟さがバグの原因になることも少なくありません。

そこで近年、PHPの開発現場で重要視されているのが「型宣言(タイプヒンティング)」です。
関数の引数や戻り値、クラスのプロパティに明示的に型を指定することで、エラーを未然に防ぎ、コードの可読性を劇的に向上させることができます。

この記事では、PHPにおける型宣言の基礎から、PHP 8で導入された「ユニオン型」や「交差型」といった最新機能、さらには配列やクラスでの実践的な使い方までを網羅的に解説します。

曖昧なコードから卒業し、堅牢なアプリケーションを作るための知識を身につけましょう。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はこじんまりとしたプログラミングスクールを運営
  • モットーは「利他の精神」

PHPの型宣言(タイプヒンティング)とは?

型宣言とは、関数やメソッドがどのような種類のデータ(型)を受け取り、何を返すのかをプログラム内で明示する機能のことです。

以前は「タイプヒンティング」と呼ばれていましたが、現在では言語仕様としてより厳密に統合されたため、単に「型宣言」と呼ばれることが一般的です。

型宣言を行うメリット

型宣言を導入することには、主に3つの大きなメリットがあります。

バグの早期発見
意図しない型のデータが渡された時点でエラーが発生するため、開発段階でバグに気づくことができます。
例えば、数字を計算する関数に文字列が渡されるといったミスを防げます。

コードの可読性向上
関数定義を見るだけで、「何を受け取って何を返すのか」が一目瞭然になります。
ドキュメントやコメントを確認する手間が省け、他のエンジニア(あるいは未来の自分)がコードを理解する助けになります。

IDE(統合開発環境)の支援
型情報が明確になることで、VS CodeやPhpStormなどのエディタが強力なコード補完や静的解析を提供できるようになります。
これにより、開発効率が飛躍的に上がります。

PHP 7からPHP 8への進化

PHP 5時代はクラスや配列など一部の型しか指定できませんでしたが、PHP 7でスカラー型(int, stringなど)や戻り値の型宣言が可能になり、実用性が大幅に向上しました。

さらにPHP 8以降では、複数の型を許容する「ユニオン型」や、複数の型をすべて満たす「交差型」などが導入され、柔軟かつ厳密な型定義が可能になっています。

現代のPHP開発において、型宣言はもはや必須のスキルと言えるでしょう。

型宣言の基本的な書き方と一覧

それでは、実際にPHPコードでどのように型を宣言するのか、具体的な書き方を見ていきましょう。

主に関数の「引数」と「戻り値」、そしてクラスの「プロパティ」に対して指定を行います。

関数の引数に型を指定する

関数の引数に型を指定するには、変数名の前に型名を記述します。

<?php
// int型の引数を受け取る関数
function calculateTotal(int $price, int $quantity) {
    return $price * $quantity;
}

// 正常な呼び出し
echo calculateTotal(100, 5); // 出力: 500

// 型が異なる場合(デフォルトでは自動変換される場合もあるが、推奨されない)
// calculateTotal("100", "5"); 
?>

このように記述することで、$price$quantity は必ず整数として扱われることが保証されます。

関数の戻り値に型を指定する

関数が返す値の型を指定するには、引数リストの閉じ括弧 ) の後ろにコロン : を書き、その後に型名を記述します。

<?php
// 戻り値がstring型であることを宣言
function getGreeting(string $name): string {
    return "こんにちは、" . $name . "さん";
}

$message = getGreeting("田中");
var_dump($message);
?>

実行結果は以下の通りです。

string(25) "こんにちは、田中さん"

もし、この関数内で return 100; のように数値を返そうとすると、PHPは TypeError を発生させます。
これにより、関数の仕様と実装の不整合を防ぐことができます。

クラスのプロパティに型を指定する

PHP 7.4以降では、クラスのプロパティ(メンバ変数)にも型宣言が可能になりました。

<?php
class User {
    // プロパティへの型宣言
    public int $id;
    public string $name;
    public bool $isActive;

    public function __construct(int $id, string $name) {
        $this->id = $id;
        $this->name = $name;
        $this->isActive = true;
    }
}

$user = new User(1, "佐藤");
echo $user->name;
?>

プロパティに型を指定することで、オブジェクトの状態が予期せず不正な型になることを防げます。
初期化される前のプロパティにアクセスするとエラーになるため、初期化忘れの防止にもつながります。

利用できる型の一覧

PHPの型宣言で使用できる主な型は以下の通りです。

型宣言 説明 対応バージョン
int 整数 PHP 7.0~
float 浮動小数点数 PHP 7.0~
string 文字列 PHP 7.0~
bool 真偽値(true / false) PHP 7.0~
array 配列 PHP 5.1~
object オブジェクト PHP 7.2~
iterable 配列またはTraversable PHP 7.1~
mixed 任意の型 PHP 8.0~
void 値を返さない(戻り値のみ) PHP 7.1~
クラス名/IF名 特定のクラスやインターフェース PHP 5.0~

複数の型やNullを扱う高度な型宣言

実務では、「文字列か、もしくはNullを受け入れたい」「数値または文字列を返したい」といった柔軟な対応が必要になるケースが多々あります。

PHP 8系では、こうした要求に応えるための表現力が大幅に強化されています。

Nullを許容する(?型名)

引数や戻り値で null を許可したい場合は、型名の前に ? を付けます。
これを「Nullable(ヌーラブル)型」と呼びます。

<?php
// string または null を受け取り、string または null を返す
function findUser(?int $id): ?string {
    if ($id === 1) {
        return "ユーザーA";
    }
    return null; // nullを返してもエラーにならない
}

var_dump(findUser(1));
var_dump(findUser(null));
?>

実行結果は以下の通りです。

string(13) "ユーザーA"
NULL

?string と書くことで、「基本は文字列だが、値がない(null)場合も許容する」という意図を明確に表現できます。

複数の型を許容するユニオン型(Union Types)

PHP 8.0からは、2つ以上の異なる型を受け入れる「ユニオン型」が導入されました。
型同士を |(パイプ)で繋いで記述します。

<?php
// int または float を受け取る
function addNumber(int|float $number1, int|float $number2): int|float {
    return $number1 + $number2;
}

echo addNumber(10, 2.5); // 12.5 (float)
?>

これにより、以前はドキュメントコメント(PHPDoc)でしか表現できなかった「数値または文字列」といった仕様を、コードレベルで強制できるようになりました。

交差型(Intersection Types)とDNF型

PHP 8.1では、複数の型(クラスやインターフェース)をすべて満たす必要がある「交差型」が登場しました。型同士を & で繋ぎます。

さらにPHP 8.2からは、ユニオン型と交差型を組み合わせた「DNF型(Disjunctive Normal Form)」も利用可能です。

<?php
interface A {}
interface B {}

// A かつ B を満たすオブジェクトのみ受け取る(交差型)
function execute(A&B $obj) {
    // ...
}

// (AかつB) または null を受け取る(DNF型)
function executeOrNull((A&B)|null $obj) {
    // ...
}
?>

これらは高度なオブジェクト指向設計を行うフレームワークやライブラリ開発で特に威力を発揮します。

mixed型とvoid型

mixed型
「どんな型でもよい」ことを明示する型です(PHP 8.0~)。
型を指定しないのと動作は似ていますが、「あえて型を問わない」という意図を伝えるために使われます。

void型
「値を返さない」ことを明示する戻り値の型です。
return; は許されますが、return 値; を書くとエラーになります。

配列やクラスなど具体的なケースでの型宣言

ここでは、現場でよく遭遇する具体的なデータ構造に対する型宣言のパターンを紹介します。

配列(array)の型宣言

配列を受け取る場合は array を指定します。

ただし、PHPの型宣言では「文字列の配列(string[])」や「整数の配列(int[])」といった中身の型までは指定できません

<?php
function processList(array $items) {
    foreach ($items as $item) {
        // ここで $item の型チェックが必要になる場合がある
        echo $item . "\n";
    }
}

processList(["apple", "banana"]);
?>

中身の型まで厳密に指定したい場合は、PHPDoc(コメント)を併用するのが一般的です。

/**
 * @param string[] $items
 */
function processList(array $items) { ... }

クラス・インターフェースの型宣言

特定のクラスのインスタンスを受け取りたい場合は、そのクラス名を型として指定します。

これにより、渡されるオブジェクトがそのクラス(またはサブクラス)であることを保証できます。

<?php
class User {
    public function getName(): string {
        return "User Name";
    }
}

// Userクラスのインスタンスしか受け取れない
function printUserName(User $user) {
    echo $user->getName();
}

$u = new User();
printUserName($u);
?>

インターフェースを指定すれば、そのインターフェースを実装したクラスであれば何でも受け取れるようになり、柔軟性の高い設計が可能になります。

厳密な型チェックを行う「strict_types」

PHPはデフォルトでは「弱い型付け」の言語です。

例えば、int 型を要求する関数に文字列の "100" を渡すと、PHPは親切心でこれを数値の 100 に変換して処理しようとします。
これは便利な反面、予期せぬバグの温床になります。

型の厳密さを強制したい場合は、ファイルの先頭で declare(strict_types=1); を宣言します。

declare(strict_types=1); の使い方

<?php
declare(strict_types=1); // 厳密な型チェックを有効化

function add(int $a, int $b): int {
    return $a + $b;
}

// 以下の呼び出しは Fatal Error (TypeError) になる
// add(10, "20"); 
?>

この宣言を行うと、型が完全に一致しない場合に自動変換を行わず、即座にエラーを出します。
例外として、 int から float への変換は許可される場合がありますが、逆は厳格にチェックされます。

大規模開発やライブラリ開発においては、この設定を有効にして堅牢性を高めるのがモダンなPHPのスタンダードです。

ただし、この宣言は「ファイル単位」で有効になる点に注意してください。
呼び出し元のファイルと呼び出し先のファイルで設定が異なると、挙動が直感的でなくなることがあります。

変数自体の型宣言はできる?

JavaやC#などの静的型付け言語では、ローカル変数を宣言する際に int $number = 10; のように型を指定します。

しかし、PHPではローカル変数に対して型宣言を行うことはできません

ローカル変数の型宣言について

PHPの変数(ローカル変数)は、代入される値によって動的に型が変わります。

<?php
$value = 10;      // ここではint型
$value = "hello"; // string型に変わる(エラーにならない)
?>

型宣言ができるのはあくまで「関数の引数」「関数の戻り値」「クラスのプロパティ」の3箇所です。

ローカル変数の型を保証したい場合は、is_int() などの関数でチェックするか、クラスのプロパティとして定義して型宣言を利用する設計にする必要があります。

PHPのスキルを活かして年収を上げる方法

以上、PHPの型宣言について解説してきました。

なお、PHPのスキルがある場合には、「転職して年収をアップさせる」「副業で稼ぐ」といった方法を検討するのがおすすめです。

PHPエンジニアの需要は非常に高く求人数・案件数も多いため、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。

なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。

今すぐ転職する気がなくとも、とりあえず転職エージェントに無料登録しておくだけで、スカウトが届いたり、思わぬ好待遇の求人情報が送られてきたりするというメリットがあります。

併せて、副業案件を獲得できるエージェントにも登録しておくと、空いている時間を活かして稼げるようなPHPの案件を探しやすくなります。

転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。