Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

PHPbeginnerwebAI generated

Personal Portfolio Site with Contact Form

Build a personal portfolio website in plain PHP: a home page about you, a projects page showing your work in a grid, and a contact page with a form. When a visitor submits the form, the site checks the input, protects against spam, and emails the message to you using PHPMailer. Shared parts like the header and footer are written once and reused on every page. It's a practical first PHP project: you'll learn how PHP builds pages on the server, how to reuse templates with include, how to handle and validate form submissions safely, and how to send email through SMTP, all while ending up with a site you can actually use.

Estimate
~8.5h
Steps
6
Completed by
0
Proposed by
codeseed.app

PHPMailer

Project roadmap

  1. 01

    Build the page structure

    ~1.5h

    Install PHP 8. Create includes/header.php and includes/footer.php with the site's HTML head, navigation (Home, Projects, Contact) and footer, and three pages, index.php, projects.php and contact.php, that include them. Highlight the current page in the navigation. Run it with php -S localhost:8000. Done when: all three pages open with the same header and footer, and the menu links work.

  2. 02

    List your projects from a data file

    ~1.5h

    Store your projects in data/projects.json: title, short description, technologies, image path and link. In projects.php, read the file with json_decode and loop over it to render a card for each project in a responsive CSS grid. Escape every value with htmlspecialchars. Done when: the projects page shows one card per project in the JSON file.

  3. 03

    Build the contact form

    ~1h

    Add a form to contact.php with name, email, subject and message fields, submitted with POST to the same page. Add a hidden honeypot field that real visitors never fill in, to catch simple spam bots. After a failed submission, keep what the user typed in the fields. Done when: the form submits and shows the typed values again.

  4. 04

    Validate the input

    ~1.5h

    On submit, trim every field and check: name and message are required, the email passes filter_var with FILTER_VALIDATE_EMAIL, the subject is at most 100 characters and the message at most 2,000. Silently ignore submissions where the honeypot is filled in. Show each error next to its field. Done when: invalid submissions show clear errors and nothing is sent.

  5. 05

    Send the email with PHPMailer

    ~2h

    Install PHPMailer with Composer. Read the SMTP host, port, username and password from a config file that's excluded from Git (commit a config.example.php). Send the message to yourself with the visitor's address as Reply-To, then redirect to contact.php?sent=1 to show a thank-you message, so refreshing doesn't send it again. For testing, use a local catcher such as Mailpit. Done when: a valid submission arrives in Mailpit, or your inbox.

  6. 06

    Polish and handle failures

    ~1h

    If sending fails, show a friendly message and log the PHPMailer error to a file, never to the page. Make the site look good on phones and desktops with CSS, and write a README with setup steps. Done when: a wrong SMTP password shows a friendly error while the real error is written to the log file.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~8.5h · 6 steps

Tech stack

PHPMailer