1.

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: 新規プロジェクトでは付けるべき。型変換による潜在バグを防げます。既存コードへ後付けすると影響大なので段階的に。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 基本的なルール
  2. 変数
  3. 演算子
  4. 標準ライブラリ
  5. 外部ライブラリ
  6. 制御構文
  7. リスト(配列)
  8. タプル
  9. セット
  10. 辞書(dict)
  11. クラスとメソッド
  12. 継承の概念と必要性
  13. 継承の構文
  14. コンストラクタ
  15. cookieの値の設定と取得
  16. 例外処理
  17. 例外を文字列で出力する方法
  18. httpリクエスト(curl)をする方法
  19. Responseオブジェクトの中身の確認
  20. 変数が空かどうか判定する方法
  21. タイムゾーンの設定と現在日時の取得と文字列化
  22. シングルクォーテーションとダブルクォーテーションの違い

最近更新/作成されたページ