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

タイトル: シングルクォートとダブルクォートの違い
SEOタイトル: PHP シングルクォート/ダブルクォート違い完全ガイド (変数展開/エスケープ/ヒアドキュメント)

この記事の要点
  • シングルクォート '…': 変数展開なし。エスケープは \\\' のみ
  • ダブルクォート "…": $var{$obj->prop} を展開。\n / \t / \xNN も解釈
  • ヒアドキュメント <<<EOT: ダブルクォート相当。Nowdoc <<<'EOT': シングル相当
  • 速度差は実用上ほぼ無視可能。可読性SQL Injection 対策で選ぶ
  • JS のテンプレートリテラル `${var}` は PHP のダブルクォート展開に近い

結論: 使い分けの基本

$name = 'Taro';

// シングル: 変数展開しない (リテラル)
echo 'Hello, $name';        // → Hello, $name

// ダブル: 変数展開する
echo "Hello, $name";        // → Hello, Taro
echo "Hello, {$name}さん";   // → Hello, Taroさん

// 改行コード等のエスケープ
echo 'foo\nbar';            // → foo\nbar (リテラル)
echo "foo\nbar";            // → foo[改行]bar

違いを一覧で確認

項目シングル '…'ダブル "…"
変数展開 ($var)
配列展開 ($arr[0])
オブジェクト展開 ($obj->p)
\n \t \r❌ そのまま✅ 改行/タブ等
\xNN \uNNNN
\\ (バックスラッシュ)
\' (クォート)そのまま
\"そのまま

エスケープシーケンス詳細

// シングルクォートで認識される唯一のエスケープ
echo 'I\'m a programmer';          // I'm a programmer
echo 'C:\\Users\\Taro';            // C:\Users\Taro
echo 'foo\nbar';                   // foo\nbar (文字列リテラル)

// ダブルクォートで認識されるエスケープ
echo "line1\nline2";               // 改行
echo "col1\tcol2";                 // タブ
echo "\$price = 100";              // $price = 100 (リテラル)
echo "Hex: \x41";                  // Hex: A (0x41 = 'A')
echo "Unicode: \u{3042}";          // Unicode: あ (PHP 7+)
echo "Octal: \101";                // Octal: A

変数展開の構文

$user = ['name' => 'Taro', 'age' => 30];
$obj = (object)['title' => 'Engineer'];

// シンプル変数 (中括弧不要)
echo "Hello $user";          // 配列を文字列化しようとして Warning

// 配列要素
echo "Name: $user[name]";    // OK (角括弧内はクォート不要)
echo "Name: {$user['name']}"; // ✅ 推奨 (クォート可)

// オブジェクトプロパティ
echo "Job: $obj->title";     // OK
echo "Job: {$obj->title}";   // ✅ 推奨

// メソッド呼び出し (中括弧必須)
echo "Upper: {$obj->getTitle()}";

// 文字列と直結する場合
$word = "test";
echo "$wordABC";             // ❌ $wordABC という変数を探す → 未定義
echo "{$word}ABC";           // ✅ testABC

ヒアドキュメントと Nowdoc

複数行文字列を書くときは ヒアドキュメント (ダブル相当) と Nowdoc (シングル相当) が便利:

$name = 'Taro';

// ヒアドキュメント (変数展開あり)
$html = <<<EOT
<div>
    Hello, $name さん!
    今日は {$today} です。
</div>
EOT;

// Nowdoc (変数展開なし、識別子をクォート)
$sql = <<<'SQL'
SELECT *
FROM users
WHERE name = '$name'   -- リテラルの $name 文字列
SQL;

// PHP 7.3+ 終了識別子のインデント可
function template(): string {
    return <<<EOT
        Hello
        World
        EOT;  // ← この空白分が削除される
}

性能差はあるか?

「シングルクォートの方が速い」とよく言われますが、現代の PHP (7+) では 差はほぼ無視できるレベルです。可読性とエスケープミス防止で選んでください。

// マイクロベンチマーク (PHP 8.3, 1000 万回)
// 'plain string'    : 0.31s
// "plain string"    : 0.32s   (差はほぼなし)
// "with $var"       : 0.45s   (展開コストあり)
// 'pre' . $var      : 0.42s   (連結)
// "pre {$var}"      : 0.46s   (中括弧展開)

// 結論: マイクロ最適化は不要。可読性優先で OK

SQL Injection とクォート

クォートの違いを理解していないと SQL Injection を作り込みます:

// ❌ 危険: ダブルクォートで変数展開
$id = $_GET['id'];  // "1 OR 1=1"
$sql = "SELECT * FROM users WHERE id = $id";
// → SELECT * FROM users WHERE id = 1 OR 1=1

// ✅ プリペアドステートメント (PDO)
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);

// ✅ Eloquent (Laravel)
User::where('id', $id)->first();

JavaScript との比較

言語シングルダブル変数展開
PHPリテラル変数展開ありダブル / ヒアドキュメント
JavaScript区別なし区別なしテンプレートリテラル `${var}`
Python区別なし区別なしf-string f"{var}"
Rubyリテラル寄り変数展開ありダブル "#{var}"

FAQ

Q: チーム規約でどちらを推奨すべき?
A: PSR-12 では明示的な規定はありませんが、Symfony / Laravel コードは 変数展開が必要なときだけダブルを使う傾向。基本シングルを推奨します。

Q: ダブルクォート内の $ をリテラルにしたい
A: \$ でエスケープ。例: "\$price = $price"

Q: HTML 属性が多くてダブルクォート地獄
A: シングルの中にダブルが書けるので '<a href="...">' が楽。または sprintf やヒアドキュメントを使う。