こんにちは!今回は、PHPの標準関数であるsizeof()について詳しく解説していきます。配列の要素数を取得する関数で、実はcount()のエイリアスです!
sizeof関数とは?
sizeof()関数は、配列またはオブジェクトの要素数を数える関数です。
count()関数の完全なエイリアス(別名)で、まったく同じ動作をします。配列の長さやサイズを知りたいときに使用します!
基本的な構文
sizeof(Countable|array $value, int $mode = COUNT_NORMAL): int
- $value: 要素を数える配列またはオブジェクト
- $mode: カウントモード(
COUNT_NORMALまたはCOUNT_RECURSIVE) - 戻り値: 要素の数
count()との関係
// sizeof()とcount()は完全に同じ
$array = [1, 2, 3, 4, 5];
echo sizeof($array); // 5
echo count($array); // 5
// どちらを使っても同じ結果
var_dump(sizeof($array) === count($array)); // true
基本的な使用例
単純な配列
// 数値配列
$numbers = [1, 2, 3, 4, 5];
echo sizeof($numbers); // 5
// 文字列配列
$fruits = ['apple', 'banana', 'orange'];
echo sizeof($fruits); // 3
// 空配列
$empty = [];
echo sizeof($empty); // 0
連想配列
// 連想配列
$person = [
'name' => 'John',
'age' => 30,
'city' => 'Tokyo'
];
echo sizeof($person); // 3
多次元配列(通常モード)
// 多次元配列
$data = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// 通常モード(デフォルト)
echo sizeof($data); // 3(最上位の要素数のみ)
echo sizeof($data, COUNT_NORMAL); // 3
多次元配列(再帰モード)
// 再帰モード
$data = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// 再帰的にカウント
echo sizeof($data, COUNT_RECURSIVE); // 12(3 + 9)
// 内訳:
// - トップレベルの配列: 3要素
// - 各サブ配列: 3要素 × 3 = 9要素
// 合計: 3 + 9 = 12
オブジェクトのカウント
// Countableインターフェースを実装したクラス
class MyCollection implements Countable {
private $items = [];
public function add($item) {
$this->items[] = $item;
}
public function count(): int {
return count($this->items);
}
}
$collection = new MyCollection();
$collection->add('item1');
$collection->add('item2');
$collection->add('item3');
echo sizeof($collection); // 3
実践的な使用例
例1: 配列サイズチェッカー
class ArraySizeChecker {
/**
* 配列が空かチェック
*/
public static function isEmpty($array) {
return sizeof($array) === 0;
}
/**
* 配列に要素があるかチェック
*/
public static function hasElements($array) {
return sizeof($array) > 0;
}
/**
* 配列のサイズを取得
*/
public static function getSize($array) {
return sizeof($array);
}
/**
* 配列のサイズを比較
*/
public static function compare($array1, $array2) {
$size1 = sizeof($array1);
$size2 = sizeof($array2);
if ($size1 > $size2) {
return 1;
} elseif ($size1 < $size2) {
return -1;
} else {
return 0;
}
}
/**
* 最小・最大サイズをチェック
*/
public static function validateSize($array, $min = null, $max = null) {
$size = sizeof($array);
$errors = [];
if ($min !== null && $size < $min) {
$errors[] = "最小{$min}要素必要です(現在{$size}要素)";
}
if ($max !== null && $size > $max) {
$errors[] = "最大{$max}要素まで(現在{$size}要素)";
}
return [
'valid' => empty($errors),
'size' => $size,
'errors' => $errors
];
}
/**
* 全要素数を再帰的にカウント
*/
public static function getTotalElements($array) {
return sizeof($array, COUNT_RECURSIVE);
}
/**
* 配列の深さを取得
*/
public static function getDepth($array) {
if (!is_array($array)) {
return 0;
}
$maxDepth = 1;
foreach ($array as $value) {
if (is_array($value)) {
$depth = 1 + self::getDepth($value);
$maxDepth = max($maxDepth, $depth);
}
}
return $maxDepth;
}
}
// 使用例
echo "=== 配列サイズチェッカー ===\n";
$data = [1, 2, 3, 4, 5];
echo "空かどうか: " . (ArraySizeChecker::isEmpty($data) ? 'Yes' : 'No') . "\n";
echo "要素あり: " . (ArraySizeChecker::hasElements($data) ? 'Yes' : 'No') . "\n";
echo "サイズ: " . ArraySizeChecker::getSize($data) . "\n";
// サイズ検証
echo "\n=== サイズ検証 ===\n";
$validation = ArraySizeChecker::validateSize($data, 3, 10);
echo "検証結果: " . ($validation['valid'] ? 'OK' : 'NG') . "\n";
echo "サイズ: {$validation['size']}\n";
if (!$validation['valid']) {
foreach ($validation['errors'] as $error) {
echo " - {$error}\n";
}
}
// 多次元配列
echo "\n=== 多次元配列 ===\n";
$nested = [
[1, 2, [3, 4]],
[5, 6],
[7, 8, 9]
];
echo "トップレベル要素数: " . sizeof($nested) . "\n";
echo "全要素数: " . ArraySizeChecker::getTotalElements($nested) . "\n";
echo "配列の深さ: " . ArraySizeChecker::getDepth($nested) . "\n";
// 配列の比較
echo "\n=== 配列の比較 ===\n";
$array1 = [1, 2, 3];
$array2 = [1, 2, 3, 4, 5];
$result = ArraySizeChecker::compare($array1, $array2);
if ($result > 0) {
echo "配列1の方が大きい\n";
} elseif ($result < 0) {
echo "配列2の方が大きい\n";
} else {
echo "同じサイズ\n";
}
例2: データバリデーター
class DataValidator {
/**
* 配列の長さをチェック
*/
public static function validateArrayLength($data, $field, $min, $max) {
if (!isset($data[$field])) {
return [
'valid' => false,
'error' => "フィールド'{$field}'が存在しません"
];
}
if (!is_array($data[$field])) {
return [
'valid' => false,
'error' => "フィールド'{$field}'は配列ではありません"
];
}
$size = sizeof($data[$field]);
if ($size < $min) {
return [
'valid' => false,
'error' => "'{$field}'は最低{$min}要素必要です(現在{$size}要素)"
];
}
if ($size > $max) {
return [
'valid' => false,
'error' => "'{$field}'は最大{$max}要素までです(現在{$size}要素)"
];
}
return [
'valid' => true,
'size' => $size
];
}
/**
* 選択肢の数をチェック
*/
public static function validateChoices($choices, $min = 2, $max = 10) {
$count = sizeof($choices);
return [
'valid' => $count >= $min && $count <= $max,
'count' => $count,
'min' => $min,
'max' => $max
];
}
/**
* 必須フィールドの数をチェック
*/
public static function validateRequiredFields($data, $requiredFields) {
$missing = [];
foreach ($requiredFields as $field) {
if (!isset($data[$field])) {
$missing[] = $field;
}
}
return [
'valid' => sizeof($missing) === 0,
'missing' => $missing,
'missing_count' => sizeof($missing),
'required_count' => sizeof($requiredFields)
];
}
/**
* フォームデータを検証
*/
public static function validateForm($formData, $rules) {
$errors = [];
foreach ($rules as $field => $rule) {
if (isset($rule['min_items']) || isset($rule['max_items'])) {
if (!isset($formData[$field])) {
$errors[$field] = "フィールドが必要です";
continue;
}
$size = is_array($formData[$field]) ? sizeof($formData[$field]) : 0;
if (isset($rule['min_items']) && $size < $rule['min_items']) {
$errors[$field] = "最低{$rule['min_items']}個必要です";
}
if (isset($rule['max_items']) && $size > $rule['max_items']) {
$errors[$field] = "最大{$rule['max_items']}個までです";
}
}
}
return [
'valid' => sizeof($errors) === 0,
'errors' => $errors,
'error_count' => sizeof($errors)
];
}
}
// 使用例
echo "=== データバリデーション ===\n";
$data = [
'tags' => ['PHP', 'JavaScript', 'Python'],
'categories' => ['Web Development']
];
// 配列の長さチェック
$result = DataValidator::validateArrayLength($data, 'tags', 1, 5);
echo "タグ検証: " . ($result['valid'] ? 'OK' : 'NG') . "\n";
if (!$result['valid']) {
echo " エラー: {$result['error']}\n";
} else {
echo " サイズ: {$result['size']}\n";
}
// 選択肢の数チェック
echo "\n=== 選択肢検証 ===\n";
$choices = ['選択肢1', '選択肢2', '選択肢3'];
$result = DataValidator::validateChoices($choices);
echo "選択肢数: {$result['count']}\n";
echo "検証結果: " . ($result['valid'] ? 'OK' : 'NG') . "\n";
// 必須フィールドチェック
echo "\n=== 必須フィールド検証 ===\n";
$requiredFields = ['name', 'email', 'age'];
$userData = ['name' => 'John', 'email' => 'john@example.com'];
$result = DataValidator::validateRequiredFields($userData, $requiredFields);
echo "検証結果: " . ($result['valid'] ? 'OK' : 'NG') . "\n";
echo "不足: {$result['missing_count']}/{$result['required_count']}フィールド\n";
if (!$result['valid']) {
echo "不足フィールド: " . implode(', ', $result['missing']) . "\n";
}
// フォーム検証
echo "\n=== フォーム検証 ===\n";
$formData = [
'interests' => ['読書', '映画'],
'skills' => ['PHP', 'JavaScript', 'Python', 'Ruby', 'Go', 'Java']
];
$rules = [
'interests' => ['min_items' => 1, 'max_items' => 5],
'skills' => ['min_items' => 1, 'max_items' => 5]
];
$result = DataValidator::validateForm($formData, $rules);
echo "検証結果: " . ($result['valid'] ? 'OK' : 'NG') . "\n";
echo "エラー数: {$result['error_count']}\n";
foreach ($result['errors'] as $field => $error) {
echo " {$field}: {$error}\n";
}
例3: コレクション管理
class Collection {
private $items = [];
/**
* アイテムを追加
*/
public function add($item) {
$this->items[] = $item;
return $this;
}
/**
* 複数アイテムを追加
*/
public function addMany($items) {
foreach ($items as $item) {
$this->add($item);
}
return $this;
}
/**
* アイテム数を取得
*/
public function size() {
return sizeof($this->items);
}
/**
* 空かどうか
*/
public function isEmpty() {
return sizeof($this->items) === 0;
}
/**
* 空でないかどうか
*/
public function isNotEmpty() {
return sizeof($this->items) > 0;
}
/**
* 最初のN個を取得
*/
public function take($count) {
return array_slice($this->items, 0, $count);
}
/**
* 最後のN個を取得
*/
public function takeLast($count) {
return array_slice($this->items, -$count);
}
/**
* すべて取得
*/
public function all() {
return $this->items;
}
/**
* クリア
*/
public function clear() {
$this->items = [];
return $this;
}
/**
* チャンクに分割
*/
public function chunk($size) {
return array_chunk($this->items, $size);
}
/**
* 統計情報
*/
public function stats() {
return [
'count' => sizeof($this->items),
'empty' => $this->isEmpty(),
'first' => $this->items[0] ?? null,
'last' => $this->items[sizeof($this->items) - 1] ?? null
];
}
}
// 使用例
echo "=== コレクション管理 ===\n";
$collection = new Collection();
$collection->addMany([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
echo "サイズ: " . $collection->size() . "\n";
echo "空: " . ($collection->isEmpty() ? 'Yes' : 'No') . "\n";
echo "\n最初の3個: " . implode(', ', $collection->take(3)) . "\n";
echo "最後の3個: " . implode(', ', $collection->takeLast(3)) . "\n";
echo "\n=== チャンク分割 ===\n";
$chunks = $collection->chunk(3);
foreach ($chunks as $i => $chunk) {
echo "チャンク" . ($i + 1) . ": " . implode(', ', $chunk) . "\n";
}
echo "\n=== 統計情報 ===\n";
$stats = $collection->stats();
print_r($stats);
例4: ページネーション
class Paginator {
private $items = [];
private $perPage;
public function __construct($items, $perPage = 10) {
$this->items = $items;
$this->perPage = $perPage;
}
/**
* 総アイテム数
*/
public function total() {
return sizeof($this->items);
}
/**
* 総ページ数
*/
public function totalPages() {
return (int)ceil(sizeof($this->items) / $this->perPage);
}
/**
* 指定ページのアイテムを取得
*/
public function getPage($page) {
$page = max(1, min($page, $this->totalPages()));
$offset = ($page - 1) * $this->perPage;
return [
'items' => array_slice($this->items, $offset, $this->perPage),
'current_page' => $page,
'per_page' => $this->perPage,
'total' => $this->total(),
'total_pages' => $this->totalPages(),
'from' => $offset + 1,
'to' => min($offset + $this->perPage, $this->total()),
'has_previous' => $page > 1,
'has_next' => $page < $this->totalPages()
];
}
/**
* 各ページのアイテム数を取得
*/
public function getPageSizes() {
$sizes = [];
$totalPages = $this->totalPages();
for ($page = 1; $page <= $totalPages; $page++) {
$offset = ($page - 1) * $this->perPage;
$size = min($this->perPage, $this->total() - $offset);
$sizes[$page] = $size;
}
return $sizes;
}
}
// 使用例
echo "=== ページネーション ===\n";
$items = range(1, 47); // 47個のアイテム
$paginator = new Paginator($items, 10);
echo "総アイテム数: " . $paginator->total() . "\n";
echo "総ページ数: " . $paginator->totalPages() . "\n";
echo "\n=== ページ1 ===\n";
$page1 = $paginator->getPage(1);
echo "表示: {$page1['from']}〜{$page1['to']} / {$page1['total']}\n";
echo "アイテム: " . implode(', ', $page1['items']) . "\n";
echo "前ページ: " . ($page1['has_previous'] ? 'あり' : 'なし') . "\n";
echo "次ページ: " . ($page1['has_next'] ? 'あり' : 'なし') . "\n";
echo "\n=== 各ページのアイテム数 ===\n";
$sizes = $paginator->getPageSizes();
foreach ($sizes as $page => $size) {
echo "ページ{$page}: {$size}個\n";
}
例5: 統計計算
class Statistics {
/**
* 平均値
*/
public static function average($numbers) {
$count = sizeof($numbers);
if ($count === 0) {
return 0;
}
return array_sum($numbers) / $count;
}
/**
* 中央値
*/
public static function median($numbers) {
$count = sizeof($numbers);
if ($count === 0) {
return 0;
}
sort($numbers);
$middle = floor($count / 2);
if ($count % 2 === 0) {
return ($numbers[$middle - 1] + $numbers[$middle]) / 2;
} else {
return $numbers[$middle];
}
}
/**
* 最頻値
*/
public static function mode($numbers) {
if (sizeof($numbers) === 0) {
return null;
}
$frequency = array_count_values($numbers);
arsort($frequency);
return array_key_first($frequency);
}
/**
* 範囲(最大値 - 最小値)
*/
public static function range($numbers) {
if (sizeof($numbers) === 0) {
return 0;
}
return max($numbers) - min($numbers);
}
/**
* 要約統計
*/
public static function summary($numbers) {
$count = sizeof($numbers);
if ($count === 0) {
return null;
}
return [
'count' => $count,
'min' => min($numbers),
'max' => max($numbers),
'sum' => array_sum($numbers),
'average' => self::average($numbers),
'median' => self::median($numbers),
'mode' => self::mode($numbers),
'range' => self::range($numbers)
];
}
}
// 使用例
echo "=== 統計計算 ===\n";
$data = [85, 92, 78, 92, 88, 95, 72, 80, 92, 68];
echo "データ数: " . sizeof($data) . "\n";
echo "平均: " . Statistics::average($data) . "\n";
echo "中央値: " . Statistics::median($data) . "\n";
echo "最頻値: " . Statistics::mode($data) . "\n";
echo "範囲: " . Statistics::range($data) . "\n";
echo "\n=== 要約統計 ===\n";
$summary = Statistics::summary($data);
print_r($summary);
count()との違い(なし)
// sizeof()とcount()は完全に同じ動作
$array = [1, 2, 3, 4, 5];
// どちらを使っても結果は同じ
var_dump(sizeof($array) === count($array)); // true
// パフォーマンスも同じ
// 内部的に同じ関数を呼び出している
// 一般的にはcount()の方がよく使われる
// sizeofはC言語からの移植で残っている
まとめ
sizeof()関数の特徴をまとめると:
できること:
- 配列の要素数をカウント
- Countableオブジェクトのカウント
- 再帰的なカウント
count()との関係:
- 完全なエイリアス(別名)
- 動作は100%同じ
- パフォーマンスも同じ
カウントモード:
COUNT_NORMAL: 通常モード(デフォルト)COUNT_RECURSIVE: 再帰モード
推奨される使用場面:
- 配列のサイズ確認
- バリデーション
- ページネーション
- 統計処理
- コレクション管理
注意点:
count()の方が一般的- どちらを使っても問題なし
- チーム内で統一推奨
関連関数:
count(): 同じ機能(こちらが推奨)array_count_values(): 値の出現回数iterator_count(): イテレータの要素数
推奨事項:
// 一般的にはcount()を使用
$size = count($array); // 推奨
// sizeof()でも動作は同じ
$size = sizeof($array); // 動作するが一般的ではない
// コーディング規約で統一すると良い
sizeof()はcount()の完全なエイリアスで、どちらを使っても全く同じ結果が得られます。一般的にはcount()の方がよく使われますが、どちらを選んでも問題ありません。チーム内で統一することをお勧めします!
