| この記事の要点 |
|
基本の書き方
<!DOCTYPE html>
<html lang="ja">
<body>
<h1><?php echo "こんにちは"; ?></h1>
<?php $name = "田中"; ?>
<p><?= $name ?> さん</p>
</body>
</html>
PHP タグの外側は解釈されずにそのまま出力されます。つまり PHP ファイルは「HTML の中に、必要なところだけ PHP を差し込む」形で書けます。
タグの種類
| 書き方 | 意味 | 使ってよいか |
|---|---|---|
<?php ... ?> | 標準 | これを使う |
<?= $x ?> | <?php echo $x; ?> の短縮 | 使える(PHP 5.4 以降つねに有効) |
<? ... ?> | 短縮開始タグ | 使わない(short_open_tag 依存・XML と衝突) |
<% ... %> | ASP 風タグ | PHP 7 で廃止済み |
終了タグを書かない
<?php
// functions.php — PHP コードだけのファイル
function greet(string $name): string
{
return "こんにちは {$name} さん";
}
// ここに ?> を書かない
終了タグの後ろにある改行や空白まで出力されます。それが原因で次のエラーが出ます。
Warning: Cannot modify header information - headers already sent by
(output started at /path/functions.php:12) in /path/index.php on line 3
header() や setcookie()、セッション開始は出力が 1 バイトでも始まる前に呼ぶ必要があります。詳細は Warning: Cannot modify header information を参照してください。
HTML の中で分岐・繰り返しをする
<?php $tasks = ['買い物', '掃除']; ?>
<?php if ($tasks): ?>
<ul>
<?php foreach ($tasks as $i => $task): ?>
<li><?= $i + 1 ?>. <?= htmlspecialchars($task, ENT_QUOTES, 'UTF-8') ?></li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>タスクはありません</p>
<?php endif; ?>
この : と endif; の書き方を代替構文といいます。波かっこだと HTML の中で } が散らばり、どのブロックの終わりか分からなくなるため、テンプレートでは代替構文を使うのが定石です。
| 通常の構文 | 代替構文 |
|---|---|
if (...) { } | if (...): ... endif; |
foreach (...) { } | foreach (...): ... endforeach; |
for (...) { } | for (...): ... endfor; |
while (...) { } | while (...): ... endwhile; |
switch (...) { } | switch (...): ... endswitch; |
出力するときは必ずエスケープする
<?php
$comment = '<script>alert(1)</script>'; // 利用者が入力した値
?>
<!-- 危険: スクリプトがそのまま動く -->
<p><?= $comment ?></p>
<!-- 安全: 文字として表示される -->
<p><?= htmlspecialchars($comment, ENT_QUOTES, 'UTF-8') ?></p>
短く書くためにヘルパー関数を用意しておくと、書き忘れが減ります。
function e(?string $s): string
{
return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
}
// テンプレート側
<p><?= e($comment) ?></p>
| 出力先 | 使うもの |
|---|---|
| HTML の本文・属性値 | htmlspecialchars($s, ENT_QUOTES, 'UTF-8') |
| URL のパラメータ | urlencode() / http_build_query() |
| JavaScript に渡す値 | json_encode($v, JSON_HEX_TAG | JSON_HEX_AMP) |
| SQL | プレースホルダ(PDO)。文字列連結しない |
ロジックと表示を分ける
<?php
// index.php — ここで必要なデータを揃える
require __DIR__ . '/lib/db.php';
$tasks = fetchTasks($pdo); // DB アクセスや計算はここまで
require __DIR__ . '/views/tasks.php'; // 表示は別ファイルへ
<!-- views/tasks.php — ここでは表示だけ -->
<ul>
<?php foreach ($tasks as $task): ?>
<li><?= e($task['title']) ?></li>
<?php endforeach; ?>
</ul>
表示用のファイルには echo と分岐・繰り返しだけを置きます。DB アクセスや条件計算がテンプレートに混ざると、画面を直すたびにロジックを壊す危険が出ます。フレームワークを使う場合は Bladeテンプレート のような専用の仕組みがこれを担当します。
共通部分をまとめる
<!-- views/layout/header.php -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= e($title ?? 'サイト名') ?></title>
</head>
<body>
<?php
$title = 'タスク一覧';
require __DIR__ . '/views/layout/header.php';
?>
<h1><?= e($title) ?></h1>
<?php require __DIR__ . '/views/layout/footer.php'; ?>
読み込んだファイルからは読み込み元の変数がそのまま見えます。$title のように渡したい値を、読み込む直前で用意しておくのが素朴なやり方です。
出力バッファリング
function render(string $file, array $data = []): string
{
extract($data, EXTR_SKIP);
ob_start(); // ここから先の出力をためる
require $file;
return ob_get_clean(); // ためた内容を文字列で受け取る
}
$html = render(__DIR__ . '/views/tasks.php', ['tasks' => $tasks]);
echo $html; // 加工してから出力できる
テンプレートの結果を文字列として受け取れるので、メール本文を組み立てたり、キャッシュに保存したりできます。ob_start() と ob_get_clean() は必ず対にしてください。
フォームの値を表示する
<form method="post" action="">
<input type="text" name="title"
value="<?= e($_POST['title'] ?? '') ?>">
<select name="status">
<?php foreach (['open' => '未着手', 'done' => '完了'] as $v => $label): ?>
<option value="<?= e($v) ?>"
<?= (($_POST['status'] ?? '') === $v) ? 'selected' : '' ?>>
<?= e($label) ?>
</option>
<?php endforeach; ?>
</select>
</form>
入力エラーで戻したときに値を保つには、value に $_POST の値を入れ直します。属性値の中でも必ずエスケープしてください。" がエスケープされないと、属性を抜け出して任意の属性を差し込まれます。
よくあるつまずき
| 症状 | 原因 |
|---|---|
| PHP のコードがそのまま画面に出る | 拡張子が .html/Web サーバー経由でなくファイルを直接開いている |
headers already sent | 終了タグの後ろの改行、または BOM 付きで保存している |
| 画面が真っ白 | 致命的エラー。display_errors ではなくエラーログを見る |
| 文字化けする | ファイルを UTF-8(BOM なし)で保存し、<meta charset="utf-8"> を出す |
| 変数が出ない | スコープ違い。関数の中から外の変数は見えない(スコープ) |
関連
- 文法 — 親カテゴリ
- 基本事項 — PHP タグとコメントの基本
- エスケープ文字
- シングルクォートとダブルクォートの違い
- 外部ファイルを呼び出す方法
- printとechoの違い
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38