PHPでデータの型チェックを行う際、値が整数かどうかを正確に判定する必要があることがよくあります。そんな時に重要な役割を果たすのがis_int()
関数です。この記事では、is_int()
関数の基本的な使い方から実践的な活用法、他の関数との違いまで詳しく解説していきます。
is_int関数とは?
is_int()
は、指定された変数が整数型(integer)かどうかを判定するPHPの組み込み関数です。変数の値ではなく、データ型を厳密にチェックするため、文字列の数値や浮動小数点数はfalse
を返します。
基本的な構文
is_int(mixed $value): bool
- 引数:
$value
– 判定したい値(任意の型) - 戻り値: 整数型の場合は
true
、それ以外の場合はfalse
- エイリアス:
is_integer()
、is_long()
も同じ機能
基本的な使用例
整数型の判定
<?php
// 整数型
var_dump(is_int(42)); // bool(true)
var_dump(is_int(-10)); // bool(true)
var_dump(is_int(0)); // bool(true)
// 浮動小数点数(整数値でも浮動小数点型)
var_dump(is_int(42.0)); // bool(false)
var_dump(is_int(10.5)); // bool(false)
// 文字列(数値文字列でも文字列型)
var_dump(is_int("42")); // bool(false)
var_dump(is_int("10")); // bool(false)
// その他の型
var_dump(is_int(true)); // bool(false)
var_dump(is_int(null)); // bool(false)
var_dump(is_int([])); // bool(false)
?>
型キャストとの比較
<?php
function demonstrateTypeCasting() {
$values = [42, 42.0, "42", "42.0", true, false, null];
echo "値\t\tis_int\t\t(int)値\t\tis_int((int)値)\n";
echo str_repeat("-", 60) . "\n";
foreach ($values as $value) {
$intCasted = (int)$value;
printf("%-10s\t%-10s\t%-10s\t%-10s\n",
var_export($value, true),
is_int($value) ? 'true' : 'false',
$intCasted,
is_int($intCasted) ? 'true' : 'false'
);
}
}
demonstrateTypeCasting();
?>
実践的な活用場面
1. フォーム入力値の検証
<?php
class FormValidator {
public static function validateAge($input) {
// まず数値文字列かチェック
if (!is_numeric($input)) {
return ['valid' => false, 'error' => '数値を入力してください'];
}
// 整数に変換
$age = (int)$input;
// 変換後の値が元の値と一致するか(小数点がないか)
if ((string)$age !== (string)$input) {
return ['valid' => false, 'error' => '整数を入力してください'];
}
// 範囲チェック
if ($age < 0 || $age > 150) {
return ['valid' => false, 'error' => '有効な年齢を入力してください(0-150)'];
}
return ['valid' => true, 'value' => $age];
}
public static function validateQuantity($input) {
if (is_int($input)) {
// 既に整数型の場合
$quantity = $input;
} elseif (is_numeric($input) && (int)$input == $input) {
// 数値文字列で整数値の場合
$quantity = (int)$input;
} else {
return ['valid' => false, 'error' => '整数の数量を入力してください'];
}
if ($quantity < 1) {
return ['valid' => false, 'error' => '1以上の数量を入力してください'];
}
return ['valid' => true, 'value' => $quantity];
}
}
// 使用例
$testInputs = [25, "25", "25.5", "abc", -5, 0, 1];
foreach ($testInputs as $input) {
$result = FormValidator::validateAge($input);
echo "入力: " . var_export($input, true) . " → ";
if ($result['valid']) {
echo "有効(値: {$result['value']})\n";
} else {
echo "無効({$result['error']})\n";
}
}
?>
2. 配列のインデックス検証
<?php
class ArrayHelper {
public static function getByIndex($array, $index) {
if (!is_array($array)) {
throw new InvalidArgumentException("第1引数は配列である必要があります");
}
if (!is_int($index)) {
throw new InvalidArgumentException("インデックスは整数である必要があります");
}
if ($index < 0) {
// 負のインデックスは末尾からの位置として扱う
$index = count($array) + $index;
}
if (!isset($array[$index])) {
throw new OutOfBoundsException("インデックス {$index} は範囲外です");
}
return $array[$index];
}
public static function safeSlice($array, $start, $length = null) {
if (!is_array($array)) {
return null;
}
if (!is_int($start)) {
return null;
}
if ($length !== null && !is_int($length)) {
return null;
}
return array_slice($array, $start, $length);
}
}
// 使用例
$fruits = ['apple', 'banana', 'orange', 'grape'];
try {
echo ArrayHelper::getByIndex($fruits, 1) . "\n"; // banana
echo ArrayHelper::getByIndex($fruits, -1) . "\n"; // grape
echo ArrayHelper::getByIndex($fruits, "1") . "\n"; // エラー
} catch (Exception $e) {
echo "エラー: " . $e->getMessage() . "\n";
}
?>
3. APIパラメータの検証
<?php
class APIValidator {
public static function validatePaginationParams($params) {
$defaults = ['page' => 1, 'limit' => 10];
$validated = [];
// ページ番号の検証
if (isset($params['page'])) {
if (is_int($params['page']) && $params['page'] > 0) {
$validated['page'] = $params['page'];
} elseif (is_numeric($params['page']) && (int)$params['page'] > 0 && (int)$params['page'] == $params['page']) {
$validated['page'] = (int)$params['page'];
} else {
throw new InvalidArgumentException("ページ番号は正の整数である必要があります");
}
} else {
$validated['page'] = $defaults['page'];
}
// リミットの検証
if (isset($params['limit'])) {
if (is_int($params['limit']) && $params['limit'] > 0 && $params['limit'] <= 100) {
$validated['limit'] = $params['limit'];
} elseif (is_numeric($params['limit'])) {
$limit = (int)$params['limit'];
if ($limit > 0 && $limit <= 100 && $limit == $params['limit']) {
$validated['limit'] = $limit;
} else {
throw new InvalidArgumentException("リミットは1-100の整数である必要があります");
}
} else {
throw new InvalidArgumentException("リミットは整数である必要があります");
}
} else {
$validated['limit'] = $defaults['limit'];
}
return $validated;
}
public static function validateSortParams($params) {
$validated = [];
if (isset($params['sort_by'])) {
if (!is_string($params['sort_by'])) {
throw new InvalidArgumentException("sort_byは文字列である必要があります");
}
$validated['sort_by'] = $params['sort_by'];
}
if (isset($params['sort_order'])) {
if (!in_array($params['sort_order'], ['asc', 'desc'])) {
throw new InvalidArgumentException("sort_orderは'asc'または'desc'である必要があります");
}
$validated['sort_order'] = $params['sort_order'];
}
return $validated;
}
}
// 使用例
$apiParams = [
'page' => "2",
'limit' => 20,
'sort_by' => 'created_at',
'sort_order' => 'desc'
];
try {
$paginationParams = APIValidator::validatePaginationParams($apiParams);
$sortParams = APIValidator::validateSortParams($apiParams);
echo "検証済みパラメータ:\n";
print_r(array_merge($paginationParams, $sortParams));
} catch (Exception $e) {
echo "バリデーションエラー: " . $e->getMessage() . "\n";
}
?>
他の型チェック関数との比較
is_int() vs is_numeric() vs ctype_digit()
<?php
function compareNumericFunctions() {
$testValues = [
42, // 整数
42.0, // 浮動小数点数
"42", // 数値文字列
"42.0", // 小数点付き数値文字列
"+42", // 符号付き数値文字列
"-42", // 負の数値文字列
"0x2A", // 16進数文字列
"1e2", // 指数表記
"042", // 先頭0付き数値文字列
" 42 ", // 空白付き数値文字列
"42abc", // 数値+文字列
true, // 真偽値
false, // 真偽値
null, // null
[] // 配列
];
echo "値\t\tis_int\t\tis_numeric\tctype_digit\n";
echo str_repeat("-", 60) . "\n";
foreach ($testValues as $value) {
printf("%-15s\t%-10s\t%-10s\t%-10s\n",
var_export($value, true),
is_int($value) ? 'true' : 'false',
is_numeric($value) ? 'true' : 'false',
ctype_digit((string)$value) ? 'true' : 'false'
);
}
}
compareNumericFunctions();
?>
型安全な整数判定関数
<?php
class IntegerValidator {
/**
* 厳密な整数判定(型チェック)
*/
public static function isStrictInteger($value): bool {
return is_int($value);
}
/**
* 値が整数として扱えるかチェック
*/
public static function isIntegerValue($value): bool {
if (is_int($value)) {
return true;
}
if (is_float($value)) {
return $value == (int)$value && !is_infinite($value) && !is_nan($value);
}
if (is_string($value)) {
return is_numeric($value) && (int)$value == $value;
}
return false;
}
/**
* 正の整数判定
*/
public static function isPositiveInteger($value): bool {
return is_int($value) && $value > 0;
}
/**
* 非負整数判定
*/
public static function isNonNegativeInteger($value): bool {
return is_int($value) && $value >= 0;
}
/**
* 範囲内の整数判定
*/
public static function isIntegerInRange($value, $min, $max): bool {
return is_int($value) && $value >= $min && $value <= $max;
}
}
// 使用例とテスト
$testValues = [42, 42.0, "42", -5, 0, 3.14, "abc"];
foreach ($testValues as $value) {
echo "値: " . var_export($value, true) . "\n";
echo " 厳密整数: " . (IntegerValidator::isStrictInteger($value) ? 'Yes' : 'No') . "\n";
echo " 整数値: " . (IntegerValidator::isIntegerValue($value) ? 'Yes' : 'No') . "\n";
echo " 正の整数: " . (IntegerValidator::isPositiveInteger($value) ? 'Yes' : 'No') . "\n";
echo " 非負整数: " . (IntegerValidator::isNonNegativeInteger($value) ? 'Yes' : 'No') . "\n";
echo " 範囲内(1-100): " . (IntegerValidator::isIntegerInRange($value, 1, 100) ? 'Yes' : 'No') . "\n";
echo "\n";
}
?>
データベースとの連携
安全なクエリ構築
<?php
class DatabaseHelper {
private $pdo;
public function __construct($pdo) {
$this->pdo = $pdo;
}
public function getUserById($userId) {
if (!is_int($userId)) {
throw new InvalidArgumentException("ユーザーIDは整数である必要があります");
}
if ($userId <= 0) {
throw new InvalidArgumentException("ユーザーIDは正の整数である必要があります");
}
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$userId]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
public function getUsersWithPagination($page, $limit) {
if (!is_int($page) || $page < 1) {
throw new InvalidArgumentException("ページは正の整数である必要があります");
}
if (!is_int($limit) || $limit < 1 || $limit > 100) {
throw new InvalidArgumentException("リミットは1-100の整数である必要があります");
}
$offset = ($page - 1) * $limit;
$stmt = $this->pdo->prepare("SELECT * FROM users LIMIT ? OFFSET ?");
$stmt->execute([$limit, $offset]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function updateUserStatus($userId, $status) {
if (!is_int($userId) || $userId <= 0) {
throw new InvalidArgumentException("無効なユーザーIDです");
}
if (!is_int($status) || !in_array($status, [0, 1, 2])) {
throw new InvalidArgumentException("ステータスは0、1、2のいずれかである必要があります");
}
$stmt = $this->pdo->prepare("UPDATE users SET status = ? WHERE id = ?");
return $stmt->execute([$status, $userId]);
}
}
// 使用例(PDO接続は省略)
try {
// $dbHelper = new DatabaseHelper($pdo);
// $user = $dbHelper->getUserById(123);
// $users = $dbHelper->getUsersWithPagination(1, 10);
// $updated = $dbHelper->updateUserStatus(123, 1);
} catch (Exception $e) {
echo "データベースエラー: " . $e->getMessage() . "\n";
}
?>
配列処理での活用
配列内の整数フィルタリング
<?php
class ArrayIntegerProcessor {
/**
* 配列から整数のみを抽出
*/
public static function extractIntegers($array): array {
return array_filter($array, 'is_int');
}
/**
* 配列から正の整数のみを抽出
*/
public static function extractPositiveIntegers($array): array {
return array_filter($array, function($value) {
return is_int($value) && $value > 0;
});
}
/**
* 配列内の整数の統計情報を取得
*/
public static function getIntegerStats($array): array {
$integers = self::extractIntegers($array);
if (empty($integers)) {
return ['count' => 0];
}
return [
'count' => count($integers),
'sum' => array_sum($integers),
'min' => min($integers),
'max' => max($integers),
'average' => array_sum($integers) / count($integers)
];
}
/**
* 配列内の値を整数に変換可能なものだけ変換
*/
public static function convertToIntegers($array): array {
$result = [];
foreach ($array as $key => $value) {
if (is_int($value)) {
$result[$key] = $value;
} elseif (is_numeric($value) && (int)$value == $value) {
$result[$key] = (int)$value;
}
// 変換できない値は除外
}
return $result;
}
}
// 使用例
$mixedArray = [1, 2.5, "3", "4.5", true, null, 5, "abc", 6.0, "7"];
echo "元の配列:\n";
print_r($mixedArray);
echo "\n整数のみ:\n";
print_r(ArrayIntegerProcessor::extractIntegers($mixedArray));
echo "\n正の整数のみ:\n";
print_r(ArrayIntegerProcessor::extractPositiveIntegers($mixedArray));
echo "\n統計情報:\n";
print_r(ArrayIntegerProcessor::getIntegerStats($mixedArray));
echo "\n整数変換:\n";
print_r(ArrayIntegerProcessor::convertToIntegers($mixedArray));
?>
パフォーマンス最適化
高速な整数判定
<?php
class PerformanceComparison {
public static function benchmarkIntegerCheck($iterations = 1000000) {
$testValues = [42, 42.0, "42", true, null];
// is_int()のベンチマーク
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
foreach ($testValues as $value) {
is_int($value);
}
}
$isIntTime = microtime(true) - $start;
// gettype()のベンチマーク
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
foreach ($testValues as $value) {
gettype($value) === 'integer';
}
}
$getTypeTime = microtime(true) - $start;
// filter_var()のベンチマーク
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
foreach ($testValues as $value) {
filter_var($value, FILTER_VALIDATE_INT) !== false;
}
}
$filterVarTime = microtime(true) - $start;
echo "パフォーマンス比較 ({$iterations}回実行):\n";
printf("is_int(): %.4f秒\n", $isIntTime);
printf("gettype(): %.4f秒\n", $getTypeTime);
printf("filter_var(): %.4f秒\n", $filterVarTime);
}
public static function optimizedIntegerFilter($array) {
// 大量データの場合は配列関数を使用
return array_filter($array, 'is_int');
}
}
// ベンチマークの実行(実際の実行では時間がかかります)
// PerformanceComparison::benchmarkIntegerCheck(100000);
?>
エラーハンドリングとデバッグ
デバッグ用の詳細な型情報表示
<?php
class TypeDebugger {
public static function analyzeValue($value, $varName = 'value') {
echo "=== {$varName} の型分析 ===\n";
echo "値: " . var_export($value, true) . "\n";
echo "型: " . gettype($value) . "\n";
// 各種判定結果
echo "is_int(): " . (is_int($value) ? 'true' : 'false') . "\n";
echo "is_numeric(): " . (is_numeric($value) ? 'true' : 'false') . "\n";
echo "is_string(): " . (is_string($value) ? 'true' : 'false') . "\n";
echo "is_float(): " . (is_float($value) ? 'true' : 'false') . "\n";
// 変換結果
if (is_numeric($value)) {
echo "(int)変換: " . (int)$value . "\n";
echo "(float)変換: " . (float)$value . "\n";
echo "変換後一致: " . ((int)$value == $value ? 'true' : 'false') . "\n";
}
echo "\n";
}
public static function debugFormInput($input) {
echo "フォーム入力のデバッグ:\n";
foreach ($input as $key => $value) {
echo "フィールド: {$key}\n";
self::analyzeValue($value, $key);
// 整数として扱えるかの判定
if (is_int($value)) {
echo "→ 既に整数型です\n";
} elseif (is_numeric($value) && (int)$value == $value) {
echo "→ 整数に変換可能です\n";
} else {
echo "→ 整数として扱えません\n";
}
echo str_repeat("-", 30) . "\n";
}
}
}
// 使用例
$formData = [
'user_id' => "123",
'age' => "25",
'price' => "19.99",
'quantity' => "5",
'name' => "John Doe"
];
TypeDebugger::debugFormInput($formData);
?>
まとめ
is_int()
関数は、PHPで整数型の厳密な判定を行う重要な関数です。主な特徴と活用場面をまとめると:
主な特徴
- 厳密な型チェック: 値ではなく型を判定
- 高速な処理: 単純な型チェックのため高速
- エイリアス:
is_integer()
、is_long()
も利用可能
主な活用場面
- フォーム入力の検証: ユーザー入力の型安全性確保
- API パラメータの検証: 整数パラメータの厳密チェック
- 配列インデックス: 配列アクセスの安全性確保
- データベース操作: SQLインジェクション対策
- 配列処理: 整数値のフィルタリングと処理
注意点
is_int("123")
はfalse
(文字列のため)is_int(123.0)
はfalse
(浮動小数点数のため)- 値の判定には
is_numeric()
や独自の検証関数を併用
適切に使用することで、型安全で堅牢なPHPアプリケーションを構築できます。特にユーザー入力やAPIパラメータの検証では、is_int()
を活用して確実な型チェックを行いましょう。