変数は、値に名前をつけてプログラム中から参照できるようにする仕組みです。
変数は必ず名前を持ち、名前は識別子のルールに従います。
変数の名前は、$ で始まり識別子が続きます。
識別子は、先頭が  _  または英字、それに 0 文字以上の _ または 英数字が続きます。
有効な変数
無効な変数
また、PHPでは、変数名の大文字小文字を区別します。
 $name  $NAME  $Name  $namE  $nAME
はすべて違う変数です。
関数、ラベル、定数、クラス、トレイト、インターフェース、名前空間なども名前を持つことができますが、それぞれ識別子の規則に従います。
変数を使ったプログラム。
例:
実行結果:
99
上記コードは変数 $a に値 99を代入し、それをecho文によって表示するプログラムです。
このように変数は、文字列を入れることもできます。
PHPでは、変数は宣言する必要はありません（できません）。強いて言うなら、最初の代入が変数のスコープのはじまりという意味で宣言に相当します。
引用符の中での変数の埋込み
ほかの例も下記に見ていきましょう。
例:
実行結果:
挨拶 : こんにちは
このように、引用符の中に変数を埋め込むことができます。
$aを{}で囲んでいるのは、分かち書きされていないと変数名を正しくparseできないからです。
例:
>
実行結果:
7 is answer
これは、変数の文字列への埋込み機能を使うと次のようにも書けます。
例:
>
{$a}が答えです。と{ }（波括弧）で囲います。
print は上位互換で短縮表記もある echo があるので殆ど使われませんが、Cのprintf()/sprintf()と同じ機能の、 printf()/sprintf()がPHPにはあり、書式化出力に便利です。
printf():
sprintf():
実行結果:
7 is answer
sprintf()は、標準出力に書き出すのではなく、文字列を返します。
Cのsprintf()と違いバッファの管理は処理系が行ってくれるので、バッファオーバーランを気にしなくても良いのがメリットです。
PHPでは他のプログラミング言語同様、数学風の演算子式で計算を行います。
[https://paiza.io/projects/Vs-8ESGbNjQewkY7SkzjFQ?language=php 例]:
 ", $x + $y, PHP_EOL;
echo "$x - $y --> ", $x - $y, PHP_EOL;
echo "$x * $y --> ", $x * $y, PHP_EOL;
echo "$x / $y --> ", $x / $y, PHP_EOL;
echo "intdiv($x, $y) --> ", intdiv($x, $y), PHP_EOL;
echo "$x % $y --> ", $x % $y, PHP_EOL;
?>
実行結果:
11 + 7 --> 18
11 - 7 --> 4
11 * 7 --> 77
11 / 7 --> 1.5714285714286
intdiv(11, 7) --> 1 
11 % 7 --> 4
PHPの /（除算）の結果は浮動小数点数です。
整数の範囲で割り算をしたい場合には、PHP7以降ではintdiv() 関数を使うことで実現できます。
PHP7以前でも、小数点斬り捨ての関数 floor()などで、割り算の整数値を求められます。
負数の丸め方向には特に注意が必要です。
例:
実行結果:
1.5714285714286
という浮動小数点数です。
整数除算は、intdiv(被除数, 除数) です
intdiv():
実行結果:
5
まとめ
+, -, *, /, %のような演算を表す記号を演算子とよびます（これらは二項演算子（中置演算子とも））。
それに対し、intdiv()のような形式は関数と呼びます。
とはいうものの、PHPは、演算子・関数・コマンドの区別が曖昧で、公式のドキュメントでも混用が見られます。
なにか型ジャグリングと通じるものがありますね。
PHPも、多くのプログラミング言語と同じく演算子に優先順位があります。
 1 + 2 * 3
は
 ( 1 + 2 ) * 3
ではなく
 1 + ( 2 * 3 )
の順で評価されます（それぞれの演算子の優先順位については、後ほど表にまとめます）。
異なる優先順位の演算子であれば、優先順位に従い評価すればよいのですが、同じ優先順位の演算子が続いた場合はどうでしょう。
 1 + 2 + 3
…これは交換則が成り立つので良い例ではないですね。
 1 - 2 - 3
は
 1 - ( 2 - 3 )
ではなく
 ( 1 - 2 ) - 3
の順で評価されます。このような評価順序の演算子を左結合の演算子と呼びます。
演算子は概ね左結合ですが、少数の例外があります。
 $a = $b = 42;
これ（代入演算子）は、
 $a = ( $b = 42 );
の順（右結合）で評価されます。
また、
 2 ** 3 ** 4
（冪乗演算子）も
 2 ** ( 3 ** 4 ）
の順（右結合）で評価されます。
リテラルとは、ハードコードされた値のことです。リテラルはスクリプトの中で特定の値を表現する手段となります。例えば代入の右辺には次のようなものがあります。
[https://paiza.io/projects/e7yqBTBmEUw1XJJNToL6qw?language=php 文字リテラルの例]:
実行結果:
string(13) "a fixed value"
リテラルにはいくつかの種類があります。最も一般的なのは文字列リテラルですが、他にも整数や浮動小数点のリテラル、論理値のリテラル、配列や連想配列のリテラルなどがあります。
[https://paiza.io/projects/0IHxdpnQ0PhskS2e1gahKg?language=php 連想配列リテラルの例]:
 'value',
  'anotherName' => 'anotherValue',
];
var_export($myHash);
?>
実行結果:
array (
  'name' => 'value',
  'anotherName' => 'anotherValue', 
)
PHPの型と型名とリテラルの例を示します。
PHPには、$で始まる変数とは別に、イミュータブルなオブジェクト＝定数を宣言することができます。
[https://paiza.io/projects/sjCA27ERj4YfyATgn3AqQQ?language=php 例]:
実行結果:
a = 42
定数は変数と違い $ を前置しません。
定数への代入（エラーになります）:
エラー:
PHP Parse error:  syntax error, unexpected token "=" in /workspace/Main.php on line 6
このように、定数への代入はパース時に構文エラーになります。
また変数と定数は名前空間が異なるので、同じ名前の変数と定数があっても問題ありません。
組込み関数 define() を使っても定義できますが
PHP 8.0.0 以降では無効。この機能を使っていたプログラムはPHP 8.0.0 以降では動きません。
というバグ級の仕様上の問題（8.0.0で一部是正）があります。
const が使えるのであれば、define()は使うべきではありません。
あえて define() を使うべきケース
const では、クラスのインスタンスを定数にできません（8.1.13時点で、コンパイル時に確定している値しか定数にできません）。
例えば、複素数型の定数として虚数単位 i を定義したい場合困ります。
function i() { return new Complex(0, 1); }でも良い気がしますが、毎回インスタンスが新たに作られるので、 === が思ったように機能しません。
const と似た仕組みに、PHP 8.1.0 以降のクラスのプロパティのreadonly修飾子があります。
ただし、readonly修飾子はプロパティにしか使えません。
また、クラスはクラススコープの定数「クラス定数」を定義することができます。
PHPには9つのマジカル定数( ''Magic constants'' )があり、それらは使用される場所によって変化します[https://www.php.net/manual/en/language.constants.magic.php Magic constants]。
たとえば、__LINE__ の値は、スクリプトのどの行で使用されるかに依存します。
これらの「魔法の」定数は、実行時に解決される通常の定数とは異なり、すべてコンパイル時に解決されます。
これらの特殊な定数は大文字と小文字を区別しません。
[https://paiza.io/projects/sSkHLuno23Iy3ebTizPUgA?language=php 例]:
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の適用後、変数を参照しています。
例:
実行結果:
70
12
PHP Warning:  Undefined variable $m in /workspace/Main.php on line 10
PHP Warning:  Undefined variable $x in /workspace/Main.php on line 11
unset() された $m は、存在しない変数 $x と同じ挙動をします。
unset($x) しても何も起こりません。
PHPでは、ループ変数のスコープはループではなく関数スコープ（あるいはグローバルスコープ）なので、ループを抜けたあと悪さをしないように、unset() しましょう（ループから脱走したリファレンスを使って代入すると発見困難なバグになります）。
ドメインによっては、 $ループ変数 = null; で標準化していることもありますが趣旨は同じです。
null は、変数の束縛を解く時につかわれ、その意味では unset() と似ています。
NULLが入った変数は、isset()はfalseを返します。
[https://paiza.io/projects/4jdDNxzV1rFFKirNkjqaow?language=php 例]:
 ', var_export($n, true), PHP_EOL;
echo 'var_export($m, true) --> ', var_export($m, true), PHP_EOL;
$m = null;
echo '$m = null;', PHP_EOL;
echo 'var_export($m, true) --> ', var_export($m, true), PHP_EOL;
echo 'var_export(isset($m), true) --> ', var_export(isset($m), true), PHP_EOL;
echo 'var_export(isset($n), true) --> ', var_export(isset($n), true), PHP_EOL;
echo 'var_export($n ?? "no", true) --> ', var_export($n ?? "no", true), PHP_EOL;
echo 'var_export($m ?? "no", true) --> ', var_export($m ?? "no", true), PHP_EOL;
実行結果:
var_export($n, true) --> 70
var_export($m, true) --> 12
$m = null;
var_export($m, true) --> NULL
var_export(isset($m), true) --> false
var_export(isset($n), true) --> true
var_export($n ?? "no", true) --> 70
var_export($m ?? "no", true) --> 'no'
var_export(）は与えられた式を、PHPのリテラルの形式にします。
nullは、大文字小文字を区別しません。
??は、NULL合体演算子です。式１ ?? 式２は、isset(式１) ? 式１ : 式２と同じ意味です。v7.0から導入されました。
2022年12月現在の最新の安定バージョン v8.1.13 では、未定義（Undefined）の変数参照すると警告( ''Warning'' )が出ます。
例:
実行結果:
PHP Warning:  Undefined variable $w in /workspace/Main.php on line 2
PHP Warning:  Undefined variable $w in /workspace/Main.php on line 3
hello
意図的に未定義変数を参照することはありえません。
未定義変数の参照が起こるときは、概ねミススペルが原因です。
未定義変数の参照に関する警告を、エラー制御演算子(@)で回避するのは間違いです。未定義となった原因を排除するか、適切な初期値を与えましょう。
エラー制御演算子(@)は、名前と機能がやや乖離していて、「メッセージ抑制演算子」程度の機能しかありません。
エラー制御演算子には、トラブルシューティングに役立つエラーや警告を表示させないという害悪があるので、他の方法（例えば例外処理）を検討するべきです。
例:
実行結果:
PHP Warning:  file(/noexist): Failed to open stream: No such file or directory in /workspace/Main.php on line 2
2:file(/noexist): Failed to open stream: No such file or directory 
3:file(/noexist): Failed to open stream: No such file or directory