PHP 入門

PHP データタイプ

PHP において、スクリプトが処理する各データには特定のデータタイプが割り当てられています。これらのタイプはバリアブル(変数)が保持する値を分類し、PHP がデータをメモリに格納し、オペレーションを実行する方法に直接影響を与えます。データタイプの理解は、効率的でバグのない PHP コードを記述するための基盤です。なぜなら、算術計算、ストリングのコンカチネーション(結合)、ロジカル比較などのオペレーションの具体的な挙動を決定づけるからです。

PHP はダイナミックタイピング言語(動的型付け言語)です。つまり、バリアブルのデータタイプを明示的にデリクレア(宣言)する必要はありません。PHP はランタイム時に、代入された値に基づいて自動的にそのタイプを判定します。そうは言っても、システム内部では、PHP はこれらのタイプを厳密に区別しています。本章では、PHP の4つのスカラー(単一値)データタイプ、すなわちストリング(Strings)、インテジャー(Integers)、フロート(Floats)、ブーリアン(Booleans)にフォーカスして解説します。

1. ストリング (Strings)

ストリングは、テキストを表現するためのキャラクター(文字)のシーケンスです。PHP において、ストリングは必ずシングルクォート (') またはダブルクォート (") で囲む必要があります。どちらを選択するかによって、PHP がストリング内部の特殊キャラクターやバリアブルをパース(解析)する方法が直接影響を受けます。

1.1 シングルクォートストリング

シングルクォートで囲まれたストリングは、ほぼすべてのキャラクターをリテラル(見たままの文字)として扱います。認識される特殊キャラクターは、シングルクォート自身をエスケープするためのバックスラッシュ (\') と、バックスラッシュ自身をエスケープするためのバックスラッシュ (\\) のみです。シングルクォート内に記述されたバリアブル名がパースされたり、その値に置き換えられたりすることはありません。

<?php
$name = "Alice";
$message1 = 'こんにちは、$name!'; // $name は通常のテキストとして出力され、Alice には変換されません
$message2 = '今日はとてもいい天気です。It\'s a beautiful day.'; // シングルクォートをエスケープ
$message3 = 'C:\\Program Files\\App'; // ' や \ をエスケープする用途以外では、バックスラッシュは通常のテキスト記号として扱われます

echo $message1; // 出力:こんにちは、$name!
echo "\n";
echo $message2; // 出力:今日はとてもいい天気です。It's a beautiful day.
echo "\n";
echo $message3; // 出力:C:\Program Files\App
?>

シングルクォートストリングは、インタープリタが内部のバリアブルや複雑なエスケープシーケンスをスキャンする必要がないため、PHP にとって処理速度が速くなる傾向があります。テキスト内にバリアブルを展開する必要がない場合は、シングルクォートを使用するのがベストな選択です。

1.2 ダブルクォートストリング

ダブルクォートストリングはよりパワフルです。より多くのエスケープシーケンスをパースし、バリアブルのインターポレーション(変数展開)をサポートしているからです。PHP はダブルクォート内にダラーサイン ($) を見つけると、それを同名のバリアブルの値に置き換えようとします。

ダブルクォートストリングでよく使われるエスケープシーケンス:

  • \n: 改行
  • \r: キャリッジリターン
  • \t: 水平タブ (Tab)
  • \\: バックスラッシュ
  • \$: ダラーサイン
  • \": ダブルクォート
<?php
$city = "ニューヨーク";
$temp = 25;

$message4 = "ようこそ $city へ!今日の気温は $temp 度です。\n"; // バリアブルのインターポレーション
$message5 = "このストリングには \"ダブルクォート\" と改行が含まれています。\n"; // ダブルクォートと改行のエスケープ

echo $message4;
echo $message5;

// カーリーブレースを使用して複雑なバリアブル展開を行う(任意ですが、コードの可読性向上のため強く推奨されます)
$fruit = "リンゴ";
$count = 3;
$sentence = "私は {$count} 個の{$fruit}を持っています。"; // カーリーブレースによりバリアブル名の境界が明確になります
echo $sentence; // 出力:私は 3 個のリンゴを持っています。
echo "\n";

// ダブルクォート内で直接アレイ(配列)の要素にアクセスする
$user = ['first_name' => 'ボブ'];
echo "ユーザーの名前は {$user['first_name']} です。\n";
?>

ダブルクォートストリングは、ユーザーデータを組み込んだメッセージや特殊キャラクターを含むフォーマット済みテキストなど、ダイナミックな出力のビルドに非常に適しています。

2. インテジャー (Integers)

インテジャーは小数点以下の部分を持たない数値で、正の数、負の数、またはゼロをとることができます。PHP では、インテジャーは10進数(ベース10)、16進数(ベース16、0x から始まる)、8進数(ベース8、0o または 0 から始まる)、2進数(ベース2、0b から始まる)で表現できます。

インテジャーのサイズは実行されるプラットフォームに依存しますが、モダンなシステムでは通常64ビットであり、約 -9E18 から 9E18 のレンジを持ちます。インテジャーの演算結果がこのレンジをオーバーフローした場合、自動的にフロート(Float)にキャスト(変換)されます。

<?php
$decimalInt = 12345;      // 10進数
$negativeInt = -500;      // 負のインテジャー
$hexInt = 0xFF;           // 16進数(10進数の 255)
$octalInt = 0o123;        // 8進数(10進数の 83、モダンな PHP では '0o' プレフィックスを推奨しますが、'0' でも可)
$binaryInt = 0b101010;    // 2進数(10進数の 42)

echo "10進数:" . $decimalInt . "\n";
echo "負の数:" . $negativeInt . "\n";
echo "16進数:" . $hexInt . "\n";
echo "8進数:" . $octalInt . "\n";
echo "2進数:" . $binaryInt . "\n";

// インテジャーのオーバーフローによってフロートに変換される例
$largeNumber = 9223372036854775807; // 64ビットインテジャーの最大値
$overflow = $largeNumber + 1;
var_dump($overflow); // 出力は float(9.2233720368548E+18) となります
?>

インテジャーは通常、カウント、ID、年齢、数量など、小数点以下の数値を必要としないデータの処理に利用されます。

3. フロート (Floats)

フロート(「ダブル」または倍精度浮動小数点数とも呼ばれます)は、小数点を含む数値、または指数表記の数値を表します。価格、測定値、科学技術計算など、インテジャーよりも高いプレシジョン(精度)が要求される場合にフロートを使用します。

<?php
$price = 19.99;          // 10進数のフロート
$temperature = -3.5;     // 負のフロート
$largeFloat = 1.234e3;   // 指数表記 (1.234 * 10^3 = 1234.0)
$smallFloat = 5.67e-2;   // 指数表記 (5.67 * 10^-2 = 0.0567)

echo "価格:" . $price . "\n";
echo "気温:" . $temperature . "\n";
echo "大きなフロート:" . $largeFloat . "\n";
echo "小さなフロート:" . $smallFloat . "\n";

// 【重要なトラップ】フロートのプレシジョン問題:コンピュータの基礎的な格納メカニズムの都合上、フロート同士を直接比較すると問題が発生する可能性があります。
$a = 0.1 + 0.7;
$b = 0.8;
echo "0.1 + 0.7 = " . $a . "\n"; // 出力された見た目は 0.8 になります
var_dump($a == $b); // 出力:bool(false) - これは非常に一般的なトラップです。

// 正確な比較を行うためには、通常、極めて小さな許容誤差(トレランス/エプシロン)を使用するか、金額計算を処理する場合は優先的にインテジャーを使用します(例:「ドル」を「セント」に変換して計算する)。
?>

フロートは、ファイナンス系のアプリケーション(プレシジョン問題に細心の注意が必要)、科学的なモデリング、および小数部分に強く依存するあらゆる機能において不可欠です。

4. ブーリアン (Booleans)

ブーリアンは真偽値を表し、true(真)または false(偽)のいずれかのステータスしか持ちません。これらの値はケースインセンシティブ(大文字・小文字を区別しない)です。ブーリアンは if ステートメントやループなどのコントロールストラクチャーのベースとなり、プログラムは条件が満たされているかどうかに基づいてディシジョンを下します。

<?php
$isLoggedIn = true;     // バリアブルにブーリアンの true をセット
$isAdmin = FALSE;       // バリアブルにブーリアンの false をセット(大文字小文字は区別されません)
$hasPermission = (10 > 5); // 比較演算の結果、すなわち true がセットされます
$isGuest = (empty($_POST['username'])); // ファンクションがブーリアンをリターンする例

echo "ログイン済みですか? " . ($isLoggedIn ? "はい" : "いいえ") . "\n"; // ターナリオペレーター(三項演算子)を用いた出力
echo "管理者ですか? " . ($isAdmin ? "はい" : "いいえ") . "\n";
echo "権限はありますか? " . ($hasPermission ? "はい" : "いいえ") . "\n";

// ブーリアンへのキャスト:「Falsy(偽値)」の理解
// 以下の値は、ブーリアンに変換された際に FALSE として評価されます:
// - ブーリアンの FALSE 自身
// - インテジャーの 0 (ゼロ)
// - フロートの 0.0 (ゼロ)
// - 空のストリング "" およびストリングの "0"
// - 要素がゼロ個のアレイ (空のアレイ [])
// - 特殊タイプの NULL
// - 空のタグから作成された SimpleXML オブジェクト

$emptyString = "";
$zeroInt = 0;
$zeroFloat = 0.0;
$emptyArray = [];
$nullVar = null;

if ($emptyString) { echo "空のストリングは TRUE です\n"; } else { echo "空のストリングは FALSE です\n"; }
if ($zeroInt) { echo "数字の 0 は TRUE です\n"; } else { echo "数字の 0 は FALSE です\n"; }
if ($zeroFloat) { echo "フロートの 0.0 は TRUE です\n"; } else { echo "フロートの 0.0 は FALSE です\n"; }
if ($emptyArray) { echo "空のアレイは TRUE です\n"; } else { echo "空のアレイは FALSE です\n"; }
if ($nullVar) { echo "NULL は TRUE です\n"; } else { echo "NULL は FALSE です\n"; }

$nonEmptyString = "こんにちは";
if ($nonEmptyString) { echo "空ではないストリングは TRUE です\n"; } else { echo "空ではないストリングは FALSE です\n"; }
?>

ブーリアンは、ロジカルな条件判定、ステータスフラグ、そしてオペレーションがサクセスしたかフェイルしたかを示すための中核を担います。たとえば、あるファンクションは実行が成功した場合は true を、そうでない場合は false をリターンします。

5. 総合実践ケース

以下に紹介するケースは、これまでディスカッションしてきたデータタイプを組み合わせ、よくある実際のユースケースをデモンストレーションするものです。

5.1 Eコマースのオーダー詳細

シンプルなEコマースシステムを構築していると想定してください。プロダクト名、数量、価格、および商品に在庫があるかどうかのステータスを格納する必要があります。

<?php
// プロダクト情報
$productName = "ワイヤレスマウス";       // ストリング (String)
$quantity = 2;                  // インテジャー (Integer)
$unitPrice = 29.99;             // フロート (Float)
$isInStock = true;              // ブーリアン (Boolean)

// 小計の計算
$subtotal = $quantity * $unitPrice; // 演算結果はフロートになります

echo "プロダクト名:" . $productName . "\n";
echo "数量:" . $quantity . "\n";
echo "単価:$" . $unitPrice . "\n";
echo "在庫あり:" . ($isInStock ? "はい" : "いいえ") . "\n";
echo "小計金額:$" . $subtotal . "\n";

// ダブルクォートを使用したストリングのコンカチネーションの例
$orderSummary = "あなたは {$quantity} 個の {$productName} を注文しました。単価は $" . $unitPrice . " です。合計:$" . $subtotal . "。";
echo $orderSummary . "\n";
?>

このケースは、現実世界のマターを表現するために、異なるデータタイプがいかに自然に連携するかを示しています。productName はテキスト、quantity はインテジャー、unitPrice は小数を含み、isInStock は「はい/いいえ」の条件となっています。

5.2 ユーザー認証ステータス

ユーザーがWebサイトにログインする際、彼らの認証ステータスをトラッキングする必要があります。

<?php
$username = "john.doe"; // ストリング
$isAuthenticated = false; // ブーリアン - 初期ステータスは未認証とします

// 認証試行のシミュレート
$passwordAttempt = "password123";
$storedPasswordHash = "hashed_password_from_database"; // 実際にはハッシュ値の比較を行う必要があります

// シンプルにするため、基本的な条件に基づいて isAuthenticated をセットします
if ($username == "john.doe" && $passwordAttempt == "password123") {
    $isAuthenticated = true; // ユーザー認証サクセス
}

// 認証結果の表示
if ($isAuthenticated) {
    echo "ようこそ、" . $username . "!正常にログインしました。\n";
} else {
    echo $username . " の認証がフェイルしました。再試行してください。\n";
}

// 管理者フラグに関する別のブーリアンの例
$userLevel = "admin";
$isAdministrator = ($userLevel === "admin"); // ユーザーが管理者かどうかをチェックします
echo "管理者ですか? " . ($isAdministrator ? "はい" : "いいえ") . "\n";
?>