PHP/入門/変数と値

出典: フリー教科書『ウィキブックス(Wikibooks)』
< PHP
ナビゲーションに移動 検索に移動

算術演算[編集]

まず、PHPで加算や減算など四則演算を表示したい場合、

<?php
	echo 1+3, "aaa", 50+8, "<br>";
?>
実行結果
4aaa58
  • PHPは2種類の文字リテラルの構文があります。1つは"(ダブルクォーテーションマーク)でくくる方法が、もう1つは(ダブルクォーテーションマーク)でくくる方法です。"でくくると文字列の中の変数は展開されます。でくくると文字列の中の変数は展開されません。
  • echo文は、print文と機能が似ていますが、引数を複数受け取ることができるので、コードがドット記号 .(文字列連結演算子)や( )(括弧)だらけになるのを避けることができます。
    四則演算などの算術演算子と文字列連結演算子を1つの式で混在させる場合、計算値の範囲を丸カッコ ( ) で指定する必要があります。文字列連結演算子の方が高いからです。
  • <br> はHTMLのBR要素(強制改行)です。もしウェブコンテンツとしてレンダリングしているのでなければ、改行されずにそのまま<br> が表示されます。

また、この表示後のページのソースコードを見ても(一般的なwebブラウザにはhtmlソースコード表示の機能がある)、

実行結果
4aaa58<br>
のように、計算後の値が出力されていることがわかります。
PHPはこのように、計算後の数値をHTMLに代入します。

サーバーサイドのレンダリングの仕組み[編集]

PHPがウェブサーバー側で動いている時、.phpの拡張子のついたスクリプトファイルは、ウェブサーバーによってHTTPリクエストをきっかけにルーティングされ、PHPのプログラムとして実行されます。プログラムの実行結果は標準出力に書き出され、この時すでにHTMLの形式であり、echo や print の「結果」がレンダリングされています(されるようにプログラムを組みます)。ウェブサーバは、PHPで書かれたプログラムのレンダリング結果に、HTTPレスポンスヘッダーをつけユーザーエージェント(多くの場合ウェブブラウザ)に応答します(都度HTMLファイルが書かれるわけではありません)。 このため、PHPで書かれたプログラムの内容はユーザーエージェント側には送信されません。

変数とは[編集]

変数とは、値に名前をつけてプログラム中から参照で切るよにする仕組みです。 変数は必ず名前を持ち、識別子のルールに従います。


PHPの変数を扱う決まり[編集]

変数を示すとき、 $ を初めに書きます。 また、識別子は、最初の文字が _ もしくはアルファベットである必要があります。

つまり、

$kk3k
$_kkk54

は変数名として有効ですが、

$89aa
$7_loop

が変数名としては無効です。

PHPでは、変数名の大文字、小文字を区別します。

$name  $NAME  $Name  $namE  $nAME

はすべて違う変数です。

変数を使う[編集]

概要[編集]

変数を使うプログラムをかいてみる。

<?php
$a = 99;

echo $a, PHP_EOL;
?>
実行結果
99
上記コードは変数 $a に値 99を代入し、それをecho文によって表示するプログラムである。
このように変数は、文字列を入れることもできる。


引用符の中での変数の埋め込み

ほかの例も下記に見ていこう。

:
<?php
$a = "こんにちは";

echo "挨拶 : {$a}", PHP_EOL;
?>
実行結果
挨拶 : こんにちは
このように、引用符の中に変数を埋め込むことができる。
$aを{}で囲んでいるのは、分かち書きされていないと変数名を正しくparseできないためです。

変数と文字の連結[編集]

PHP で変数と文字列を連結するとき、. を使う。(文字列と別の文字列の連結で使う.演算子と同一です。)

<?php
$a = 7;
print $a . " is answer";
?>
実行結果
7 is answer

なお、下記のようにドット連結を使わなくても、同じ結果になるコードを書くことができる。

<?php
$a = 7;
print "{$a} is answer";
?>
実行結果
7 is answer

printとprintf[編集]

print文とは別に、printf という末尾にfのついている関数があります。末尾にfのつくほうの printf 関数は、C言語に由来する関数です(C言語に同じ名前の関数があり、同じような書式で使います)。

<?php
$a = 7;
printf ("%d is answer", $a);
?>
実行結果
7 is answer

演算子[編集]

PHPでは他のプログラミング言語同様、数学風の演算子式で計算を行う。

:
<?php
$num1 = 70;
$num2 = 12;
$sum = 0;

$sum = $num1 + $num2;
echo $sum, "<br>"
$sum = $num1 - $num2;
echo $sum, "<br>"
$sum = $num1 * $num2;
echo $sum, "<br>"
$sum = $num1 / $num2;
echo $sum, "<br>"
$sum = $num1 % $num2;
echo $sum, "<br>"
?>
実行結果
82
58
840
5.8333333333333
10
※ PHPの除算は、割り切れない場合の「/」の結果は浮動小数である。この型変換の規則は、プログラミング言語ごとに異なり、負の値が関連した時に特異的に特徴が出ることもあるので、PHPに限らず新しいプログラミング言語を習得するときのチェックポイントです。
整数の範囲で割り算をしたい場合には、PHP7以降ではintdiv() 関数を使うことで実現できる。
PHP7以前でも、小数点斬り捨ての関数 floor()などで、割り算の整数値を求められる。

たとえば、Apache上でPHP7を試しても(webブラウザで閲覧)、

<?php
 print(70/12);
?>

の結果は

5.8333333333333

という浮動小数である。

intdiv()は、HTMLに組み込む場合、

<?php
  print(intdiv(70,12));
?>

のように使い、結果は「5」である。書式は intdiv(割られる数,割る数) である。


説明の簡単化のためコマンドラインから使う場合で説明すると、

php > print(intdiv(70,12));
5

のように、1行目を入力すると、2行目に答えの「5」が自動的に出てくる。


floor()関数を使うなら、

php > print(floor(70/12));
5

「5」というのは、

70/12 = 5 あまり10

の商の5の事である。


この、 + - * /  % は、それぞれ「演算子」と呼ばれる。

<?php

$a = 5;
$b = 5;

$a++;
$b--;

printf ($a . "<br>" . $b);

?>
実行結果
6
4

このように、 ++, -- 、はそれぞれ、プラス1, マイナス1を実行する。

これらをそれぞれ、(プラス1するほうを)インクリメント、(マイナス1するほうを)デクリメント、と呼ぶ。

定数[編集]

PHPには、$で始まる変数とは別に、イミュータブルなオブジェクト=定数を宣言することができます。

<?php
const a = 42;

echo "a = ", a , PHP_EOL;
?>
実行結果
a = 42
定数は変数と違い $ を前置しません。
定数への代入(エラーになります)
<?php
const a = 99;

echo "a = ", a , PHP_EOL;

a = 10;
?>
エラー
PHP Parse error:  syntax error, unexpected token "=" in /workspace/Main.php on line 6
このように、定数への代入はパース時に構文エラーになります。
また変数と定数は名前空間が異なるので、同じ名前の変数と定数があっても問題ありません。

define()は使うべきではない[編集]

組込み関数 define() を使っても定義できますが

  • キーワードも定数として定義できてしまう
  • 大文字小文字を区別しない定数が定義できてしまう
    PHP 8.0.0 以降では無効。この機能を使っていたプログラムはPHP 8.0.0 以降では動きません。
  • const 宣言と機能が重複する

というバグ級の仕様上の問題があります。

define()は使うべきではありません。

あえて define() を使うべきケース
クラスのインスタンスを定数にしたい場合
const では、クラスのインスタンスを定数にできません(8.1.13時点で、コンパイル時に確定している値しか定数にできません)。
例えば、複素数型の定数として虚数単位 i を定義したい場合困ります。
function i() { return new Complex(0, 1); }でも良い気がしますが、毎回インスタンスが新たに作られるので、 === が思ったように機能しません。

readonlyプロパティ[編集]

const と似た仕組みに、PHP 8.1.0 以降のクラスのプロパティのreadonly修飾子があります。 ただし、readonly修飾子はプロパティにしか使えません。

また、クラスはクラススコープの定数「クラス定数」を定義することができます。

マジカル定数[編集]

PHPには9つのマジカル定数( Magic constants )があり、それらは使用される場所によって変化します[1]。 たとえば、__LINE__ の値は、スクリプトのどの行で使用されるかに依存します。 これらの「魔法の」定数は、実行時に解決される通常の定数とは異なり、すべてコンパイル時に解決されます。 これらの特殊な定数は大文字と小文字を区別しません。

PHP のマジカル定数
名称 説明
__LINE__ ファイル中の現在の行番号
__FILE__ シンボリックリンクを解決したファイルのフルパスとファイル名。インクルード内で使用された場合、インクルードファイルの名前が返されます。
__DIR__ ファイルが存在するディレクトリ。インクルード内で使用された場合、インクルードファイルのディレクトリが返されます。これは、dirname(__FILE__)と同等である。このディレクトリ名は、ルートディレクトリでない限り、末尾のスラッシュを持ちません。
__FUNCTION__ 関数名。匿名関数の場合は {closure}
__CLASS__ クラス名。クラス名には、宣言された名前空間が含まれます (例: Foo\Bar)。trait メソッドで使用される場合、__CLASS__ は trait が使用されるクラスの名前になります。
__TRAIT__ トライト名。トレイト名には宣言された名前空間が含まれます (例: Foo\Bar)。
__METHOD__ クラスメソッド名。
__NAMESPACE__ 現在のネームスペース名。
クラス::class 完全修飾クラス名。
<?php
namespace MyNamespace {
    trait MyTrait {
        public function myTraitFunction(): void
        {
            echo "--- In trait method call ---", PHP_EOL;
            echo "__DIR__ = ", __DIR__, PHP_EOL;
            echo "__FILE__ = ", __FILE__, PHP_EOL;
            echo "__LINE__ = ", __LINE__, PHP_EOL;
            echo "__FUNCTION__ = ", __FUNCTION__, PHP_EOL;
            echo "__METHOD__ = ", __METHOD__, PHP_EOL;
            echo "__CLASS__ = ", __CLASS__, PHP_EOL;
            echo "__TRAIT__ = ", __TRAIT__, PHP_EOL;
            echo "__NAMESPACE__ = ", __NAMESPACE__, PHP_EOL;
            echo "MyClass::class = ", MyClass::class, PHP_EOL, PHP_EOL;
        }
    }
    class MyClass {
        use MyTrait;
        
        public function __construct() {
            echo "--- In construcror ---", PHP_EOL;
            echo "__DIR__ = ", __DIR__, PHP_EOL;
            echo "__FILE__ = ", __FILE__, PHP_EOL;
            echo "__LINE__ = ", __LINE__, PHP_EOL;
            echo "__FUNCTION__ = ", __FUNCTION__, PHP_EOL;
            echo "__METHOD__ = ", __METHOD__, PHP_EOL;
            echo "__CLASS__ = ", __CLASS__, PHP_EOL;
            echo "__TRAIT__ = ", __TRAIT__, PHP_EOL;
            echo "__NAMESPACE__ = ", __NAMESPACE__, PHP_EOL;
            echo "MyClass::class = ", MyClass::class, PHP_EOL, PHP_EOL;
        }
        public function myFunction(): void
        {
            echo "--- In method call ---", PHP_EOL;
            echo "__DIR__ = ", __DIR__, PHP_EOL;
            echo "__FILE__ = ", __FILE__, PHP_EOL;
            echo "__LINE__ = ", __LINE__, PHP_EOL;
            echo "__FUNCTION__ = ", __FUNCTION__, PHP_EOL;
            echo "__METHOD__ = ", __METHOD__, PHP_EOL;
            echo "__CLASS__ = ", __CLASS__, PHP_EOL;
            echo "__TRAIT__ = ", __TRAIT__, PHP_EOL;
            echo "__NAMESPACE__ = ", __NAMESPACE__, PHP_EOL;
            echo "MyClass::class = ", MyClass::class, PHP_EOL, PHP_EOL;
        }
    }

    $obj = new MyClass();
    $obj->myTraitFunction();
    $obj->myFunction();
    
    $sub = function() {
        echo "--- In anonymous function call ---", PHP_EOL;
        echo "__DIR__ = ", __DIR__, PHP_EOL;
        echo "__FILE__ = ", __FILE__, PHP_EOL;
        echo "__LINE__ = ", __LINE__, PHP_EOL;
        echo "__FUNCTION__ = ", __FUNCTION__, PHP_EOL;
        echo "__METHOD__ = ", __METHOD__, PHP_EOL;
        echo "__CLASS__ = ", __CLASS__, PHP_EOL;
        echo "__TRAIT__ = ", __TRAIT__, PHP_EOL;
        echo "__NAMESPACE__ = ", __NAMESPACE__, PHP_EOL;
        echo "MyClass::class = ", MyClass::class, PHP_EOL, PHP_EOL;
    };
    $sub();
    
    echo "--- In namespace top level ---", PHP_EOL;
    echo "__DIR__ = ", __DIR__, PHP_EOL;
    echo "__FILE__ = ", __FILE__, PHP_EOL;
    echo "__LINE__ = ", __LINE__, PHP_EOL;
    echo "__FUNCTION__ = ", __FUNCTION__, PHP_EOL;
    echo "__METHOD__ = ", __METHOD__, PHP_EOL;
    echo "__CLASS__ = ", __CLASS__, PHP_EOL;
    echo "__TRAIT__ = ", __TRAIT__, PHP_EOL;
    echo "__NAMESPACE__ = ", __NAMESPACE__, PHP_EOL;
    echo "MyClass::class = ", MyClass::class, PHP_EOL, PHP_EOL;
}
?>
実行結果
--- In construcror ---
__DIR__ = /workspace
__FILE__ = /workspace/Main.php
__LINE__ = 25
__FUNCTION__ = __construct
__METHOD__ = MyNamespace\MyClass::__construct
__CLASS__ = MyNamespace\MyClass
__TRAIT__ = 
__NAMESPACE__ = MyNamespace
MyClass::class = MyNamespace\MyClass

--- In trait method call ---
__DIR__ = /workspace
__FILE__ = /workspace/Main.php
__LINE__ = 9
__FUNCTION__ = myTraitFunction
__METHOD__ = MyNamespace\MyTrait::myTraitFunction
__CLASS__ = MyNamespace\MyClass
__TRAIT__ = MyNamespace\MyTrait
__NAMESPACE__ = MyNamespace
MyClass::class = MyNamespace\MyClass

--- In method call ---
__DIR__ = /workspace
__FILE__ = /workspace/Main.php
__LINE__ = 38
__FUNCTION__ = myFunction
__METHOD__ = MyNamespace\MyClass::myFunction
__CLASS__ = MyNamespace\MyClass
__TRAIT__ = 
__NAMESPACE__ = MyNamespace
MyClass::class = MyNamespace\MyClass

--- In anonymous function call ---
__DIR__ = /workspace
__FILE__ = /workspace/Main.php
__LINE__ = 56
__FUNCTION__ = MyNamespace\{closure}
__METHOD__ = MyNamespace\{closure}
__CLASS__ = 
__TRAIT__ = 
__NAMESPACE__ = MyNamespace
MyClass::class = MyNamespace\MyClass

--- In namespace top level ---
__DIR__ = /workspace
__FILE__ = /workspace/Main.php
__LINE__ = 69
__FUNCTION__ = 
__METHOD__ = 
__CLASS__ = 
__TRAIT__ = 
__NAMESPACE__ = MyNamespace
MyClass::class = MyNamespace\MyClass

その他[編集]

unset[編集]

今後に使う予定のない変数に unset() 関数を適用することで、明示的にその変数を使わないことを表明できます。 また、unset にともない、unsetした変数に占有されていたメモリ領域のリファレンスカウントが一つ減るので、メモリが開放される可能性があります。

unsetの適用後、変数を参照すると、言語処理系が警告をしてくれるので、バグなどを発見しやすくなります。

ためしに下記コード例では、unsetの適用後、変数を参照しています。

<?php
$num1 = 70;
$num2 = 12;

print $num1."<br>";

print $num2."<br>";

unset($num2);

print $num2."<br>";

?>
実行結果
70
12
Warning: Undefined variable $num2 in C:\ファイルアドレス\ファイル名.php on line 11

上記の実行結果のように、言語処理系が警告をしてくれています。unsetの仕様に反して無理やりにnum2を再使用しているので、警告をしてくれる動作のほうが、言語処理系の動作としては正常な動作結果です。

なお、C++など他の言語で類似の機能をもつ「delete」という名の文ないし関数は、PHPには存在しません[2]

null[編集]

もし、変数の再使用を禁止したいわけではなく、単にいったん変数を一時的に空(から)にしたいだけの場合、変数に null を代入します。 発音的には null は「ヌル」または「ナル」などと読みます。

<?php
$num1 = 70;
$num2 = 12;

print $num1."<br>";

print $num2."<br>";

// unset($num2);

$num2 = null;
print $num2."<br>";

$num2 = 35;
print $num2."<br>";

?>
実行結果
70
12

35

実行結果の3行目の何も表示されてない行が、null に相当します。

未定義変数[編集]

2021年の現在、最新のPHP8では、未定義(Undefined)の変数をprintしたりechoなど出力したりすると、警告文(warning)が出るようになりました(以前は通知 notice どまりだった)。実行自体は中断されずに続行しますが、あまり推奨されません。

コード例
<?php
    print $w; // これ以前のどこでも$wを定義していない
    $d = $w;  
    print "hello";
?>
実行結果
Warning: Undefined variable $w in C:\ファイルアドレス\ファイル名.php on line 2

Warning: Undefined variable $w in C:\ファイルアドレス\ファイル名.php on line 3
hello


学習者への注意

今後は上記のような未定義での変数の使用法は、ひかえるべきです。初心者は、わざわざ非推奨の未定義変数の利用をする必要がありません。

PHPの過去バージョンで、未定義変数の利用が昔は非推奨でなかった頃がありました。そのような古いバージョンとの動作互換性を当面のあいだは残しておくためなどの理由で、現状のPHP8ではまだ動作するだけにすぎないでしょう。

今後のバージョン(PHP9以降)では、もしかしたら動作すらできずにエラーになる可能性すらありえます。

通知(PHP7以前)→警告(PHP8) と、どんどんと非推奨のレベルが上がっているので、この調子で非推奨のレベルが上がっていくと、いつかは使用不可能のエラーになる可能性があります。

なので初心者は、未定義変数の利用を控えましょう。今から学習を始める初心者が、わざわざ非推奨の方法を使う必要はないのです。


なお、表示出力以外の構文や関数でも同様に、未定義変数を未定義のままで構文または関数で参照すると警告文が出ます。


なお、下記コードのように変数の前に@ アットマーク をつけることで、警告文などを非表示にすることができますが、これは単に非表示になっただけに過ぎず、大本のPHP本体の開発陣たちが未定義変数を非推奨にしていく開発方針の流れ自体は変わらないので、警告メッセージから目を背けるのではなく、変数の定義をするなどの対応をしておきましょう。なお、このようなPHPのアットマークの機能のことを「エラー制御演算子」といいます。

<?php
    print @$w; // これ以前のどこでも$wを定義していない
    $d = @$w;  
    print "hello";
?>

非表示の機能を実務で使うとするならば、たとえば、すでに過去バージョンで大きなプログラムを作ってしまった人が、他のエラーメッセージを発見しやすくするために原因の分かっている警告を非表示にするなどの用途に限定されるべきです。

なお、webブラウザで閲覧している場合には、ブラウザのログ画面を見ない限りは、一般にエラーメッセージや警告メッセージなどは出ません。なので、エラーの許されない厳しいプログラムを作る場合は、ブラウザだけでなく、コンソール端末でも動作を確認しましょう。

  1. ^ Magic constants
  2. ^ 『PHP: delete - Manual』 2021年12月7日に確認.