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

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

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li>PHP は <strong><code><?php ?></code></strong> タグで囲む。短縮タグ <code><? ?></code> は非推奨</li><li><strong>文末セミコロン <code>;</code> 必須</strong>。変数は <strong><code>$name</code></strong> 形式</li><li>関数名は<strong>大文字小文字鈍感</strong>、変数名は<strong>敏感</strong> ($Name と $name は別)</li><li>シングルクォート <code>"..."</code> は変数展開しない、ダブルクォート <code>"..."</code> は変数展開する</li><li>推奨コーディング規約は <strong>PSR-12</strong>、型厳密化は <code>declare(strict_types=1);</code></li></ul></td></tr></table>
<h2>PHP ファイルの基本構造</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-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(&apos;email&apos;, $email)->first();
    }
}
// ★ 終了タグ ?> は付けない (出力が紛れ込むのを防ぐ)</code></pre>
<h2>PHP タグの種類</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>タグ</th><th>記述</th><th>推奨</th></tr></thead>
<tbody>
<tr><td>標準</td><td><code><?php ... ?></code></td><td>★ 標準</td></tr>
<tr><td>短縮 echo</td><td><code><?= $var ?></code></td><td>OK (テンプレートで多用)</td></tr>
<tr><td>短縮タグ</td><td><code><? ... ?></code></td><td>非推奨 (設定依存)</td></tr>
<tr><td>ASP 風</td><td><code><% ... %></code></td><td>PHP 7 で廃止</td></tr>
<tr><td>script タグ</td><td><code><script language="php"></code></td><td>PHP 7 で廃止</td></tr>
</tbody>
</table>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php"><!-- Blade / プレーン PHP テンプレート -->
<h1>Hello, <?= htmlspecialchars($name) ?>!</h1>

<?php foreach ($users as $user): ?>
    <li><?= $user->name ?></li>
<?php endforeach; ?></code></pre>
<h2>変数と命名規則</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">$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;</code></pre>
<p>関数名は<strong>大文字小文字を区別しない</strong>のが歴史的仕様。クラス名・名前空間は区別する。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">function greet() { return "hello"; }

greet();   // OK
Greet();   // OK (関数名は鈍感)
GREET();   // OK

class User { ... }
// USER のような呼び出しは NG (クラス名は敏感)</code></pre>
<h2>文字列リテラル: クォートの違い</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>種類</th><th>変数展開</th><th>エスケープ</th><th>速度</th></tr></thead>
<tbody>
<tr><td>シングル <code>'...'</code></td><td>×</td><td><code>\\</code> <code>\'</code> のみ</td><td>★ わずかに速い</td></tr>
<tr><td>ダブル <code>"..."</code></td><td>○ (<code>$var</code> 展開)</td><td><code>\n</code> <code>\t</code> <code>\\</code> <code>\$</code> <code>\"</code></td><td>遅い</td></tr>
<tr><td>Heredoc <code><<<TAG</code></td><td>○ (ダブル相当)</td><td>不要</td><td>同じ</td></tr>
<tr><td>Nowdoc <code><<<'TAG'</code></td><td>×</td><td>不要</td><td>同じ</td></tr>
</tbody>
</table>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">$name = "Alice";

echo &apos;Hello, $name&apos;;    // Hello, $name (展開されない)
echo "Hello, $name";    // Hello, Alice
echo "Hello, {$name}!"; // Hello, Alice! (中括弧で範囲明示)

// 配列要素・オブジェクトプロパティ
echo "{$user[&apos;name&apos;]}";  // 配列
echo "{$user->name}";    // オブジェクト

// Heredoc (ダブル相当)
$msg = <<<EOT
Hello, $name!
今日は良い天気ですね。
EOT;

// Nowdoc (シングル相当、展開なし)
$tpl = <<<&apos;EOT&apos;
$name は展開されません
\n もそのまま
EOT;</code></pre>
<h2>コメント</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">// 一行コメント (C/Java スタイル)

# 一行コメント (Perl スタイル)

/*
複数行
コメント
*/

/**
 * ★ PHPDoc コメント (IDE が型情報として解釈)
 *
 * @param string $name ユーザー名
 * @param int    $age  年齢
 * @return User
 * @throws InvalidArgumentException
 */
function createUser(string $name, int $age): User { ... }</code></pre>
<h2>declare(strict_types=1)</h2>

<p>PHP 7+ の<strong>型厳密モード</strong>。ファイルの先頭で宣言すると、関数の引数・戻り値の型変換が許されなくなります。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php"><?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 (デフォルト) は自動変換される</code></pre>
<h2>PSR-12 コーディング規約 (主要ルール)</h2>

<ul>
<li>インデントは<strong>スペース 4 つ</strong> (タブ禁止)</li>
<li>改行は<strong>LF のみ</strong> (Windows の CRLF NG)</li>
<li>ファイル末尾は<strong>空行 1 つ</strong>で終わる</li>
<li>クラス・関数の <code>{</code> は<strong>改行して次行</strong>に置く</li>
<li>制御構文の <code>{</code> は<strong>同じ行</strong></li>
<li><strong>名前空間 / use 文 の後に空行</strong></li>
<li><strong>クラス名 PascalCase</strong>, <strong>メソッド・変数 camelCase</strong>, <strong>定数 SNAKE_UPPER</strong></li>
<li>PHP 終了タグ <code>?></code> は<strong>PHP のみのファイルでは付けない</strong></li>
</ul>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-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(&apos;limit must be positive&apos;);
        }

        return $this->repo->findActive($limit);
    }
}</code></pre>
<h2>制御構文</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">// 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 &apos;active&apos;:
        echo "active";
        break;
    case &apos;pending&apos;:
    case &apos;review&apos;:
        echo "in progress";
        break;
    default:
        echo "?";
}

// match 式 (PHP 8+)
$label = match (true) {
    $score >= 90 => &apos;A&apos;,
    $score >= 80 => &apos;B&apos;,
    $score >= 70 => &apos;C&apos;,
    default      => &apos;F&apos;,
};

// ループ
for ($i = 0; $i < 10; $i++) { ... }
foreach ($users as $user) { ... }
foreach ($users as $i => $user) { ... }
while ($cond) { ... }
do { ... } while ($cond);</code></pre>
<h2>PHP 8.x の主な新機能</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#fff3e0"><th>バージョン</th><th>機能</th></tr></thead>
<tbody>
<tr><td>8.0</td><td>名前付き引数、コンストラクタプロパティ昇格、union 型、match 式、nullsafe <code>?-></code>、JIT</td></tr>
<tr><td>8.1</td><td>enum、readonly プロパティ、never 戻り値、Fiber、配列アンパック with string キー</td></tr>
<tr><td>8.2</td><td>readonly クラス、disjunctive normal form 型、null/false/true 型</td></tr>
<tr><td>8.3</td><td>typed class constants、<code>#[\Override]</code> アノテーション</td></tr>
<tr><td>8.4</td><td>property hooks、asymmetric visibility、new MyClass()->method() (新インスタンスの即時メソッド呼び)</td></tr>
</tbody>
</table>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">// 名前付き引数 (PHP 8.0+)
createUser(name: &apos;Alice&apos;, 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 = &apos;active&apos;;
    case Inactive = &apos;inactive&apos;;

    public function label(): string {
        return match($this) {
            Status::Active => &apos;有効&apos;,
            Status::Inactive => &apos;無効&apos;,
        };
    }
}

// nullsafe (PHP 8.0+)
$country = $user?->address?->country?->name;</code></pre>
<h2>FAQ</h2>

<p><strong>Q: <code>?></code> は必要?</strong><br />
A: PHP のみのファイルでは<strong>付けない</strong>のがベストプラクティス。末尾に余計な改行や空白が混じると HTTP ヘッダ送信前に出力されてしまうため。</p>

<p><strong>Q: シングルとダブル、どちらを使う?</strong><br />
A: <strong>変数展開しないならシングル</strong>が原則。<code>"hello"</code> と <code>'hello'</code> の性能差はマイクロ最適化レベルですが、明確に意図が伝わるのでシングル推奨。</p>

<p><strong>Q: <code>declare(strict_types=1)</code> は必須?</strong><br />
A: 新規プロジェクトでは<strong>付けるべき</strong>。型変換による潜在バグを防げます。既存コードへ後付けすると影響大なので段階的に。</p>