あっぽログ
← 記事一覧に戻る

PHPの型宣言を完全理解する:スカラー型・戻り値・Union型・nullableを使いこなす

はじめに

PHPはもともと動的型付け言語であり、変数の型を意識せずに書けることが魅力でした。しかし規模が大きくなるにつれ、「引数に何を渡せばいいのかわからない」「関数が何を返すのか不明」といった問題が起きやすくなります。

PHP 7以降に強化された**型宣言(Type Declaration)**を使うことで、こうした問題を事前に防ぎ、コードの可読性と安全性を高めることができます。この記事では型宣言の基本から実践的な使い方まで、順を追って解説します。


スカラー型の宣言

PHP 7.0から、引数と戻り値にスカラー型(基本的な型)を指定できるようになりました。

<?php

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

echo add(3, 5);   // 8
echo add(3.7, 5); // 8(暗黙の型変換が行われる)

指定できる主なスカラー型は次のとおりです。

説明
int整数
float浮動小数点数
string文字列
bool真偽値

strict_typesで厳格モードに切り替える

デフォルトでは、PHPは型を自動的に変換(キャスト)します。たとえば int を期待する関数に "3" (文字列)を渡しても動作します。これを防ぐには、ファイルの先頭で declare(strict_types=1) を宣言します。

<?php
declare(strict_types=1);

function multiply(int $a, int $b): int
{
    return $a * $b;
}

echo multiply(3, 4);     // 12
echo multiply("3", 4);   // TypeError が発生!

厳格モードを有効にすると、型が一致しない場合は TypeError がスローされます。チーム開発やライブラリ作成では、ファイルごとに strict_types=1 を付けることを強くおすすめします。


戻り値の型宣言

関数が何を返すかを明示するには、引数リストの後ろにコロン : で型を指定します。

<?php
declare(strict_types=1);

function greet(string $name): string
{
    return "こんにちは、{$name}さん!";
}

echo greet("太郎"); // こんにちは、太郎さん!

戻り値がない場合は void を使います。

function logMessage(string $message): void
{
    echo "[LOG] " . $message . PHP_EOL;
    // return は書けない(return; だけはOK)
}

nullable型:nullを許容する

引数や戻り値に null を許容したい場合は、型名の前に ? を付けます。

<?php
declare(strict_types=1);

function findUser(int $id): ?string
{
    $users = [1 => "Alice", 2 => "Bob"];
    return $users[$id] ?? null; // 存在しなければnullを返す
}

var_dump(findUser(1)); // string(5) "Alice"
var_dump(findUser(9)); // NULL

これにより「値があればその型、なければ null」という実態に即した表現が可能になります。


Union型:複数の型を受け付ける(PHP 8.0以降)

PHP 8.0では Union型 が導入され、| で複数の型を指定できるようになりました。

<?php
declare(strict_types=1);

function formatInput(int|string $value): string
{
    if (is_int($value)) {
        return "整数: {$value}";
    }
    return "文字列: {$value}";
}

echo formatInput(42);      // 整数: 42
echo formatInput("hello"); // 文字列: hello

null も Union型に含めることができます。?stringstring|null と同等です。

function process(int|float|null $value): string
{
    if ($value === null) return "値なし";
    return (string)($value * 2);
}

クラスやインターフェースを型として使う

スカラー型だけでなく、クラスやインターフェースも型として指定できます。依存注入(DI)パターンでよく使われます。

<?php
declare(strict_types=1);

interface LoggerInterface
{
    public function log(string $message): void;
}

class ConsoleLogger implements LoggerInterface
{
    public function log(string $message): void
    {
        echo "[Console] " . $message . PHP_EOL;
    }
}

class App
{
    public function __construct(private LoggerInterface $logger) {}

    public function run(): void
    {
        $this->logger->log("アプリを起動しました");
    }
}

$app = new App(new ConsoleLogger());
$app->run(); // [Console] アプリを起動しました

インターフェースを型にすることで、具体的な実装に依存しない柔軟なコードが書けます。


まとめ

PHPの型宣言を整理すると、次のようになります。

機能書き方導入バージョン
スカラー型(引数)function f(int $a)PHP 7.0
戻り値型function f(): stringPHP 7.0
nullable型function f(?string $a)PHP 7.1
void型function f(): voidPHP 7.1
Union型function f(int|string $a)PHP 8.0
厳格モードdeclare(strict_types=1)PHP 7.0

型宣言を積極的に活用することで、バグの早期発見・IDEによる補完の向上・コードの自己文書化が実現できます。最初は慣れが必要ですが、strict_types=1 と戻り値型の宣言から始めるだけでも大きな効果があります。ぜひ日常のPHP開発に取り入れてみてください。

← 記事一覧に戻る