この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:8
ページ更新者:guest
更新日時:2026-06-11 07:10:02

タイトル: 基本的なルール
SEOタイトル: PHP 基本構文ルール完全ガイド (PSR-12 / strict_types / クォート)

この記事の要点
  • PHP は <?php ?> タグで囲む。短縮タグ <? ?> は非推奨
  • 文末セミコロン ; 必須。変数は $name 形式
  • 関数名は大文字小文字鈍感、変数名は敏感 ($Name と $name は別)
  • シングルクォート "..." は変数展開しない、ダブルクォート "..." は変数展開する
  • 推奨コーディング規約は PSR-12、型厳密化は declare(strict_types=1);

PHP ファイルの基本構造

<?php
declare(strict_types=1);   // 型厳密化 (推奨)

namespace App\Services;

use App\Models\User;
use App\Exceptions\NotFoundException;

class UserService
{
    public function findByEmail(string $email): ?User
    {
        return User::where('email', $email)->first();
    }
}
// ★ 終了タグ ?> は付けない (出力が紛れ込むのを防ぐ)

PHP タグの種類

タグ記述推奨
標準<?php ... ?>★ 標準
短縮 echo<?= $var ?>OK (テンプレートで多用)
短縮タグ<? ... ?>非推奨 (設定依存)
ASP 風<% ... %>PHP 7 で廃止
script タグ<script language="php">PHP 7 で廃止
<!-- Blade / プレーン PHP テンプレート -->
<h1>Hello, <?= htmlspecialchars($name) ?>!</h1>

<?php foreach ($users as $user): ?>
    <li><?= $user->name ?></li>
<?php endforeach; ?>

変数と命名規則

$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 <<<TAG○ (ダブル相当)不要同じ
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 = <<<EOT
Hello, $name!
今日は良い天気ですね。
EOT;

// Nowdoc (シングル相当、展開なし)
$tpl = <<<'EOT'
$name は展開されません
\n もそのまま
EOT;

コメント

// 一行コメント (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+ の型厳密モード。ファイルの先頭で宣言すると、関数の引数・戻り値の型変換が許されなくなります。

<?php
declare(strict_types=1);  // ★ ファイル先頭でのみ有効

function add(int $a, int $b): int {
    return $a + $b;
}

add(1, 2);        // 3
add("1", 2);      // ❌ TypeError (strict なしなら 3 になる)
add(1.5, 2);      // ❌ TypeError

// strict_types=0 (デフォルト) は自動変換される

PSR-12 コーディング規約 (主要ルール)

  • インデントはスペース 4 つ (タブ禁止)
  • 改行はLF のみ (Windows の CRLF NG)
  • ファイル末尾は空行 1 つで終わる
  • クラス・関数の {改行して次行に置く
  • 制御構文の {同じ行
  • 名前空間 / use 文 の後に空行
  • クラス名 PascalCase, メソッド・変数 camelCase, 定数 SNAKE_UPPER
  • PHP 終了タグ ?>PHP のみのファイルでは付けない
<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\User;
use App\Repositories\UserRepository;

class UserService
{
    public function __construct(
        private readonly UserRepository $repo,
    ) {}

    public function findActiveUsers(int $limit = 10): array
    {
        if ($limit <= 0) {
            throw new \InvalidArgumentException('limit must be positive');
        }

        return $this->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.1enum、readonly プロパティ、never 戻り値、Fiber、配列アンパック with string キー
8.2readonly クラス、disjunctive normal form 型、null/false/true 型
8.3typed class constants、#[\Override] アノテーション
8.4property 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: 新規プロジェクトでは付けるべき。型変換による潜在バグを防げます。既存コードへ後付けすると影響大なので段階的に。