PHPの基礎 - 変数

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

変数は文字列や数値の値を格納するために使用する。
単に値を保持するだけではなく、変数そのものに対して演算することも可能である。


変数の宣言と値の代入

PHPの変数は、値そのものを変数に格納する。
変数は事前に宣言は必要は無く、値を格納した時点からその変数を使用することができる。

変数を使用するには、変数名と変数に格納する値を使用する。
変数は、$ + <変数名>で表される。

$<変数名> = <値>;


変数名として使用できる文字列は、先頭がアンダーバーまたはアルファベットで始まる。
変数名は、大文字・小文字は区別されて、英数字やアンダーバー以外の記号で変数名を始めることはできない。

変数に値を格納するには、代入演算子=を使用する。

 $old = 20;
 $name = '加藤';


数値や文字列等の値が変数に格納されると、変数は値のように扱うことができる。
例えば、変数をprint文等で出力すること、および、数値が格納された変数を他の数値と演算することもできる。

 $name = '加藤';
 print $name;

 $num = 20;
 print $num * 9;


変数は、他の変数を格納することもできる。
以下の例では、変数num1に格納された値が変数num2にコピーされている。

 $num1 = 320;
 $num2 = $num1;


PHPにおける変数は各変数が値を保管しているため、任意の変数を別の変数に代入する時、元の変数の値を複製して別の変数に格納する。


変数の初期化とNULL

変数は、値を格納していない状態でも使用することができる。

以下のように、1度も値が代入されておらず、初期化していない変数には、NULLが格納されていると見なされる。

 print $name;  // $name = NULL;と同じ意味
               // 変数には値が格納されていないため、出力しても何も表示されない (ただし、エラーではない)


NULLは、データ型の1つで値が存在しないことを表す。
明示的に、変数にNULLを代入することにより、変数には値が存在していない状態となる。

大文字・小文字は区別しないため、Nullやnullも使用できる。


変数のデータ型

データ型の概要

数値や文字列等の値にはデータ型が存在するが、PHPの変数はどのデータ型でも同じように格納することができる。
そのため、変数の型を宣言する必要はない。

 $name = 'Yamada';
 $old = 24;


また、任意の値が格納された変数に対して、別のデータ型の値を再度格納することもできる。
変数に型が存在しないわけではなく、自動的に格納された値の型に変換される。

 $var = 'Yamada';
 $var = 24;


以下の例では、gettype関数を使用して、引数の値や変数の型を確認している。
格納された値に応じて、変数のデータ型も変換されていることが確認できる。

 <?php
    $var = '高橋';
    print '[値]'.$var.',';
    print '[型]'.gettype($var).'<br />';
 
    $var = 180;
    print '[値]'.$var.',';
    print '[型]'.gettype($var).'<br />';
 ?>


整数

最大値 / 最小値

最大値および最小値は、AMD64またはx86環境により依存することに注意する。

PHPでは、オーバーフローまたはアンダーフローを引き起こしてもプログラムはエラーにならない。
特に、ユーザが⼊⼒した数値においては、必ず範囲内に収まっているかどうかを⼊⼒時にチェックする必要がある。

 // 整数の最⼤値
 $intmax = PHP_INT_MAX;
 var_dump($max);
 
 // 整数の最⼩値
 $intmin = PHP_INT_MIN;  // PHP 7.0以降使用可能
 var_dump($min);


累乗
 // PHP 5.5以前は、pow関数を使用する必要がある
 var_dump(pow(2, 3));
 
 // PHP 5.6以降は、**演算⼦および^演算子が使用できる
 var_dump(2 ** 3);
 var_dump(2 ^ 3);
 
 // 数値でない値を累乗計算する場合は、警告が発⽣する
 var_dump('a' ** 3);


2進数 8進数 16進数

以下に示すようなものに利⽤されている。

  • 16進数の例 : HTMLのカラーコード
  • 8進数の例 : Linuxにおけるファイルのパーミッション


 $a = 0b111;     // 2進数 : 先頭に0bを付加する
 var_dump($a);  // int(7)
 
 $b = 012;       // 8進数 : 先頭に0を付加する
 var_dump($b);   // int(10)
 
 $c = 0x1A;      // 16進数 : 先頭に0xを付加する
 var_dump($c);   // int(26)


浮動⼩数点数

浮動小数点の概要

浮動⼩数点数は、⼩数を含めた数を表現できる型である。
浮動小数点数(float型)のサイズは、AMD64またはx86により依存する。
一般的に、10進数で14桁の精度があり、AMD64での最大値は約1.8e308 (IEEE 854) となる。

 $number = 3.14;         // 値 : 3.14
 echo $number. PHP_EOL;
 
 $number = 3.14e5;       // 値 : 314000
 echo $number. PHP_EOL;
 
 $number = 1_234.567;    // PHP 7.4以降は、_(アンダーバー)が使用できる
 
 if (is_float($number))       print "number is float" . PHP_EOL;
 else if (is_double($number)) print "number is double" . PHP_EOL;


浮動小数点のキャスト

floatval関数 / doubleval関数は、他のデータ型から浮動小数点型に変換する。
どちらも同様の機能であるが、floatval関数を使用した方がよい。

 $num = "100";  // 文字列型として宣言
 
 $num1 = floatval($num);
 echo gettype($num1). PHP_EOL;  // floatと出力
 
 $num2 = doubleval($num);
 echo gettype($num2). PHP_EOL;  // doubleと出力


変換の型を指定して明示的に変換する。
どちらも同様の機能であるが、float型としてキャストした方がよい。

 $num = "3.14";  // 文字列型として宣言
 
 $num1 = (float)$num;
 echo gettype($num1). PHP_EOL;  // floatと出力
 
 $num2 = (double)$num;
 echo gettype($num2). PHP_EOL;  // doubleと出力


その他のデータ型から浮動小数点にキャストする。
このキャスト結果は、整数型とほぼ同じである。

 var_dump((float)"aaa");     // キャストの結果 : 0  (文字列の場合は、全て0となる)
 var_dump((float)"999aaa");  // キャストの結果 : 999  (文字列 + 数値の場合は、文字の部分が削除されてキャストされる)
 var_dump((float)"123");     // キャストの結果 : 123
 var_dump((float)"999.99");  // キャストの結果 : 999.99
 var_dump((float)"4E2");     // キャストの結果 : 400
 var_dump((float)true);      // キャストの結果 : 1
 var_dump((float)false);     // キャストの結果 : 0
 var_dump((float)null);      // キャストの結果 : 0


NaN

数値演算の結果が定数NaNで表される値になることがある。
この定数は、浮動小数点演算における未定義の値あるいは表現不能な値を表す。

この値を他の値と比較すると、緩やかな比較および厳密な比較のいずれでも結果はfalseとなる。

NaNは様々な値の数を表すものであり、NaNを他の値と比較してはならない。
NaNの確認を行う場合は、is_nan関数を使用する。

文字列

文字列の概要

Webプログラミングでは、⽂字列を頻繁に使用する。
ユーザ名、メールアドレス、住所等、対象とする⽂字列は様々である。

PHPでは、AMD64環境では⽂字数の⻑さに制限がない。
x86環境では、⽂字列の最⼤⻑は2[GB]が上限となる。

ただし、⻑い⽂字列を⽣成するとメモリが不⾜してメモリーオーバーを引き起こし、プログラムは異常終了することに注意する。

全⾓文字

⽇本語を1⽂字として判定したい場合は、mb_strlen関数を使⽤する。
その他にも、マルチバイトを考慮して⽂字列を判定する関数が存在する。

 // マルチバイト文字を考慮した⽂字数
 $a = 'あいうえお'
 echo mb_strlen($a). PHP_EOL;  // 出力 : 5


半⾓文字と全⾓文字の組み合わせ

mb_convert_kana関数による⽂字列の変換は、⽇本語を扱う上で重要である。
PHP 8.2以降では、オプションの組み合わせが無効な場合、例外ValueErrorがスローされる。

以下の例では、mb_convert_kana関数の第2引数において、次に示す変換をしている。

  • K
    半⾓カタカナを全⾓カタカナに変換する。
  • a
    全⾓英数字を半⾓英数字に変換する。
  • s
    全⾓スペースを半⾓スペースに変換する。


使用可能な変換オプション
オプション 説明
r 全角英字を半角英字に変換する。
R 半角英字を全角英字に変換する。
n 全角数字を半角数字に変換する。
N 半角数字を全角数字に変換する。
a 全角英数字を半角数字に変換する。
A 半角英数字を全角英数字に変換する。
(aオプション、Aオプションに含まれる文字は、U+0022, U+0027, U+005C, U+007Eを除く U+0021 - U+007E の範囲である)
s 全角スペースを半角スペースに変換する。
(U+3000 -> U+0020)
S 半角スペースを全角スペースに変換する。
(U+0020 -> U+3000)
k 全角カタカナを半角カタカナに変換する。
K 半角カタカナを全角カタカナに変換する。
h 全角ひらがなを半角カタカナに変換する。
H 半角カタカナを全角ひらがなに変換する。
c 全角カタカナを全角ひらがなに変換する。
C 全角ひらがなを全角カタカナに変換する。
V 濁点付きの文字を一文字に変換する。

※注意
このオプションは、Kオプション、または、Hオプションと共に使用する必要がある。


 // ⽇本語⽂字列の変換
 // (変換前)全⾓の1(全⾓スペース)あ(全⾓スペース)半⾓のイ
 $c = "1 あ イ";
 
 // (変換後)半⾓の1(半⾓スペース)あ(半⾓スペース)全⾓のイ
 $d = mb_convert_kana($c, Kas);
 echo $c. PHP_EOL; // 1 あ イ
 echo $d. PHP_EOL; // 1 あ イ


これにより、半⾓文字と全⾓文字を統⼀する。
全⾓文字と半⾓文字が混ざる場合、正常に⽂字列の検索ができない状況が起きる。
また、カタカナを全⾓文字として統⼀することができるといった理由もある。

例えば、Webページ上において、数値は半⾓で⼊⼒すると指定したとしても、全⾓文字として⼊⼒するユーザは多い。
そのため、全⾓文字と半⾓文字を統⼀することが重要である。

Webで使用されている文字コードを、以下に示す。

  • UTF-8
    ほとんどのWebページで使用されている。
  • ISO-2022-JP
    過去には、電⼦メールで使用されることが多かった。 (現在では、ほとんどがUTF-8である)
  • SHIFT-JIS (SJIS)
    主に、フィーチャーフォン(ガラケー)向けのモバイルサイトで使用されている。



変数の参照

PHPは、他の変数への参照を設定することも可能である。

他の変数への参照を設定するには、以下のように記述する。

=&を使用することで、右辺の変数のエイリアスとして左辺の変数を設定する。
これにより、右辺の変数が格納された値に左辺の変数名でも参照することができる。

 <変数名> =& <他の変数名>


以下の例では、変数num1の値を後から変更する場合、変数num2が格納している値も同じように変更される。

 $num1 = 320;
 $num2 =& $num1;
 
 $num1 = 45;



様々な代入演算子

変数には、演算結果の格納や文字列同士の連結した結果を格納等ができる。

 $num = 80 * 15;
 $pref = '愛知';
 $address = $pref.'県';


PHPには、以下の示す演算子が用意されている。

+=, -=, *=, /=, %=, .=


以下の例では、.=演算子を使用して文字列を連結している。

 $str = '山田';
 $str .= 'さん';



定数

定数は、数値や文字列等の値を、理解しやすい文字列として値を定義して使用する。

定数の定義は、以下のように記述する。

define("<識別子>", <値>);


識別子として使用できる文字列は、先頭がアンダーバーかアルファベットで始まる必要がある。
大文字・小文字は区別されるが、慣習的に定数名は全て大文字を使用される。
変数名とは異なり、先頭に$は必要ない。

以下の例では、商品単価に消費税を加えたものを計算している。
消費税は5[%]として計算しているが、いずれ変更される可能性もあるため、0.05という数値の代わりに定数TAXを定義する。
このように、消費税率が変更されても定数TAXの定義を変更するだけで済む。

 define("TAX", 0.05);
 
 $price1 = 100 * (1 + TAX);
 $price2 = 84 * (1 + TAX);
 $price3 = 180 * (1 + TAX);


値として指定できるのは文字列、数値、論理値のいずれかである。

 define("TAX", 0.05);
 define("PAI", 3.14159);
 define("COPYRIGHT", "Copyright (C) 2008 XXX. All Rights Reserved.");



変数展開

文字列をダブルクオーテーションで囲む場合やヒアドキュメントの場合、文字列に変数が存在する時、変数は格納されている値に置換される。
このような処理を変数展開と呼ぶ。

以下の例では、文字列に変数nameが記述されている。
この文字列を出力する時、"こんにちは。高橋 さん"と変数に格納されている値に置き換えて出力される。

 $name = '高橋';
 echo "こんにちは。$name さん";


変数展開において、変数が記述された位置の後ろにアルファベットが続く場合は、どこまでが変数名なのか区別できない場合がある。
以下の例では、変数colornamecolorを変数展開されてしまう。

 $colorname = 'red';
 echo "frame is $colornamecolor";


このように、どこまでが変数名なのか区別できない場合や配列変数等を使用する場合は、変数名を{}で囲んで記述する。

 $colorname = 'red';
 echo "frame is ${colorname}color";


※注意
シングルクオーテーションで囲んだ文字列で変数を記述しても、変数展開は行われない。


変数の削除

unset関数

unset関数は、変数や配列の要素を破棄するための関数である。

これは、nullを代入するのとは異なり、変数そのものを削除することに注意する。
変数を完全に破棄するため、メモリが解放される。

最も一般的な使用方法は、単純な変数の破棄である。

 $name = "John";
 unset($name);  // $nameという変数が破棄される
 
 // 複数の変数を同時に解除
 $a = 1;
 $b = 2;
 unset($a, $b); // 複数の変数を1度に破棄することもできる
 
 // unset後にisset関数で確認する場合、falseを返す
 isset($a)


配列の場合、特定の要素を削除することができる。
ただし、要素を削除しても配列のインデックスは自動的には詰められない。

 $fruits = ["apple", "banana", "orange"];
 unset($fruits[1]);  // "banana"が削除される
                     // 結果: array(0 => "apple", 2 => "orange")


また、セッション変数を破棄することもできる。
例えば、ユーザのログアウト処理等で使用されることが多い。

 unset($_SESSION['user_id']);  // 特定のセッション変数を破棄


オブジェクトのプロパティを削除することもできる。

 class User {
    public $name;
 }
 
 $user = new User();
 $user->name = "John";
 unset($user->name);  // プロパティを削除


関数内でグローバル変数をunsetする場合は、globalキーワードを使用しない限り、関数内でのunsetはローカルスコープにのみ影響を与える。

 $global_var = "test";
 function removeGlobal() {
    global $global_var;  // globalキーワードが必要
    unset($global_var);
 }


大規模なアプリケーションでメモリ管理を最適化する場合にunset関数が重要な役割を果たす。
特に、大きな配列やオブジェクトを扱う場合、不要になったデータを適切にunsetすることにより、メモリ使用量を抑えることができる。

array_splice関数

なお、配列の要素を削除する場合の代替手段として、array_splice関数がある。
これは、インデックスを自動的に詰めることができる。

 $array = [1, 2, 3];
 
 // 出力: [1, 3]
 array_splice($array, 1, 1);  // インデックスを詰めて削除


配列の要素を削除するだけでなく、置換、挿入等の様々な配列操作に柔軟に対応できる便利な関数である。
unset関数と異なり、インデックスが自動的に詰められる特徴があるため、連続したインデックスを維持したい場合に特に有効である。

array_splice関数の基本的な構文を以下に示す。

 // 基本的な構文
 
 array_splice(array &$array, int $offset [, int $length = null [, mixed $replacement = array() ]]);


  • 第1引数
    操作対象の配列
    参照渡しで渡すため、元の配列が直接変更される。
    $fruits = ['apple', 'banana', 'orange', 'grape'];
    array_splice($fruits, 2); // 配列fruitsが直接変更される
    

  • 第2引数
    変更を開始する位置を指定する。
    正の数の場合は配列の先頭、負の数の場合は末尾からカウントする。
    $colors = ['red', 'blue', 'green', 'yellow'];
    array_splice($colors, 1);    // 先頭から1番目以降を削除
                                 // 出力: ['red']
    array_splice($colors, -2);   // 末尾から2つを削除
                                 // 出力: ['red', 'blue']
    

  • 第3引数
    省略可能
    削除する要素の数を指定する。
    省略する場合は、開始位置から配列の末尾まで全ての要素が対象となる。
    $numbers = [1, 2, 3, 4, 5];
    array_splice($numbers, 1, 2);  // 1番目の位置から2つの要素を削除
    // 結果: [1, 4, 5]
    

  • 第4引数
    省略可能
    削除した箇所に新しい要素を挿入できる。
    $pets = ['dog', 'cat', 'bird'];
    array_splice($pets, 1, 1, ['hamster', 'rabbit']);
    // 結果: ['dog', 'hamster', 'rabbit', 'bird']
    


実際の使用例として、配列の特定の位置に要素を挿入する場合がある。

 $menu = ['coffee', 'tea', 'juice'];
 
 // lengthを0にすることで、要素の削除なしで挿入できる
 // 出力: ['coffee', 'latte', 'tea', 'juice']
 array_splice($menu, 1, 0, 'latte');


この関数の特徴は、削除された要素を戻り値として返すことである。

 $items = ['A', 'B', 'C', 'D'];
 $removed = array_splice($items, 1, 2);
 
 // $removedは ['B', 'C']
 // $itemsは ['A', 'D']



Nullable型

PHPの型宣言において、?<型名>の記法は、その変数がデータ型またはnullを許容することを示す。
これは、Nullable型と呼ばれ、PHP 7.1以降で導入された機能である。

例えば、?string型は、string|nullと同じ意味になる。
また、デフォルト値としてnullを指定することができる。

ただし、nullでない場合は、必ず文字列型である必要がある。

 function example(?string $section = null)
 {
    if ($section === null) {
       // $sectionがnullの場合の処理
       return "Section is null";
    }
 
    // $sectionが文字列の場合の処理
    return "Section is: " . $section;
 }
 
 // 両方とも有効な呼び出し
 echo example(null);         // "Section is null"
 echo example("Chapter 1");  // "Section is: Chapter 1"



スーパーグローバル変数

スーパーグローバル変数は、スクリプトのどこからでもアクセスできる。
ただし、セキュリティ上の理由から、入力値は必ず適切なバリデーションやサニタイズを行ってから使用する必要がある。

$_GET

URLパラメータからデータを取得する。
例: example.php?name=taroの場合、$_GET['name']は"taro"となる。

$_POST

POSTメソッドで送信されたフォームデータを取得する。
ファイルアップロードやパスワード等、セキュアなデータ送信に使用する。

$_SESSION

セッション変数を格納する。
ユーザのログイン状態管理等に使用する。

$_COOKIE

クライアント側に保存されたCookie情報を取得する。
ユーザ設定の保存等に使用する。

$_SERVER

サーバ情報やリクエストの詳細を取得する。

主な要素

  • $_SERVER['REQUEST_METHOD']
    HTTPメソッド
  • $_SERVER['HTTP_USER_AGENT']
    ブラウザ情報
  • $_SERVER['REMOTE_ADDR']
    クライアントのIPアドレス


$_FILES

アップロードされたファイルの情報を取得する。
ファイル名、サイズ、一時保存先等の情報を含む。

$_REQUEST

$_GET、$_POST、$_COOKIEの内容を含む。

※注意
セキュリティ上、直接的な使用は推奨されない。

$_ENV

環境変数の値を取得する。
サーバ設定や環境設定値へのアクセスに使用する。

$GLOBALS

グローバルスコープで定義された全ての変数を参照する。
他のスーパーグローバル変数も含む。