diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..870c717
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,8 @@
+# Webサーバー (Apache) がホストOSで公開されるポート番号
+WEB_PORT=8080
+
+# データベース (MySQL) がホストOSで公開されるポート番号
+DB_PORT=3306
+
+# phpMyAdmin がホストOSで公開されるポート番号
+PHPMYADMIN_PORT=8081
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..27b7db4
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,46 @@
+version: "3.8"
+
+services:
+ web:
+ image: php:8.2-apache
+ ports:
+ - "${WEB_PORT:-8080}:80"
+ volumes:
+ - ./src/docker_index.html:/var/www/html/index.html
+ - ./src/sample:/var/www/html/sample
+ - ./src/workspace:/var/www/html/workspace
+
+ depends_on:
+ - db
+
+ container_name: hello-programmer-world_web
+
+ db:
+ image: mysql:8.0
+ restart: unless-stopped
+ environment:
+ MYSQL_DATABASE: "trainee_db"
+ MYSQL_USER: "user"
+ MYSQL_PASSWORD: "password"
+ MYSQL_ROOT_PASSWORD: "root"
+
+ volumes:
+ - db_data:/var/lib/mysql
+ ports:
+ - "${DB_PORT:-3306}:3306"
+
+ container_name: hello-programmer-world_db
+
+ phpmyadmin:
+ image: phpmyadmin/phpmyadmin
+ ports:
+ - "${PHPMYADMIN_PORT:-8081}:80"
+ environment:
+ PMA_HOST: db
+ MYSQL_ROOT_PASSWORD: root # データベースサービスのrootパスワードと同じもの
+ depends_on:
+ - db
+ container_name: hello-programmer-world_phpmyadmin
+
+volumes:
+ db_data:
diff --git a/docker/.env.example b/docker/.env.example
deleted file mode 100644
index 870c717..0000000
--- a/docker/.env.example
+++ /dev/null
@@ -1,8 +0,0 @@
-# Webサーバー (Apache) がホストOSで公開されるポート番号
-WEB_PORT=8080
-
-# データベース (MySQL) がホストOSで公開されるポート番号
-DB_PORT=3306
-
-# phpMyAdmin がホストOSで公開されるポート番号
-PHPMYADMIN_PORT=8081
\ No newline at end of file
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
deleted file mode 100644
index b41faee..0000000
--- a/docker/docker-compose.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-version: "3.8"
-
-services:
- web:
- image: php:8.2-apache
- ports:
- - "${WEB_PORT:-8080}:80"
- volumes:
- - ./src:/var/www/html
-
- depends_on:
- - db
-
- container_name: hello-programmer-world_web
-
- db:
- image: mysql:8.0
- restart: unless-stopped
- environment:
- MYSQL_DATABASE: "trainee_db"
- MYSQL_USER: "trainee_user"
- MYSQL_PASSWORD: "trainee_password"
- MYSQL_ROOT_PASSWORD: "root_password"
-
- volumes:
- - db_data:/var/lib/mysql
- ports:
- - "${DB_PORT:-3306}:3306"
-
- container_name: hello-programmer-world_db
-
- phpmyadmin:
- image: phpmyadmin/phpmyadmin
- ports:
- - "${PHPMYADMIN_PORT:-8081}:80"
- environment:
- PMA_HOST: db
- MYSQL_ROOT_PASSWORD: root_password # データベースサービスのrootパスワードと同じもの
- depends_on:
- - db
- container_name: hello-programmer-world_phpmyadmin
-
-volumes:
- db_data:
diff --git a/docker/src/index.php b/docker/src/index.php
deleted file mode 100644
index b4a83eb..0000000
--- a/docker/src/index.php
+++ /dev/null
@@ -1,23 +0,0 @@
-";
- echo json_encode($message, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
- echo "";
-}
-
-?>
-
-
-
-
-
- Hello PHP World!
-
-
- こんにちは、さん!
- =varout($_SERVER);?>
-
-
diff --git a/src/components/DockerLink.astro b/src/components/DockerLink.astro
new file mode 100644
index 0000000..cd172f0
--- /dev/null
+++ b/src/components/DockerLink.astro
@@ -0,0 +1,33 @@
+---
+const { WEB_PORT = 8080 } = import.meta.env;
+
+interface Props {
+ href: string;
+ title?: string;
+}
+
+const href = (() => {
+
+ let href = Astro.props.href;
+
+ if (href.startsWith("http://") || href.startsWith("https://")) {
+ return astro.props.href;
+ }
+
+ if (href.startsWith("/")) {
+ href = href.slice(1);
+ }
+
+ const base = "http://localhost";
+ if (!WEB_PORT || WEB_PORT === "80") {
+ return `${base}/${href}`;
+ }
+
+ return `${base}:${WEB_PORT}/${href}`;
+
+})();
+---
+
+
+ Docker: {Astro.props.title ?? href}
+
diff --git a/src/docker_index.html b/src/docker_index.html
new file mode 100644
index 0000000..a950a28
--- /dev/null
+++ b/src/docker_index.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+ Docker
+
+
+ Dockerのページです。
+
+
diff --git a/src/env.d.ts b/src/env.d.ts
new file mode 100644
index 0000000..4ab85c5
--- /dev/null
+++ b/src/env.d.ts
@@ -0,0 +1,9 @@
+interface ImportMetaEnv {
+ WEB_PORT: string;
+ DB_PORT: string;
+ PHPMYADMIN_PORT: string;
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv;
+}
diff --git a/src/pages/php/010-foundation.mdx b/src/pages/php/010-foundation.mdx
index 14f2af1..f00abfc 100644
--- a/src/pages/php/010-foundation.mdx
+++ b/src/pages/php/010-foundation.mdx
@@ -4,8 +4,151 @@
import Toc from "../../components/Toc.astro";
-export const title = "PHPとWebサーバー";
+export const title = "PHPとJavaScriptを比較";
# {title}
## TOC
+
+## 変数
+
+PHPの変数は、ドル記号 (`$`) で始まります。JavaScriptの`let`や`const`のような宣言キーワードは不要で、値を代入すると変数が作成されます。
+
+```php
+$name = "Alice";
+$age = 30;
+
+echo "名前: " . $name; // "名前: Alice" と表示
+```
+
+[より詳しい型や変数の使い方...](/reference/010-foundation-php#変数)
+
+## 配列
+
+PHPの配列は、複数の値を一つの変数にまとめて格納するために使います。JavaScriptの配列と似ていますが、PHPでは大きく分けて2種類の配列があります。
+
+### 数値添字配列
+
+インデックス(添字)が `0` から始まる数値の配列です。
+
+```php
+// 果物のリスト
+$fruits = ["Apple", "Banana", "Cherry"];
+echo $fruits[1]; // "Banana" と表示
+```
+
+### 連想配列
+
+各値に、数値の代わりに文字列のキー(名前)を関連付けた配列です。オブジェクトのように、値に名前を付けて管理したい場合に便利です。
+
+```php
+// ユーザーの情報
+$user = [
+ "name" => "Bob",
+ "age" => 25,
+ "city" => "Tokyo"
+];
+echo $user["name"]; // "Bob" と表示
+```
+
+[配列の詳しい使い方...](/reference/010-foundation-php#配列-array)
+
+## 関数
+
+関数は、特定の処理をひとまとめにしたものです。`function` キーワードを使って定義し、名前を付けて呼び出すことで、同じ処理を何度も再利用できます。
+
+```php
+// 2つの数値を受け取って、その合計を返す関数
+function add($a, $b) {
+ return $a + $b;
+}
+
+// 関数を呼び出す
+$sum = add(5, 3);
+echo $sum; // "8" と表示
+```
+
+[関数の詳しい使い方...](/reference/010-foundation-php#関数)
+
+## if文による条件分岐
+
+プログラムの流れを条件によって変えたい場合、`if`文を使います。
+丸括弧 `()` の中に条件を書き、その条件が満たされる(`true`になる)場合だけ、波括弧 `{}` の中の処理が実行されます。
+
+```php
+$score = 85;
+
+// もし score が 80以上なら
+if ($score >= 80) {
+ echo "合格!";
+}
+```
+
+条件が満たされなかった場合の処理は `else` を使って書きます。さらに、別の条件を続けたい場合は `elseif` を使います。
+
+```php
+$score = 75;
+
+if ($score >= 80) {
+ echo "合格!";
+} elseif ($score >= 60) {
+ echo "惜しい!あと少し!";
+} else {
+ echo "不合格です。";
+}
+```
+
+JavaScriptと同様に、PHPにも `==` と `===` の2種類の比較があります。
+思わぬバグを防ぐため、型まで厳密に比較する `===` を使うことが推奨されます。
+
+## for / foreach による繰り返し
+
+配列などのまとまったデータに対して、同じ処理を順番に実行したい場合は繰り返し処理を使います。
+
+### for文
+
+昔ながらの書き方で、指定した回数だけ処理を繰り返します。配列の要素数だけ繰り返すことで、すべての要素にアクセスできます。
+`count()` は配列の要素数を返す関数です。
+
+```php
+$prices = [1290, 859, 1247];
+$total = 0;
+
+for ($i = 0; $i < count($prices); $i++) {
+ $total = $total + $prices[$i];
+}
+
+echo "合計: " . $total; // 合計: 3396
+```
+
+### foreach文
+
+PHPで配列の全要素を順番に処理する場合、`foreach`文を使うのが最も簡単で一般的です。
+配列から要素を1つずつ取り出し、変数(以下の例では `$price`)に代入してブロック内の処理を実行します。
+
+JavaScriptの`for...of`文に似ていますが、括弧内の書き方が少し異なります。
+
+```php
+$prices = [1290, 859, 1247];
+$total = 0;
+
+foreach ($prices as $price) {
+ $total = $total + $price;
+}
+
+echo "合計: " . $total; // 合計: 3396
+```
+
+連想配列の場合、キーと値の両方を取り出すこともできます。
+
+```php
+$user = [
+ "name" => "Bob",
+ "age" => 25,
+];
+
+foreach ($user as $key => $value) {
+ echo $key . ": " . $value . "
";
+}
+// name: Bob
age: 25
と表示される
+```
diff --git a/src/pages/php/020-html-within-php.mdx b/src/pages/php/020-html-within-php.mdx
new file mode 100644
index 0000000..32bbbd9
--- /dev/null
+++ b/src/pages/php/020-html-within-php.mdx
@@ -0,0 +1,160 @@
+---
+layout: "@/layouts/MarkdownLayout.astro"
+---
+
+import Toc from "../../components/Toc.astro";
+
+export const title = "HTMLをPHP内で扱う";
+
+import DockerLink from "@/components/DockerLink.astro";
+
+# {title}
+
+## TOC
+
+## 動作環境
+
+このセクションのサンプルコードは、以下のコマンドを入力することで実際の動作を確認できます。
+
+```bash
+cd path/to/this/project # docker-compose.ymlのあるディレクトリへ移動してください
+docker compose up -d
+```
+
+## PHPを書いてみる
+
+JavaScriptをHTML内に直接書くには、`