PHPは動的型付け言語なのか

採用はこちら

PHPは、基本的に動的型付け言語です。

動的型付け言語とは、変数を使うときにあらかじめ型を指定する必要がなく、代入された値によって実行時に型が決まる言語のことです。

たとえば、PHPでは次のように変数を使えます。

$name = "山田";
$age = 30;
$price = 1200.5;
$is_member = true;

この場合、$nameは文字列、$ageは整数、$priceは浮動小数点数、$is_memberは真偽値として扱われます。

しかし、変数を宣言する時点で「この変数は文字列です」「この変数は整数です」と明示する必要はありません。

また、PHPでは同じ変数に別の型の値を代入することもできます。

$value = 100;      // 整数
$value = "100";    // 文字列
$value = true;     // 真偽値

このように、PHPでは変数そのものに固定された型があるというより、その時点で代入されている値によって型が判断されるのが特徴です。

そのため、PHPはPython、JavaScript、Rubyなどと同じく、動的型付け言語に分類されます。

目次

PHPは型をまったく使わない言語ではない

PHPは動的型付け言語ですが、型をまったく使わない言語ではありません

現在のPHPでは、関数の引数、戻り値、クラスのプロパティなどに型を指定できます。

たとえば、関数の引数と戻り値に型を指定する場合は、次のように書きます。

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

この例では、$nameには文字列を受け取り、戻り値も文字列で返すことを示しています。

また、クラスのプロパティにも型を指定できます。

class User
{
    public string $name;
    public int $age;
}

この場合、$nameには文字列、$ageには整数を入れる設計であることが明確になります。

つまりPHPは、動的型付けを基本としながら、必要に応じて型宣言も使える言語です。

「PHPは動的型付けだから型を意識しなくてよい」というわけではありません。

通常のローカル変数には型宣言を書かない

PHPでは、関数の引数や戻り値、クラスのプロパティなどには型を指定できます。

一方で、通常のローカル変数に対して、次のような型宣言を書くことはできません。

string $name = "山田";

これはPHPの通常の変数宣言としては不正です。

PHPで一般的に書くのは、次のような形です。

$name = "山田";

このように、PHPでは通常の変数に型を明示して宣言するのではなく、代入された値によって型が判断されます。

そのため、PHPの型宣言について説明するときは、通常の変数そのものに型を付けるのではなく、主に関数の引数・戻り値・クラスのプロパティなどに型を付けると理解しておくとよいでしょう。

動的型付けと静的型付けの違い

動的型付けと対になる考え方として、静的型付けがあります。

静的型付け言語では、変数や関数の型をあらかじめ決めておくことが一般的です。

たとえばJavaでは、次のように変数の型を明示します。

int age = 30;
String name = "山田";

この場合、ageには整数、nameには文字列を入れる前提になります。

途中でageに文字列を代入しようとすると、型が合わないためエラーになります。

一方、PHPでは次のように書けます。

$age = 30;
$age = "三十歳";

最初は整数を代入し、あとから文字列を代入することもできます。

この柔軟さが、PHPの動的型付けらしい特徴です。

ただし、現在のPHPでは型宣言を使えるため、必要な部分では型の制約を設けることもできます。

function calculateTotal(int $price, int $quantity): int
{
    return $price * $quantity;
}

このように書けば、$price$quantityには整数を受け取り、戻り値も整数にするという意図が明確になります。

PHPは静的型付け言語ではありませんが、型宣言を使うことで、コードの読みやすさや安全性を高めることができます。

PHPでは自動的な型変換が行われることがある

PHPでは、文脈に応じて自動的に型変換が行われることがあります。

この性質から、PHPは「弱い型付け言語」と呼ばれることもあります。

たとえば、次のコードを見てください。

$result = "10" + 5;
echo $result;

この場合、文字列の"10"が数値として解釈され、結果は15になります。

これはPHPが、計算の文脈では文字列を数値に変換して処理するためです。

このような自動変換は便利な一方で、意図しない結果につながることもあります。

特に注意したいのが、比較演算です。

var_dump(0 == "0");   // true
var_dump(0 == false); // true

==は緩やかな比較です。

値を比較するときに、PHPが型を変換したうえで比較します。

一方、===を使うと、値だけでなく型も比較します。

var_dump(0 === "0");   // false
var_dump(0 === false); // false

そのため、PHPでは意図しない型変換によるバグを避けるために、特別な理由がなければ===を使うと安全です。

PHPの型宣言で指定できるもの

PHPでは、さまざまな型を指定できます。

代表的な型には、次のようなものがあります。

function sample(
    string $name,
    int $age,
    float $height,
    bool $is_member,
    array $items
): void {
    // 処理
}

それぞれの意味は次の通りです。

意味
string文字列
int整数
float浮動小数点数
bool真偽値
array配列
void戻り値がないこと

また、複数の型を許可するUnion型も使えます。

function displayId(int|string $id): void
{
    echo $id;
}

この例では、$idには整数または文字列を渡せます。

nullを許可したい場合は、次のように書きます。

function findUser(?int $id): ?string
{
    if ($id === null) {
        return null;
    }

    return "ユーザー名";
}

?intは、intまたはnullを許可するという意味です。

同じように、?stringstringまたはnullを許可します。

このように、PHPは動的型付け言語でありながら、型宣言を使うことで値の種類を明確にできます。

型宣言をしても自動変換される場合がある

PHPでは型宣言を付けていても、設定によっては自動的に型変換される場合があります。

たとえば、次のコードを見てください。

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

echo add("10", 5);

このコードでは、add()関数の引数にintが指定されています。

しかし、strict_types=1を指定していない場合、文字列の"10"が整数の10として扱われ、処理されることがあります。

つまり、型宣言があるからといって、常にすべての型違いが即座にエラーになるわけではありません。

PHPは標準状態では、スカラー型に対して自動的な型変換を行うことがあります。

この点は、PHPの型システムを理解するうえで重要です。

strict_typesを使うと型チェックを厳しくできる

PHPでは、ファイルの先頭にdeclare(strict_types=1);を書くことで、型チェックをより厳しくできます。

<?php
declare(strict_types=1);

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

echo add("10", 5);

この場合、add()関数は整数を受け取るように指定されています。

しかし、呼び出し時に文字列の"10"を渡しているため、TypeErrorになります。

strict_types=1を使うと、intfloatstringboolなどのスカラー型に対する自動変換を抑えられます。

ただし、strict_types=1はPHP全体を完全な静的型付け言語に変えるものではありません。

あくまで、関数呼び出し時などにおけるスカラー型の自動変換を抑えるための仕組みです。

また、strict_types=1はファイル単位で指定します。

特に関数の引数に対する厳密な型チェックは、関数を定義したファイルではなく、関数を呼び出す側のファイルの設定に影響されます。

たとえば、関数を定義するファイルが次のようになっていたとします。

<?php
// functions.php

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

そして、呼び出し側のファイルで次のように書きます。

<?php
declare(strict_types=1);

require 'functions.php';

echo add("10", 5);

この場合、呼び出し側にdeclare(strict_types=1);があるため、"10"は整数に自動変換されず、TypeErrorになります。

一方で、呼び出し側にstrict_types=1がない場合は、"10"が整数に変換されて処理される可能性があります。

PHPが動的型付けであるメリット

PHPが動的型付けであることには、いくつかのメリットがあります。

まず、コードを素早く書きやすい点です。

変数を使うたびに型を細かく指定する必要がないため、短い処理や小規模なスクリプトを手軽に書けます。

$message = "完了しました";
$count = 10;
$total = $count * 120;

また、Web開発ではフォーム入力、URLパラメータ、JSON、データベースの値など、外部から受け取るデータを扱う場面が多くあります。

このようなデータは、最初から厳密な型で扱えるとは限りません。

PHPの動的型付けは、こうしたデータを柔軟に扱いやすいという利点があります。

PHPが動的型付けであるデメリット

一方で、動的型付けには注意点もあります。

特に気をつけたいのは、意図しない型変換によるバグです。

たとえば、フォームから送信された値は、見た目が数値でも文字列として扱われることがあります。

$price = $_POST['price']; // "1000" のような文字列

この値を数値として使いたい場合は、バリデーションや型変換を行う必要があります。

$price = (int) $_POST['price'];

ただし、単純に(int)で変換するだけでは、不正な入力を見落とす可能性もあります。

実務では、filter_input()などを使って検証する方法もあります。

$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);

if ($age === false || $age === null) {
    echo '年齢を正しく入力してください';
}

このように、外部から受け取る値はそのまま信用せず、必要に応じて検証することが重要です。

また、比較演算にも注意が必要です。

if ($value == false) {
    // 0、"0"、空文字、null などが該当する可能性がある
}

==は緩やかな比較なので、型変換によって想定外の値が条件に一致することがあります。

より厳密に判定したい場合は、===を使います。

if ($value === false) {
    // booleanのfalseだけを判定
}

このように、PHPでは型の柔軟さが便利である一方、型のあいまいさによるバグに注意する必要があります。

実務でPHPを書くときの考え方

実務でPHPを書く場合は、PHPは動的型付け言語だが、型を意識して書くことが大切です。

特に、次のような書き方を意識すると安全です。

<?php
declare(strict_types=1);

function calculateTotal(int $price, int $quantity): int
{
    return $price * $quantity;
}

関数の引数と戻り値に型を指定することで、何を受け取り、何を返す関数なのかがわかりやすくなります。

また、条件分岐ではできるだけ厳密比較を使うと、意図しない型変換を防ぎやすくなります。

if ($status === 'published') {
    echo '公開中です';
}

さらに、フォーム入力や外部APIから受け取った値は、そのまま使うのではなく、バリデーションを行うことが重要です。

$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);

if ($id === false || $id === null) {
    echo 'IDが正しくありません';
}

このように、PHPの柔軟さを活かしつつ、型のあいまいさを減らすことで、読みやすく安全なコードを書きやすくなります。

静的解析ツールを使うとさらに安全になる

PHPは動的型付け言語ですが、PHPStanやPsalmのような静的解析ツールを使うことで、型に関する問題を事前に見つけやすくなります。

通常、PHPの型エラーは実行時に発見されます。

しかし、静的解析ツールを使うと、コードを実行する前に「この関数には文字列ではなく整数を渡すべき」「この戻り値は想定と違う可能性がある」といった問題を検出できます。

そのため、現在のPHP開発では、次のような組み合わせが有効です。

  • 型宣言を使う
  • strict_types=1を使う
  • ===で厳密比較する
  • 外部入力をバリデーションする
  • 静的解析ツールを使う

これらを取り入れることで、PHPの動的な柔軟性を保ちながら、型に関するミスを減らせます。

PHPは動的型付けだが、型を意識した開発ができる

PHPは、変数の型をあらかじめ固定しない動的型付け言語です。

変数には、代入された値に応じて整数、文字列、真偽値、配列などの型が決まります。

一方で、現在のPHPでは関数の引数、戻り値、クラスのプロパティなどに型を指定できます。

そのため、PHPは「型を使わない言語」ではなく、動的型付けを基本としながら、必要に応じて型を明示できる言語です。

また、PHPには自動的な型変換があるため、計算や比較の場面では注意が必要です。

特に==による緩やかな比較では、想定外の結果になることがあります。

そのため、実務では===による厳密比較や、入力値のバリデーションを意識することが大切です。

まとめ

PHPは、基本的に動的型付け言語です。

変数を宣言するときに型を指定する必要はなく、代入された値によって実行時に型が判断されます。

同じ変数に、整数、文字列、真偽値など異なる型の値を代入することもできます。

ただし、現在のPHPでは、関数の引数、戻り値、クラスのプロパティなどに型宣言を付けられます。

そのため、PHPは動的型付けを基本としつつ、必要に応じて型を明示できる柔軟な言語です。

また、PHPでは文脈によって自動的な型変換が行われることがあります。

この仕組みは便利ですが、意図しない比較や計算につながることもあります。

そのため、実務ではstrict_types=1、型宣言、===による厳密比較、入力値のバリデーションなどを組み合わせるとよいでしょう。

結論として、PHPは動的型付け言語でありながら、型を意識した安全な開発もできる言語です。

以上、PHPは動的型付け言語なのかについてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次