Skip to content
🏺A modern MVC framework written without libraries or frameworks.
Branch: master
Clone or download
Latest commit 5f9ad6e Mar 9, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
assets/scss Fix typos Jul 1, 2018
bin Fix install code Jul 1, 2018
config Clean up README and packages Feb 26, 2019
data Just a few more todos Jun 28, 2018
public Make comment styling consistent with current conventions Dec 22, 2018
src Clean up README and packages Feb 26, 2019
tests Add testing Jun 21, 2018
.gitignore Remove .DS_Store Jun 25, 2018
LICENSE Clean up README and packages Feb 26, 2019 Update Mar 9, 2019
composer.json Clean up README and packages Feb 26, 2019
package.json Clean up README and packages Feb 26, 2019

Laconia License: MIT

A modern MVC framework written without libraries or frameworks (PHP).


Laconia is a personal project created by Tania Rascia to learn the fundamentals of programming and modern web development from scratch. The main goals of the project are to learn MVC (Model View Controller) architecture, the OOP (Object-Oriented Programming) paradigm, routing, authentication, security, modern development practices, and how to tie it all together to make a functional web app.

Laconia runs on PHP 7.2 and MySQL. It uses Composer to autoload classes, configuration and utility files, as well as future tests through PHPUnit. Node.js is used to compile Sass to CSS via npm scripts. The CSS framework Primitive was used for the design.

Here are some of the concepts I learned while writing this program:

  • Authentication – logging in, logging out, resetting a password, having private content/dashboard hidden from anonymous users
  • Security and validation – encrypted passwords and hashing, parameter binding with SQL, making sure users cannot be overridden, making sure no spam or empty content can go through, making sure passwords and usernames have the proper characters
  • Routing – Redirecting to URLs based on incoming request method and URI path, creating public user profiles in the root directory, creating dynamic pages based on GET requests
  • Object-oriented programming – I had never used a class in a working application before writing this app, so I learned a lot about constructors, inheritance, and abstract classes
  • Composer – I had no prior experience using Composer, so I wanted to find out why it was the standard in modern PHP development. I used it for autoloading classes and configuration.
  • Database schema – how to structure a database to relate information easily between the tables, i.e. linking lists and list items, users and user comments, etc. Sessions and Users – how to easily deal with sessions, users, and authentication.


View the live site or install a local copy with the instructions below.

Install Apache, MySQL, and PHP

It is assumed you already know how to install a LAMP stack. For macOS and Windows local development, I would recommend downloading MAMP for a sandboxed environment. You can set up virtual hosts as well.

If using MAMP, add MAMP to the PHP command line by adding this line to .bash_profile.

export PATH=/Applications/MAMP/bin/php/php7.2.1/bin:$PATH

Install Composer

Composer is the standard in PHP for dependency management, class autoloading, and much more.

curl -sS | php
sudo mv composer.phar /usr/local/bin/composer

Set up server

Create a virtual host called laconia.server. The server should point to the /public directory. Your httpd-vhosts.conf will look like this:

<VirtualHost *:80>
    DocumentRoot "/Users/tania/hosts/laconia/public"
    ServerName laconia.server

Run install script

  • Run php bin/install.php in the root directory to initialize the database.
  • Run composer install to autoload classes and configuration.
  • Run npm install to use Sass
  • To run Sass, use npm run sass.

Laconia is all set up and ready to use!

Project Structure

The entire program flows through /public/index.php, and the rest of the project is a directory above public.

  .git             # Git source directory
  assets/          # Uncompiled raw SCSS, JavaScript
  bin/             # Command line scripts
  config/          # Database credentials, utility helpers, and other configuration
  data/            # SQL database files
  node_modules/    # Node.js front end dependencies
  public/          # Publicly accessible files
      css/         # Compiled, ready-to-use styles
      js/          # Compiled, ready-to-use scripts
      index.php    # Main entry point for the entire application
  src/             # PHP source code
      controllers/ # Controller classes
      models/      # Model classes
      views/       # Views
  tests/           # Unit tests
  vendor/          # Composer files and 3rd party packages
  .gitignore       # Files to be ignored in the repository
  composer.json    # Composer dependency file
  install.php      # Database installation script
  LICENSE          # MIT License file
  package.json     # npm dependency file        # Brief documentation


Laconia is a simple list-making website. You can register an account, log in, log out, reset your password, create and edit lists, and view public profiles.

  • / - Index
  • /register - Register a new user
  • /login - Login to user account
  • /home - Logged in home screen
  • /logout - Logout of user session
  • /forgot-password - Get a password reset link
  • /create-password - Create a new password
  • /view-users - View all users
  • /settings - Edit user settings
  • /create - Create a new list
  • /edit/:list_id - Edit an existing list
  • /:username - View public profile
  • /404 - Any not found redirects to 404.


Laconia uses PHPUnit for unit testing. Tests will go in the /tests directory. For now, here is how to run a Hello, World! script.

./vendor/bin/phpunit ./tests/HelloWorldTest


  • Write "Everything I Learned Writing an MVC Framework from Scratch"
  • Set up SSL and put on a live server
  • Make nav responsive
  • Email empty password forgot - PHP Mailer
  • Comment board
  • Make sure users can't comment as someone else
  • Instant display of comment state in the DOM
  • Allow users to delete list items in add mode
  • Make router class
  • Fix issue with trailing slash in URL
  • Validate through JavaScript and send all POST requests through JavaScript instead of page reload
    • Login
    • Register
    • Forgot Password
    • Create Password
    • Create List
    • Edit List
    • Delete
    • Settings
  • Do not allow > 255 chars for lists
  • Add ability to delete a user account
  • Disallow spaces in usernames
  • Comment all code
  • Create a user settings page
  • Make view for public user lists
  • Prevent adding new list items if post is empty
  • Create a top navigation bar when logged in
  • Add CSS styles (Primitive)
  • Disallow multiple same usernames with different casing
  • Make Sass watch
  • Integrate Composer for autoloading of classes and config
  • Clean up password validation code
  • Allow users to edit their own lists - /edit
  • Allow user to create a list with list items - /create
  • Create public facing user profile - laconia.test/$username - will require Apache redirects? or PHP redirects?
  • Make routing dynamic based on incoming pathname and existing files, rather than a switch with each filename
  • Separate POST and GET into different functions - do not display POST code in GET view
  • Turn all controllers into classes
  • Route all URLs through index.php
  • Separate views into partials
  • Separate business logic (controller) from HTML (view)
  • Add ability to reset password of users
  • Add ability to log in, log out, and register a user


I've used a combination of many tutorials and StackOverflow posts to create this project. These have been the most important.


Please feel free to fork, comment, critique, or submit a pull request.



This project is open source and available under the MIT License.

You can’t perform that action at this time.