PHPとは
PHPは、Webサーバー上で動くプログラミング言語です。HTMLだけでは毎回同じ内容を表示しますが、PHPを使うと日時やユーザーの入力、データベースの内容などに応じてページを作れます。
- お問い合わせフォームの受け付け
- ログイン機能や会員ページの作成
- ブログや商品のデータ管理
- JSONを返すWeb APIの作成
ブラウザが受け取るのはPHPのコードそのものではなく、PHPを実行した後のHTMLです。
PHPを実行してみよう
PHPを実行できる環境を用意し、作業フォルダーに hello.php を作ります。最初のプログラムを書いてみましょう。
<?php
echo "こんにちは、PHP!";
?>
開発用サーバーは、ターミナルでファイルのあるフォルダーへ移動して次のコマンドで起動できます。
php -S localhost:8000
ブラウザで http://localhost:8000/hello.php を開き、「こんにちは、PHP!」と表示されたら成功です。
基本の書き方
PHPタグと文
PHPの処理は <?php から始めます。文の終わりにはセミコロン(;)を書きます。PHPだけのファイルでは、末尾の ?> は省略するのが一般的です。
<?php
echo "1行目";
echo "2行目";
コメント
コメントはプログラムとして実行されないメモです。目的や判断理由を残すと、後からコードを読みやすくなります。
// 1行のコメント
# この形式も1行コメント
/*
複数行のコメント
*/
HTMLに埋め込む
<h1><?= htmlspecialchars($title, ENT_QUOTES, 'UTF-8') ?></h1>
<p>今日は <?= date('Y年m月d日') ?> です。</p>
変数とデータ型
変数は値に名前を付けて保存する箱です。名前は $ で始め、大文字と小文字は区別されます。
$name = "Mity"; // 文字列 string
$age = 20; // 整数 int
$height = 170.5; // 小数 float
$isStudent = true; // 真偽値 bool
$memo = null; // 値がない null
echo "{$name}さんは{$age}歳です。";
値の型を確認するときは var_dump() が便利です。文字列の連結にはピリオド(.)を使います。
var_dump($age);
echo $name . "さん、こんにちは";
$a より $userName のほうが役割を理解しやすくなります。演算子
演算子を使うと、計算・比較・条件の組み合わせができます。
| 種類 | 演算子 | 例 |
|---|---|---|
| 算術 | + - * / % | $price * $count |
| 比較 | === !== > < >= <= | $age >= 18 |
| 論理 | && || ! | $isMember && $hasTicket |
| 代入 | = += -= *= /= | $total += 100 |
$price = 500;
$count = 3;
$total = $price * $count;
echo "合計は{$total}円です。";
=== と !== を基本にすると、意図しない型変換を避けやすくなります。条件分岐
if を使うと、条件に応じて処理を切り替えられます。
$score = 82;
if ($score >= 80) {
echo "合格です。よくできました!";
} elseif ($score >= 60) {
echo "合格です。";
} else {
echo "もう一度挑戦しましょう。";
}
ひとつの値を複数の候補と比較するときは match も便利です。
match 式はPHP 8.0以降で利用できます。PHP 7系では構文エラーになるため、実行前に php -v でバージョンを確認してください。$day = 1;
$dayName = match ($day) {
1 => '月曜日',
2 => '火曜日',
3 => '水曜日',
default => 'その他',
};
echo $dayName;
繰り返し
同じ処理を何度も行うときは、for や while を使います。配列には foreach が適しています。
for ($i = 1; $i <= 5; $i++) {
echo "{$i}回目<br>";
}
$count = 3;
while ($count > 0) {
echo $count . "<br>";
$count--;
}
echo "スタート!";
配列
配列には複数の値をまとめて保存できます。番号で取り出す「添字配列」と、名前をキーにする「連想配列」があります。
$fruits = ['りんご', 'みかん', 'ぶどう'];
$fruits[] = 'もも';
foreach ($fruits as $fruit) {
echo $fruit . "<br>";
}
$user = [
'name' => 'Mity',
'age' => 20,
'city' => '東京',
];
echo $user['name'];
foreach ($user as $key => $value) {
echo "{$key}: {$value}<br>";
}
count() で要素数を数え、sort() で並べ替え、array_map() で各要素を変換できます。
$scores = [72, 95, 81];
sort($scores); // 元の配列を昇順に並べ替える
$doubled = array_map(
fn (int $score): int => $score * 2,
$scores
);
print_r($scores); // [72, 81, 95]
print_r($doubled); // [144, 162, 190]
sort() は元の配列を書き換えます。array_map() は変換後の新しい配列を返します。関数
関数は、まとまった処理に名前を付けて再利用する仕組みです。引数で値を受け取り、return で結果を返せます。
function calculateTotal(int $price, int $count): int
{
return $price * $count;
}
$total = calculateTotal(500, 3);
echo "合計は{$total}円です。";
int の部分は型宣言です。受け取る値と返す値の種類を明確にでき、間違いを見つけやすくなります。
- 関数名から目的がわかるようにする
- ひとつの関数にはひとつの役割を持たせる
- 同じ処理を繰り返し書かず、関数にまとめる
フォームの値を受け取る
HTMLフォームから送信された値は、GETなら $_GET、POSTなら $_POST で受け取ります。
<form method="post">
<label>
お名前
<input type="text" name="name" required>
</label>
<button type="submit">送信</button>
</form>
<?php
$name = trim((string) ($_POST['name'] ?? ''));
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($name === '') {
echo '<p>名前を入力してください。</p>';
} else {
echo '<p>こんにちは、'
. htmlspecialchars($name, ENT_QUOTES, 'UTF-8')
. 'さん!</p>';
}
}
?>
htmlspecialchars() でエスケープし、XSSを防ぎます。入力値をそのまま信用しないことが大切です。クラスとオブジェクト
クラスは、データとそのデータを扱う処理をひとまとめにした設計図です。new でオブジェクトを作ります。
class User
{
public function __construct(
private string $name,
private int $age
) {
}
public function introduce(): string
{
return "{$this->name}、{$this->age}歳です。";
}
}
$user = new User('Mity', 20);
echo $user->introduce();
public はクラスの外から利用できること、private はクラスの中だけで利用できることを表します。
発展機能の入口
小さなWebアプリを安全に作り、ライブラリやデータベースを使うために知っておきたい機能を紹介します。ここでは全体像をつかみ、必要になった項目から詳しく学びましょう。
例外処理(try-catch)
処理を続けられない問題が起きたとき、例外を投げて呼び出し側で処理できます。PDOによるデータベース操作でも使う重要な仕組みです。
$age = -5; // 実際にはフォームなどから受け取った値
try {
if ($age < 0) {
throw new InvalidArgumentException('年齢が不正です');
}
echo '登録しました';
} catch (InvalidArgumentException $e) {
echo htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
}
この例では動作を確認しやすいように $age へ負の値を直接代入しています。実際のアプリでは、フォームなどから受け取った値を検証してから使用します。
名前空間(namespace)
名前空間は、同じ名前のクラスが衝突しないように分類する仕組みです。Composerの自動読み込みやフレームワークを理解する土台になります。
namespace App\Service;
class Mailer
{
public function send(): void
{
// メール送信処理
}
}
JSONとWeb API
json_encode() でPHPの配列をJSONへ変換できます。JSONを返すときはContent-Typeも指定します。
header('Content-Type: application/json; charset=UTF-8');
$data = ['name' => 'Mity', 'status' => 'ok'];
echo json_encode($data, JSON_UNESCAPED_UNICODE);
受け取ったJSON文字列は json_decode($json, true) で連想配列へ変換できます。本格的なAPIでは、HTTPメソッド、ステータスコード、認証、入力検証もあわせて設計します。
正規表現による形式確認
preg_match() は、文字列が決められた形式に一致するか調べる関数です。次の例では半角英数字だけで構成されたユーザーIDを確認します。
$userId = 'mity2026';
if (preg_match('/\A[a-zA-Z0-9]{4,20}\z/', $userId) === 1) {
echo '利用できるIDです';
}
\A と \z は、文字列全体の先頭と末尾を表します。^ と $ は複数行モードや末尾の改行によって一致する位置が変わる場合がありますが、\A と \z を使うとその影響を受けず、入力全体を確認できます。
CSRF対策
CSRFは、ログイン中の利用者に意図しない操作を実行させる攻撃です。セッションに保存したランダムなトークンをフォームへ埋め込み、POST時に一致を確認します。
session_start();
$_SESSION['csrf_token'] ??= bin2hex(random_bytes(32));
// フォーム内
// <input type="hidden" name="csrf_token"
// value="<?= htmlspecialchars($_SESSION['csrf_token'], ENT_QUOTES, 'UTF-8') ?>">
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$token = (string) ($_POST['csrf_token'] ?? '');
if (!hash_equals($_SESSION['csrf_token'], $token)) {
http_response_code(403);
exit('不正なリクエストです');
}
}
??=は、左側の値が存在しないかnullのときだけ右側を代入するnull合体代入演算子です。この例では、既存のCSRFトークンを保ち、まだない場合だけ新しく生成します。??は代入せず、左側が存在しないかnullなら右側の値を返します。
練習問題
問題 11から100までの合計を表示しよう
for を使って、1から100までの数を変数 $total に足してください。
$total = 0;
for ($i = 1; $i <= 100; $i++) {
$total += $i;
}
echo $total;
問題 2偶数だけを表示しよう
1から20のうち、2で割り切れる数字だけを表示してください。
for ($i = 1; $i <= 20; $i++) {
if ($i % 2 === 0) {
echo $i . "<br>";
}
}
問題 3商品の合計金額を計算しよう
商品名をキー、価格を値にした連想配列を作り、合計金額を表示してください。
$products = [
'ノート' => 200,
'ペン' => 120,
'消しゴム' => 80,
];
echo array_sum($products) . '円';
次に学ぶこと
ここまで理解できたら、小さなアプリを作りながら知識をつなげていきましょう。