A lightweight, self-hosted PHP web exam system designed for corporate training, licensing tests, and internal assessments. No framework or database required — everything runs on plain PHP with JSON configuration files.
輕量、免資料庫的 PHP 線上考試系統,適用於企業教育訓練、內部測驗與證照考試。僅需 PHP + Web 伺服器即可部署,支援 NAS 集中儲存答案。
| Feature | 說明 |
|---|---|
| Employee login | 員工編號 + 生日八碼登入,無需帳密管理 |
| File upload answers | 支援圖片、Excel、任意附件上傳 |
| Text answers | 支援純文字作答題型 |
| Auto-save progress | 答題進度即時儲存,重新整理不遺失 |
| NAS / network path support | 可將答案資料夾指向網路磁碟(NAS) |
| Grading interface | 批改介面:逐題評分、文字回饋、鎖定卷面 |
| Grade download | 一鍵匯出 CSV 成績單 |
| Setup tool | 考前管理工具:預建資料夾、測試權限 |
| Activity log | 每位考生完整操作紀錄(登入、上傳、儲存) |
| No database | 全程使用 JSON + 檔案系統,零資料庫依賴 |
- PHP 7.4 or later(建議 PHP 8.1+)
- Apache or Nginx(mod_rewrite not required)
- Web server write permission on the
answers/directory(或自訂的 NAS 路徑)
# 1. Clone the repository
git clone https://github.com/tskerpnext/exam.git
cd exam
# 2. Copy and edit the config files
cp config.example.json config.json
cp user.example.json user.json
# 3. Edit config.json — set exam name, questions, passwords
# 4. Edit user.json — add each employee's ID, name, birthday, email
# 5. Deploy to your PHP web server and open index.php in a browser| Key | Type | Description |
|---|---|---|
exam_name |
string | 考試名稱,顯示於登入頁與考場頁 |
exam_code |
string | 考試代碼(純顯示用) |
max_file_size_mb |
int | 單檔上傳大小上限(MB) |
answer_path |
string | 答案根目錄;留空表示使用 answers/;可填 NAS UNC 路徑 |
setup_password |
string | setup.php 管理員密碼 |
grader_password |
string | grade.php 批改者密碼 |
grader_ids |
array | 可使用批改功能的員工編號清單 |
questions |
array | 題目陣列(見下方說明) |
{
"no": 1,
"title": "題目大標",
"description": "題目說明",
"subs": [
{
"no": 1,
"title": "子題標題",
"type": "file",
"description": "請上傳截圖",
"accept": ".jpg,.png"
}
]
}type:"file"— 檔案上傳;"text"— 文字作答accept: 允許的副檔名(type: file時使用)
{
"A0001": {
"UNITS": "部門代號",
"NAME": "姓名",
"BIRTH": "19900115",
"EMAIL": "user@example.com"
}
}- 密碼為
BIRTH欄位(西元年生日八碼) - 員工編號為 JSON 的 key(登入時不區分大小寫)
exam/
├── index.php # 登入頁
├── exam.php # 考場主頁(題目列表 + 作答)
├── save.php # 文字答案儲存 API
├── upload.php # 檔案上傳 API
├── download.php # 考生答案下載
├── ping.php # 心跳 / Session 保持
├── logout.php # 登出
├── grade.php # 批改介面
├── grade_save.php # 批改儲存 API
├── grade_toggle.php # 鎖定 / 解鎖卷面 API
├── grade_download.php # 成績 CSV 下載
├── setup.php # 考前管理工具
├── lib.php # 共用函式庫
├── config.json # 考試設定(不納入版控)
├── config.example.json
├── user.json # 考生名單(不納入版控)
├── user.example.json
└── answers/ # 考生答案目錄(不納入版控)
config.jsonanduser.jsonare excluded from version control via.gitignore— never commit real employee data.- The
answers/directory is protected by.htaccess(Apache) which denies all direct HTTP access. Files are served only throughdownload.php, which enforces session auth. - Default passwords (
setup_password,grader_password) must be changed before deployment. - This system is designed for intranet / LAN use. If exposing to the internet, add HTTPS and firewall rules.
location ~ ^/(setup|grade)\.php$ {
allow 192.168.1.0/24;
deny all;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}<FilesMatch "^(setup|grade)\.php$">
Require ip 192.168.1.0/24
</FilesMatch>Set exam_start and exam_end in config.json (format: YYYY-MM-DD HH:MM:SS) to enable the timer. When time expires, all answer inputs are automatically disabled in the browser.
{
"exam_start": "2026-06-10 09:00:00",
"exam_end": "2026-06-10 11:00:00"
}In setup.php, use the 匯入 CSV 考生名單 panel to upload a UTF-8 CSV and overwrite user.json in one step. Format:
員工編號,部門,姓名,生日八碼,Email
A0001,SA,王小明,19900115,ming@example.com
B0023,HR,李美玲,19851220,li@example.com
docker compose up
# Open http://localhost:8080Mounts the current directory as the web root. PHP upload limits are pre-configured to 20 MB.
MIT License — free to use, modify, and distribute.
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.