PHPで文字列を数値(整数・小数点数)に変換する方法を、実務経験30年のエンジニアが徹底解説します。intval(), floatval(), キャスト演算子の違い、型ジャグリング、厳密な型変換まで完全網羅。
1. なぜ文字列を数値に変換する必要があるのか
よくあるシーン
// フォーム入力値(常に文字列)
$age = $_POST['age']; // "25" (文字列)
// 計算に使いたい
$next_year = $age + 1; // "25" + 1 = 26 (自動変換されるが...)問題点:
- 意図しない型ジャグリング
- 予期しない動作
- セキュリティリスク
解決策:
明示的に型変換する
実務での使用例
1. API レスポンスの処理
// JSON から取得した値(文字列の場合がある)
$json = '{"price": "1980", "quantity": "5"}';
$data = json_decode($json, true);
$total = intval($data['price']) * intval($data['quantity']);
// 1980 * 5 = 99002. データベースから取得した値
// PDO で取得した値は文字列になることがある
$result = $db->query("SELECT price FROM products WHERE id = 1");
$row = $result->fetch();
$price = floatval($row['price']); // "1980.50" → 1980.53. 環境変数の処理
// .env ファイルの値は常に文字列
$max_upload = intval(getenv('MAX_UPLOAD_SIZE')); // "10" → 102. 整数への変換方法
2-1. intval() 関数(推奨)
$str = "123";
$num = intval($str);
var_dump($num); // int(123)特徴:
- ✅ 明示的で読みやすい
- ✅ 基数指定が可能
- ✅ エラーが起きにくい
基数指定の例:
// 2進数
$bin = "1010";
$num = intval($bin, 2); // 10
// 8進数
$oct = "12";
$num = intval($oct, 8); // 10
// 16進数
$hex = "A";
$num = intval($hex, 16); // 102-2. (int) キャスト演算子
$str = "456";
$num = (int)$str;
var_dump($num); // int(456)特徴:
- ✅ 高速
- ✅ シンプル
- ❌ 基数指定不可
別名:
$num = (int)$str;
$num = (integer)$str; // 同じ2-3. 実際の変換例
// 整数文字列
intval("123"); // 123
(int)"123"; // 123
// 小数点文字列(整数部分のみ)
intval("123.45"); // 123
(int)"123.45"; // 123
// 先頭に数字がある文字列
intval("123abc"); // 123 (PHP 8.0以降は Notice)
(int)"123abc"; // 123 (PHP 8.0以降は Notice)
// 先頭が数字でない文字列
intval("abc123"); // 0
(int)"abc123"; // 0
// 負の数
intval("-456"); // -456
(int)"-456"; // -456
// 空文字列
intval(""); // 0
(int)""; // 0
// null
intval(null); // 0
(int)null; // 0
// boolean
intval(true); // 1
intval(false); // 03. 浮動小数点数への変換方法
3-1. floatval() 関数(推奨)
$str = "123.45";
$num = floatval($str);
var_dump($num); // float(123.45)特徴:
- ✅ 明示的で読みやすい
- ✅ 小数点を保持
3-2. (float) キャスト演算子
$str = "678.90";
$num = (float)$str;
var_dump($num); // float(678.9)別名:
$num = (float)$str;
$num = (double)$str; // 同じ
$num = (real)$str; // 非推奨(PHP 7.4で削除予定だった)3-3. 実際の変換例
// 小数点文字列
floatval("123.45"); // 123.45
(float)"123.45"; // 123.45
// 整数文字列
floatval("123"); // 123.0
(float)"123"; // 123.0
// 科学的記数法
floatval("1.23e2"); // 123.0
(float)"1.23E-2"; // 0.0123
// カンマ区切り(注意!)
floatval("1,234.56"); // 1.0 (カンマで停止)
// 先頭に数字がある文字列
floatval("123.45abc"); // 123.45 (PHP 8.0以降は Notice)
// 負の数
floatval("-456.78"); // -456.78
// 空文字列
floatval(""); // 0.0
// INF(無限大)
floatval("INF"); // INF
floatval("-INF"); // -INF4. キャスト演算子 vs 変換関数
4-1. 機能比較表
| 項目 | intval() / floatval() | (int) / (float) |
|---|---|---|
| 読みやすさ | ⭐⭐⭐ 高い | ⭐⭐ 普通 |
| 速度 | ⭐⭐ 普通 | ⭐⭐⭐ 高速 |
| 基数指定 | ✅ 可能 (intval) | ❌ 不可 |
| 明示性 | ✅ 明確 | ⭐⭐ 普通 |
4-2. 使い分けの推奨
// ✅ 推奨: 関数(可読性重視)
$age = intval($_POST['age']);
$price = floatval($product['price']);
// ✅ 許容: キャスト(速度重視・短いコード)
for ($i = 0; $i < count($items); $i++) {
$total += (float)$items[$i]['price'];
}
// ✅ 基数指定が必要な場合は必ず関数
$binary = intval($input, 2); // 2進数変換4-3. パフォーマンステスト
// 100万回実行
$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$num = intval("123");
}
echo microtime(true) - $start; // 約 0.15秒
$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$num = (int)"123";
}
echo microtime(true) - $start; // 約 0.12秒5. 型ジャグリング(自動型変換)
5-1. PHPの自動型変換
// 文字列 + 数値 → 自動変換
$result = "10" + 5;
var_dump($result); // int(15)
// 文字列 * 文字列 → 両方とも変換
$result = "10" * "5";
var_dump($result); // int(50)
// 文字列 . 数値 → 数値が文字列に変換
$result = "価格: " . 100;
var_dump($result); // string(9) "価格: 100"5-2. 危険な自動変換
// ⚠️ 意図しない動作
$str = "10abc";
$result = $str + 5;
var_dump($result); // int(15) (PHP 8.0以降は Notice)
// ⚠️ 比較での問題
var_dump("10" == 10); // bool(true)
var_dump("10abc" == 10); // bool(true) (PHP 8.0以降は false)
// ✅ 厳密な比較を使う
var_dump("10" === 10); // bool(false)5-3. PHP 8.0以降の変更
PHP 7.4以前:
$str = "10abc";
$num = $str + 5; // 15 (警告なし)PHP 8.0以降:
$str = "10abc";
$num = $str + 5; // 15 (Notice: A non well formed numeric value encountered)推奨:
// 明示的に変換
$str = "10abc";
$num = intval($str) + 5; // 15 (安全)6. 厳密な型変換(strict_types)
6-1. strict_types宣言
<?php
declare(strict_types=1);
function add(int $a, int $b): int {
return $a + $b;
}
// ✅ OK
add(10, 5); // 15
// ❌ エラー
add("10", "5"); // Fatal error: Argument must be of type int, string given6-2. 実務での使い方
<?php
declare(strict_types=1);
class Calculator
{
public function multiply(int $a, int $b): int
{
return $a * $b;
}
}
$calc = new Calculator();
// 明示的に変換してから渡す
$input1 = intval($_POST['number1']);
$input2 = intval($_POST['number2']);
$result = $calc->multiply($input1, $input2);7. よくあるエラーと対処法
エラー1: “A non well formed numeric value encountered”
// PHP 8.0以降
$str = "123abc";
$num = intval($str); // Notice が出る対処法:
// 数値部分のみ抽出
$str = "123abc";
preg_match('/^-?\d+/', $str, $matches);
$num = isset($matches[0]) ? intval($matches[0]) : 0;
// 123エラー2: カンマ区切りの数値
// ❌ 間違い
$price = floatval("1,234.56"); // 1.0 (カンマで停止)
// ✅ 正しい
$price = floatval(str_replace(',', '', "1,234.56")); // 1234.56エラー3: 全角数字
// ❌ 変換できない
$str = "123";
$num = intval($str); // 0
// ✅ 半角に変換してから
$str = mb_convert_kana("123", "n"); // "123"
$num = intval($str); // 123エラー4: null や false の扱い
// null
intval(null); // 0
floatval(null); // 0.0
// false
intval(false); // 0
floatval(false);// 0.0
// 空文字列
intval(""); // 0
floatval(""); // 0.0対処法(nullチェック):
$value = $_POST['age'] ?? null;
if ($value !== null && $value !== '') {
$age = intval($value);
} else {
$age = 0; // デフォルト値
}8. 実務での使い分け
8-1. フォーム入力の処理
// ✅ 推奨
$age = intval($_POST['age'] ?? 0);
$price = floatval($_POST['price'] ?? 0.0);
// ✅ さらに厳密に
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT) ?: 0;
$price = filter_input(INPUT_POST, 'price', FILTER_VALIDATE_FLOAT) ?: 0.0;8-2. データベース操作
// ✅ プリペアドステートメント(型自動判定)
$stmt = $pdo->prepare("INSERT INTO products (name, price, quantity) VALUES (?, ?, ?)");
$stmt->execute([
$name,
floatval($price), // 明示的に変換
intval($quantity)
]);
// ✅ Eloquent ORM(Laravel)
Product::create([
'name' => $name,
'price' => floatval($price),
'quantity' => intval($quantity),
]);8-3. API レスポンス生成
// JSON エンコード前に型を確定
$response = [
'user_id' => intval($user->id),
'age' => intval($user->age),
'balance' => floatval($user->balance),
'is_active' => (bool)$user->is_active,
];
echo json_encode($response);9. パフォーマンス比較
9-1. ベンチマーク結果
// 100万回変換(PHP 8.2)
// intval()
$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$num = intval("123");
}
echo microtime(true) - $start; // 約 0.15秒
// (int)キャスト
$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$num = (int)"123";
}
echo microtime(true) - $start; // 約 0.12秒
// 型ジャグリング(+ 0)
$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$num = "123" + 0;
}
echo microtime(true) - $start; // 約 0.13秒結論: 実務レベルでは誤差
9-2. 推奨する選択基準
// 可読性重視(推奨)
$num = intval($str);
// 高速処理(ループ内など)
$num = (int)$str;
// 避けるべき(意図が不明瞭)
$num = $str + 0;10. チートシート(コピペ用)
10-1. 整数変換
// 基本
intval("123"); // 123
(int)"123"; // 123
// 小数点切り捨て
intval("123.45"); // 123
// 基数指定
intval("1010", 2); // 10 (2進数)
intval("FF", 16); // 255 (16進数)
// 負の数
intval("-456"); // -456
// エッジケース
intval(""); // 0
intval(null); // 0
intval("abc"); // 0
intval("123abc"); // 123 (Notice)10-2. 浮動小数点変換
// 基本
floatval("123.45"); // 123.45
(float)"123.45"; // 123.45
// 整数も変換可能
floatval("123"); // 123.0
// 科学的記数法
floatval("1.23e2"); // 123.0
// 負の数
floatval("-456.78"); // -456.78
// エッジケース
floatval(""); // 0.0
floatval(null); // 0.0
floatval("INF"); // INF10-3. 実務テンプレート
// フォーム入力
$age = intval($_POST['age'] ?? 0);
$price = floatval($_POST['price'] ?? 0.0);
// バリデーション付き
$age = filter_var($_POST['age'] ?? 0, FILTER_VALIDATE_INT) ?: 0;
$price = filter_var($_POST['price'] ?? 0, FILTER_VALIDATE_FLOAT) ?: 0.0;
// null安全
$value = $_POST['number'] ?? null;
$number = $value !== null ? intval($value) : null;
// カンマ区切り対応
$price = floatval(str_replace(',', '', "1,234.56")); // 1234.56
// 全角数字対応
$num = intval(mb_convert_kana("123", "n")); // 123まとめ
覚えておくべきポイント
✅ 基本の使い分け:
- 整数変換:
intval()または(int) - 小数変換:
floatval()または(float) - 可読性重視なら関数、速度重視ならキャスト
✅ 注意点:
- PHP 8.0以降は不正な数値文字列で Notice
- カンマ区切りは自動除去されない
- 全角数字は変換されない
✅ 実務での推奨:
- 明示的な変換を徹底
filter_var()でバリデーションstrict_typesで型安全性向上
開発経験から
型変換は一見単純ですが、自動型変換に頼ると予期しないバグの温床になります。
実際にあったトラブル例:
- フォーム入力 “123abc” が 123 に変換され、データ不整合
- カンマ区切りの価格 “1,234.56” が 1.0 になり、大損失
- null と 0 の区別がつかず、集計エラー
明示的な型変換と適切なバリデーションで、これらは100%防げます。
あなたにおすすめの記事
PHP基礎:
Laravel関連:

