Skip to content

nurRiyad/php-task-manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PHP Task Manager API

A RESTful task management API built with vanilla PHP — no framework. Uses JSON files for storage, JWT-style bearer token authentication, and ships with a simple browser UI.

Built as a learning project to understand PHP fundamentals: routing, middleware, MVC structure, and containerisation with Docker.


Table of Contents


Tech Stack

Concern Choice
Language PHP 8.2
Routing Custom (no framework)
Auth Bearer token (stored in JSON)
Storage JSON flat files
IDs UUID v4 via ramsey/uuid
Config vlucas/phpdotenv
Container Docker + Docker Compose

Project Structure

php-task-api-learning-project/
│
├── public/                  # Web root — only this directory is exposed
│   ├── index.php            # Application entry point (front controller)
│   └── app.html             # Standalone HTML playground
│
├── src/                     # All application code (PSR-4 autoloaded as App\)
│   ├── Controllers/
│   │   ├── Controller.php       # Base controller (shared helpers: json(), input(), etc.)
│   │   ├── AuthController.php   # Handles register / login / me / logout
│   │   ├── TaskController.php   # CRUD for tasks
│   │   └── ViewController.php   # Serves PHP view pages
│   │
│   ├── Middleware/
│   │   └── Auth.php             # Validates Bearer token, returns user or 401
│   │
│   ├── Models/
│   │   ├── User.php             # Read/write users.json
│   │   └── Task.php             # Read/write tasks.json
│   │
│   ├── Routes/
│   │   ├── Router.php           # Dispatches request to the right route file
│   │   ├── AuthRoutes.php       # /api/auth/* routes
│   │   ├── TaskRoutes.php       # /api/tasks/* routes
│   │   ├── HealthRoutes.php     # /api/health
│   │   └── WebRoutes.php        # Browser page routes (/)
│   │
│   └── Views/
│       ├── layout.php           # Shared HTML shell (head, scripts)
│       ├── home.php             # Task board page
│       ├── login.php            # Login page
│       ├── signup.php           # Registration page
│       ├── profile.php          # User profile page
│       ├── partials/
│       │   ├── header.php       # Page header partial
│       │   ├── nav.php          # Navigation partial
│       │   ├── board.php        # Task board partial
│       │   └── form.php         # Task form partial
│       └── scripts/
│           ├── app.js           # Task board JS (fetch calls)
│           └── auth.js          # Auth JS (login / register / logout)
│
├── storage/                 # Flat-file database (gitignored in production)
│   ├── users.json           # Registered users
│   ├── tasks.json           # All tasks
│   └── tokens.json          # Active auth tokens
│
├── vendor/                  # Composer dependencies (not committed)
├── composer.json
├── composer.lock
├── Dockerfile
├── docker-compose.yml
├── .dockerignore
├── .env                     # Local environment config (never commit this)
└── .gitignore

Getting Started

Running with Docker (recommended)

Prerequisites: Docker Desktop installed and running.

  1. Clone the repo:

    git clone <repo-url>
    cd php-task-api-learning-project
  2. Create your .env file:

    cp .env.example .env   # or create it manually — see Environment Variables below
  3. Start the container:

    docker compose up --build
  4. Visit http://localhost:8000

To stop: docker compose down


Running locally without Docker

Prerequisites: PHP 8.2+, Composer.

  1. Install dependencies:

    composer install
  2. Create your .env file (see below).

  3. Start the dev server:

    composer dev
  4. Visit http://localhost:8000


Environment Variables

Create a .env file in the project root:

APP_NAME="Task Manager"
APP_URL=http://localhost:8000
Variable Description Default
APP_NAME Application display name Task Manager
APP_URL Base URL (used for CORS and links) http://localhost:8000

When running via Docker, these are injected by docker-compose.yml using env_file. The .env file does not need to exist inside the container.


API Reference

All API endpoints return JSON. Protected routes require an Authorization: Bearer <token> header — the token is returned on login.

Auth

Method Endpoint Auth Description
POST /api/auth/register No Create a new account
POST /api/auth/login No Log in, receive a token
GET /api/auth/me Yes Get the current user
POST /api/auth/logout Yes Invalidate the token

Register / Login request body:

{
  "email": "user@example.com",
  "password": "secret"
}

Login response:

{
  "token": "some-uuid-token",
  "user": { "id": "...", "email": "user@example.com" }
}

Tasks

All task routes require authentication.

Method Endpoint Description
GET /api/tasks List all tasks for the user
POST /api/tasks Create a new task
GET /api/tasks/:id Get a single task
PUT /api/tasks/:id Update a task
DELETE /api/tasks/:id Delete a task

Create / Update request body:

{
  "title": "Buy groceries",
  "description": "Milk, eggs, bread",
  "status": "pending"
}

Task object:

{
  "id": "uuid-v4",
  "user_id": "uuid-v4",
  "title": "Buy groceries",
  "description": "Milk, eggs, bread",
  "status": "pending",
  "created_at": "2026-05-21T15:00:00+00:00"
}

How It Works

Request lifecycle:

HTTP Request
    └── public/index.php        ← front controller, loads .env
            └── Router.php      ← matches method + path
                    ├── AuthRoutes / TaskRoutes / etc.
                    │       └── Controller method
                    │               ├── Middleware\Auth (if protected)
                    │               ├── Model (read/write JSON)
                    │               └── json() response
                    └── 404 if no route matched

Storage: Data is persisted in storage/*.json files. The storage/ directory is mounted as a Docker volume so data survives container restarts.

Authentication: On login, a UUID token is generated and stored in storage/tokens.json mapped to the user's ID. Protected routes run Middleware\Auth, which reads the Authorization header, looks up the token, and returns the associated user — or a 401 if invalid.

About

A RESTful task management API built with vanilla PHP

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors