ざっくりん雑記

プログラミングで忘れそうなことをひたすらメモる

PHP - データ型

 ざっくり、PHPには8種類のデータ型がある。

  • スカラー型(単一の値を取る)
  • 複合型(コレクション)
    • 配列
    • オブジェクト
  • 特殊型
    • リソース
    • NULL

整数

  • 10進形式、8進形式、16進形式そして2進形式の4通り

10進形式

2016
-321
+321

8進形式

8進数と見なされるには

  • 先頭が0
  • その後、0から7までの数字で続ける

とする。プラス・マイナスといった符号が付けられる。

0755         # 10進形式だと493
+010         # 10進形式だと8

16進形式

16進数と見なされるには

  • 先頭が0x
  • その後に数字(0,1)あるいは英字(AからF)で続ける

とする。英字は小文字/大文字は問わない。通常は大文字。符号付けられる。

0xFF         # 10進形式だと255
0x10         # 10進形式だと16
-0xDAD1      # 10進形式だと-56017

2進形式

2進数と見なされるには

  • 先頭が0b
  • その後に数字(0,1)で続ける

とする。符号付けられる。

0b00000001         # 10進形式だと1
0b00000010         # 10進形式だと2
-0b10              # 10進形式だと-2

その他

  • 整数値の範囲を超えた場合、数値以外を代入しようとした場合、自動的に浮動小数点への変換が行われる
  • 整数値かどうか調べる
if (is_int($number)) {
    // $numberは整数
}

浮動小数点数

PHPでの浮動小数点数の表し方

  • 普段見慣れている形式
3.14
0.00211
-432.122
  • 科学で用いられる記法
0.314E1     # 0.314*10^1 -> 3.14
17.0E-3     # 17.0*10^(-3) -> 0.017

浮動小数点数はあくまでも近似値

まず、注意したいのは、浮動小数点数どうしを比較する(==)コードは書いてはいけないこと。

たとえば「5.5」という値、多くのシステム上では「5.499999999999」という値で表されている。浮動小数点数が正確な値であると、期待してはいけない。

じゃあ、どう比較すればいいの? -> 小数点以下の特定桁数までのみで比較しよう

例として小数点以下3桁までを対象として比較するコードを示す。

if (intval($number_a * 1000) == intval($number_b * 1000)) {
    // 小数点以下3桁までは共通
}

その他

if (is_float($number)) {
    // $numberは浮動小数点数
}

文字列

 PHPは、Webで用いられる言語として多くの文字列操作機能を標準で組み込んでいる。  文字列とは、任意の長さの文字列を連結したもので、文字列リテラルを表すには、シングルクォート(')ダブルクォート(")で囲む。

  • ダブルクォート
    • その内部の変数は展開される
  • シングルクォート
    • 内部に変数があっても展開されない
$sushi = "maguro";
echo "Ah, I want to eat $sushi\n"
echo 'Ah, I want to eat $sushi'

上記を実行すると

Ah, I want to eat maguro
Ah, I want to eat $sushi

という結果になり、シングルクォートの変数は展開されないことがわかる。

2つの文字列が等しいかどうか

比較演算子 == を用いる。

if ($a == $b) {
  echo "aとbは等しい"
}

ある値が文字列であるかどうか

is_string()関数を用いる。

if (is_string($string)) {
  echo "$string は 文字列です"
}

その他

文字列はその他、多くの関数があるが、ここではひとまず触れないこととする。

論理値

 論理値とは、何かが真か偽かを表す。以下のように条件指定で調べる。

if ($alive) { ... }

PHPでfalse(偽)であるとみなされるもの

  • 整数値0
  • 浮動小数点数0.0
  • 空の文字列("")および文字列"0"
  • 素数がゼロの配列
  • プロパティやメソッドを一切持たないオブジェクト
  • NULL

逆に言えば、以上のもの以外はすべてtrueである。

ある値が論理値かどうか調べる

  • is_bool()関数を用いる。
if (is_bool($a)) {
    // $aは論理値
}

配列

 配列は、いくつかの値を一括して管理する。個々の値はゼロから始まる番号、あるいは文字列を指定して取得する。

$sushi[0] = "maguro";
$sushi[1] = "salmon";
$sushi[2] = "egg";

$favorability['maguro'] = "めっちゃ好き";
$favorability['salmon'] = "わりと好き";
$favorability['egg'] = "嫌いじゃない";

 array()構文にて作成する。

$sushi = array("maguro", "salmon", "egg");
$favorability = arrya('maguro'     => "めっちゃ好き",
               'salmon'     => "わりと好き",
               'egg'        => "嫌いじゃない");

 個々の値を処理する方法はいろいろある。最もよく使われているのはforeachループ。

foreach ($sushi as $neta) {
  echo "I like {$neta}\n";
}

foreach ($favorability as $neta => $rate) {
  echo "{$neta} はどれくらい好き勝手言うと… {$rate}かな?\n";
}

 上のコードが実行されると、以下の様な出力がされる。

I like maguro
I like salmon
I like egg
maguro はどれくらい好きかという… めっちゃ好きかな?
salmon はどれくらい好きかという… わりと好きかな?
egg はどれくらい好きかという… 嫌いじゃないかな?

 という感じ。

ある値が配列かどうか調べる

  • is_array()関数を用いる。
if (is_array($x)) {
    // $xは配列
}

その他

このような関数以外にも要素をソートする関数、要素数を数える関数など配列を操作する関数は数多くある。

オブジェクト

 PHPでは、オブジェクト指向プログラミングをサポートしている。クラスとは、オブジェクト指向設計で用いられる一つの部品であり、プロパティ(変数)やメソッド(関数)を持つ構造体のようなものである。クラスの定義はclassで行う。

class Sushi
{
    public $name = '';

    function name ($newname = NULL)
    {
        if (!is_null($newname)) {
            $this->name = $newname;
        }

        return $this->name;
    } 
}

 一度クラスを定義すれば、newキーワードを用いていくつでもそのオブジェクトを生成することができる。オブジェクトのプロパティやメソッドにアクセスする際には、->を用いる。

$maguro = new Sushi;
$maguro->name('まぐろ');
echo "めっちゃ新鮮な、 {maguro->name}\n";
$salmon = new Sushi;
$salmon->name('サーモン');
echo "めっちゃ新鮮な、 {salmon->name}\n";
めっちゃ新鮮な、 まぐろ
めっちゃ新鮮な、 サーモン

ある値がオブジェクトかどうか調べる

  • is_object()関数を用いる。
if (is_object($x)) {
    // $xはオブジェクト
}

リソース

 多くのモジュールには、PHPの外部の世界とやり取りするための関数が用意されている。  データベース関連の拡張モジュールであれば、

  • データベースへの接続
  • クエリの送信
  • データベースとの接続解除

 といったようなメソッドがある。  一度に複数のデータベース接続を扱うこともあるため、接続用関数は、確立した一意な接続を表す識別子を返すようになっている。この識別子を、リソース(またはハンドル)という。  アクティブなリソースは、各々が一意な識別子をもつ。その識別子は数値のインデックスとなっている。

 PHPの内部ルックアップテーブルはこのリソースを保持し、参照することになっている。コード内でそのリソースが参照されている(使用されている)数などを、このテーブルで管理する。作成したリソースへの参照がなくなった時点で、そのリソースを作成した拡張モジュール自身がメモリの解放などの後始末を行う。

 関数内でリソースをローカル変数に代入してしまえば、関数が終了した時点でそのローカル変数への参照はなくなる、つまりその変数の値がPHPの管理下に戻るため、後始末が自動的に実行させることができる。

 多くの拡張モジュールでは、後始末用の関数を個別で用意しているため、自動的なリソース解放に頼らずとも、明示的にその関数を呼び出すことでリソースを開放することも可能であったりする。

ある値がリソースかどうか調べる

  • is_resource()関数を用いる。
if (is_resource($x)) {
    // $xはリソース
}

NULL

 NULLが表す値は1つだけ、NULLである。これは、大文字/小文字を区別しない。  NULLということは、その変数に何も値が代入されていないことを表す。(PerlPythonでいうNoneと同じ意味)

$sushi = "maguro";
$sushi = "null";    // 変数の値が解除
$sushi = "Null";    // 上と同じ
$sushi = "NULL";    // 上と同じ

ある値がNULLかどうか調べる

  • is_null()関数を用いる。
if (is_null($x)) {
    // $xはNULL
}

参考

プログラミングPHP 第3版

プログラミングPHP 第3版