タイトル: 基本的なルール
SEOタイトル: PHP 基本構文ルール完全ガイド (PSR-12 / strict_types / クォート)
| この記事の要点 |
|
PHP ファイルの基本構造
first();
}
}
// ★ 終了タグ ?> は付けない (出力が紛れ込むのを防ぐ)
PHP タグの種類
| タグ | 記述 | 推奨 |
|---|---|---|
| 標準 | | ★ 標準 |
| 短縮 echo | = $var ?> | OK (テンプレートで多用) |
| 短縮タグ | ... ?> | 非推奨 (設定依存) |
| ASP 風 | <% ... %> | PHP 7 で廃止 |
| script タグ | | PHP 7 で廃止 |
Hello, = htmlspecialchars($name) ?>!
= $user->name ?>
変数と命名規則
$name = "Alice"; // 変数は $ 始まり
$user_id = 1; // _ で区切る (snake_case)
$isAdmin = true; // PSR-12 は camelCase 推奨
// ❌ 数字始まりは NG
// $1abc = "x";
// 大文字小文字は区別される
$Name = "Bob";
echo $name; // "Alice"
echo $Name; // "Bob"
// 定数
const APP_VERSION = "1.0";
define("PI", 3.14);
// クラスの定数
class Status {
public const ACTIVE = 1;
public const INACTIVE = 0;
}
Status::ACTIVE;
関数名は大文字小文字を区別しないのが歴史的仕様。クラス名・名前空間は区別する。
function greet() { return "hello"; }
greet(); // OK
Greet(); // OK (関数名は鈍感)
GREET(); // OK
class User { ... }
// USER のような呼び出しは NG (クラス名は敏感)
文字列リテラル: クォートの違い
| 種類 | 変数展開 | エスケープ | 速度 |
|---|---|---|---|
シングル '...' | × | \\ \' のみ | ★ わずかに速い |
ダブル "..." | ○ ($var 展開) | \n \t \\ \$ \" | 遅い |
Heredoc << | ○ (ダブル相当) | 不要 | 同じ |
Nowdoc <<<'TAG' | × | 不要 | 同じ |
$name = "Alice";
echo 'Hello, $name'; // Hello, $name (展開されない)
echo "Hello, $name"; // Hello, Alice
echo "Hello, {$name}!"; // Hello, Alice! (中括弧で範囲明示)
// 配列要素・オブジェクトプロパティ
echo "{$user['name']}"; // 配列
echo "{$user->name}"; // オブジェクト
// Heredoc (ダブル相当)
$msg = <<
コメント
// 一行コメント (C/Java スタイル)
# 一行コメント (Perl スタイル)
/*
複数行
コメント
*/
/**
* ★ PHPDoc コメント (IDE が型情報として解釈)
*
* @param string $name ユーザー名
* @param int $age 年齢
* @return User
* @throws InvalidArgumentException
*/
function createUser(string $name, int $age): User { ... }
declare(strict_types=1)
PHP 7+ の型厳密モード。ファイルの先頭で宣言すると、関数の引数・戻り値の型変換が許されなくなります。
PSR-12 コーディング規約 (主要ルール)
- インデントはスペース 4 つ (タブ禁止)
- 改行はLF のみ (Windows の CRLF NG)
- ファイル末尾は空行 1 つで終わる
- クラス・関数の
{は改行して次行に置く - 制御構文の
{は同じ行 - 名前空間 / use 文 の後に空行
- クラス名 PascalCase, メソッド・変数 camelCase, 定数 SNAKE_UPPER
- PHP 終了タグ
?>はPHP のみのファイルでは付けない
repo->findActive($limit);
}
}
制御構文
// if / elseif / else
if ($x > 10) {
echo "big";
} elseif ($x > 0) {
echo "small";
} else {
echo "zero or negative";
}
// 代替構文 (テンプレートで便利)
if ($x > 10): echo "big"; elseif ($x > 0): echo "small"; else: echo "zero"; endif;
// switch
switch ($status) {
case 'active':
echo "active";
break;
case 'pending':
case 'review':
echo "in progress";
break;
default:
echo "?";
}
// match 式 (PHP 8+)
$label = match (true) {
$score >= 90 => 'A',
$score >= 80 => 'B',
$score >= 70 => 'C',
default => 'F',
};
// ループ
for ($i = 0; $i < 10; $i++) { ... }
foreach ($users as $user) { ... }
foreach ($users as $i => $user) { ... }
while ($cond) { ... }
do { ... } while ($cond);
PHP 8.x の主な新機能
| バージョン | 機能 |
|---|---|
| 8.0 | 名前付き引数、コンストラクタプロパティ昇格、union 型、match 式、nullsafe ?->、JIT |
| 8.1 | enum、readonly プロパティ、never 戻り値、Fiber、配列アンパック with string キー |
| 8.2 | readonly クラス、disjunctive normal form 型、null/false/true 型 |
| 8.3 | typed class constants、#[\Override] アノテーション |
| 8.4 | property hooks、asymmetric visibility、new MyClass()->method() (新インスタンスの即時メソッド呼び) |
// 名前付き引数 (PHP 8.0+)
createUser(name: 'Alice', age: 25, isAdmin: true);
// コンストラクタプロパティ昇格 (PHP 8.0+)
class Point {
public function __construct(
public readonly float $x,
public readonly float $y,
) {}
}
// enum (PHP 8.1+)
enum Status: string {
case Active = 'active';
case Inactive = 'inactive';
public function label(): string {
return match($this) {
Status::Active => '有効',
Status::Inactive => '無効',
};
}
}
// nullsafe (PHP 8.0+)
$country = $user?->address?->country?->name;
FAQ
Q: ?> は必要?
A: PHP のみのファイルでは付けないのがベストプラクティス。末尾に余計な改行や空白が混じると HTTP ヘッダ送信前に出力されてしまうため。
Q: シングルとダブル、どちらを使う?
A: 変数展開しないならシングルが原則。"hello" と 'hello' の性能差はマイクロ最適化レベルですが、明確に意図が伝わるのでシングル推奨。
Q: declare(strict_types=1) は必須?
A: 新規プロジェクトでは付けるべき。型変換による潜在バグを防げます。既存コードへ後付けすると影響大なので段階的に。