10週間ウェブ開発講座

裏メニュー第二週

データ型

PHPのデータ型について解説します。

データ型

PHPが扱うデータには型が指定されています。
型とはデータの「種類」を示す情報です。

PHPのデータ型には次のようなものがあります*1

  • 論理型
  • 整数型
  • 実数型
  • 文字列型
  • 配列型

ここでは扱いませんが、この他にもリソース型、NULL型が存在します。
またプログラマがクラス定義を記述し、それをインスタンス化すると「xx*2クラスを元にしたデータ」が生成されます。
そのようなデータを「xxクラスのオブジェクト」と表現することもあります。

データ型の確認

変数の型を確認するためにはgettype関数*3を使います。

<?php
$a = 1;
$b = 1.0;
$c = NULL;
$d = new stdClass;
$e = 'foo';

echo gettype($a); // => "integer"
echo gettype($b); // => "double"
echo gettype($c); // => "NULL"
echo gettype($d); // => "object"
echo gettype($e); // => "string"
?>

データ型と比較演算

PHPの比較演算子には、型情報も含めて値を比較するものと型情報を無視して値を比較するものがあります。
型情報を無視する比較を「曖昧な比較」と表現することがあります。
曖昧な比較はバグを埋め込むことに繋がり易いので、常に型情報を含めて値を比較する習慣を身に付けましょう

PHPの比較演算子には次のようなものがあります(PHPマニュアルより引用)。

名前結果
$a == $b等しい$a が $b に等しい時に true
$a === $b等しい$a が $b に等しく同じ型である場合に true
$a != $b等しくない$a が $b に等しくない時に true
$a <> $b等しくない$a が $b に等しくない時に true
$a !== $b等しくない$a が $b に等しくないか、同じ型でない場合に true
$a < $bより少ない$a が $b より少ない時に true
$a > $bより多い$a が $b より多い時に true
$a <= $bより少ないか等しい$a が $b より少ないか等しい時に true
$a >= $bより多いか等しい$a が $b より多いか等しい時に true

曖昧な比較のために意図せぬ振舞いをするコードを例示します。

<?php
$sample = '2人で行ったあの映画館。今は違う建物。寂しい。';
if (2 == $sample) {
  echo "true\n"; // こちらを通る
} else {
  echo "false\n";
}
?>

比較演算子を == から === に変更して振舞いを検証します。

<?php
$sample = '2人で行ったあの映画館。今は違う建物。寂しい。';
if (2 === $sample) {
  echo "true\n";
} else {
  echo "false\n"; // こちらを通る
}
?>

こちらの方が直感と一致する振舞いであると言えるでしょう。

データ型の変換

ある変数の型を変更することを「(型)キャストする」と表現します。
キャストは次のようにして行います。

<?php
$a = 1;
$b = 1.0;

if ($a === $b) {
  echo "\$a と \$b は等しい\n";
} else {
  echo "\$a と \$b は等しくない\n"; // こちらを通る
}

$b = (integer)$b; // integer型にキャスト
if ($a === $b) {
  echo "\$a と \$b は等しい\n"; // こちらを通る
} else {
  echo "\$a と \$b は等しくない\n";
}
?>

宿題

全ての整数は実数でもあります(包含関係)。このことを踏まえて次の問いかけに答えてください。

  • PHP に整数型が存在するメリットは何でしょうか?
  • 整数値を実数値に変更することで動作が変わるプログラムを例示してください

比較演算では == の代りに === が、 != の代りに !== が使用されるべきです。このことを踏まえて次の問いかけに答えてください。

  • 同僚のプログラマに「== のような曖昧な比較演算は開発効率を向上させる」と主張されたときにどう返答すればよいでしょうか?
  • 比較演算子 === を == に置換することで動作が変わるプログラムを例示してください

次のプログラムが含む潜在的不具合を指摘してください。
(オプション:難しい)複数の潜在的不具合を発見した場合は複数指摘してください。

<?php
// body_measurement テーブルから各人の「名前」「身長」「体重」を取得し、
// それらの情報と計算したBMIを出力するプログラムです。
//
// body_measurement テーブルの定義は次の通りです。
// --
// CREATE TABLE `body_measurement` (
//   `id` int(11) NOT NULL auto_increment,
//   `name` varchar(255) NOT NULL,
//   `height` double default NULL,
//   `weight` double default NULL,
//   PRIMARY KEY  (`id`)
// ) ENGINE=MyISAM DEFAULT CHARSET=utf8

$db_handle = new PDO('mysql:host=localhost;dbname=test', 'y_mahata', 'password');
$query = 'SELECT * FROM body_measurement';
$st_handle = $db_handle->prepare($query);
$st_handle->execute();
while ($row = $st_handle->fetch(PDO::FETCH_ASSOC)) {
  $name = intval($row['name']);
  $height = intval($row['height']);
  $weight = intval($row['weight']);
  $bmi = $weight / (($height / 100) * ($height / 100));

  echo "{$name}, {$height}, {$weight}, {$bmi}\n";
}
?>

参考資料


*1 前提としている環境はPHP5です。
*2 xx は定義されたクラスの名前と仮定します。
*3 この関数は非推奨の関数です。代りにis_*関数を使用することが推奨されています。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-04-08 (木) 18:01:08 (150d)