What is the most scalable PHP-based directory structure for a large site?

You should have one directory as web root, where only files you want exposed to the whole internet should reside.

project/
 web/
  index.php
  css/
  js/
  images/
 config/
 lib/
  • web/ is the root shown to visitors
  • lib/ is here the library folder, and where autoload look for files.

You can add more subfolders to project/ like controller, modules, view, helper, etc. This depends on your framework.

EDIT:

If you use composer (which I recommend) and maybe npm with grunt and less your file structure would be the following:

project/
    web/
        js/
        css/
        images/
        index.php
    cli/
    config/
        config.php
    node_modules/
    src/
    test/
    vendor/
    composer.json
    composer.lock
    packages.json
  • web/ has all your public files
  • cli/ scripts and programs to be run from command line NOT the web
  • config/ has all your config files (in git you ignore config.php and instead have config.dist.php without usernames, passwords, validation codes and table prefixes/suffixes and other "secrets")
  • node_modules/ has all your library files from npm (in git I suggest you put this in a submodule)
  • src has all your local PHP files in psr4 structure, set up to autoload in composer.json
  • test/ has all your unit tests for your src classes, set up in autload-dev in composer.json (remember to use composer install --no-dev on live, maybe add -o if you don't have too many classes)
  • vendor has all your library files from composer and the ONE AND ONLY autoload.php to be included in web/index.php and any cli scripts (in git I suggest you ignore this vendor folder)

Add other folders and files as required for your project.

For deployment use this structure:

/sites/project/ (project is your projectname)
    current (alias to current release folder releases/v1.1.0)
    previous (optional alias to previous release folder releases/v1.0.1)
    releases/
        v1.0.0/ (git checkout of tag v1.0.0)
        v1.0.1/ (git checkout of tag v1.0.1)
        v1.1.0/ (git checkout of tag v1.1.0)
    shared/ (has all your shared files and folders to be aliased in all releases - maybe something like GlusterFS)

Make a deployment script. Something like this:

First take backup of db or to copy it to a new database, checkout git repo to new folder with release tag, get all git submodules, run composer install --no-dev, setup any aliases for shared folders and files like uploaded images and configuration files, generate js/css with grunt and less or equivalent, point current alias to the new folder with the tag, run update database script, restart nginx/apache/fpm-php services, run tests to check the website is up.

Have a script to go back to previous version (or a guide so you know what to do).


For core files which are included: approot/inc/

For data access functions and classes are in: approot/dao/

For javascripts: approot/scripts/

For CSS: approot/styles/

For images: approot/img/

For static content (normally for user profile pictures or uploaded images): approot/static/

For caches: approot/caches/

For templates or View files: approot/templates/

All pages file: approot/

Structure from Samstyle PHP Framework


The answer I posted here was from 2009. Over the years more standards were published, including PSR-0 which covers the topic on folder structure. I also have a new (and I feel that it's better) folder structure with Packfire Framework.


This is my setup. It's worked great for me for small - very large projects (including a social network).
These folders would all live within my main application folder:

  • config - contains custom PHP config files
  • css - contains the project's CSS files
  • helpers - contains 'helper' files (each file is a collection of functions)
  • images - contains the project's images
  • js - contains the project's Javascript files
  • lib - contains PHP classes specific to the project
  • modules - My MVC framework allows packaging site sections as modules
    • blog - An example module
      • controllers - contains the controllers for the module
      • models - contains the models for the module
      • views - contains the views for the module
  • views - contains views that should be globally accessible (page header, footer, etc)

All the directories could obviously contain sub-folders that would further organize your files. For example, the 'css' folder could have sub-folders named 'web' and 'mobile'. The 'images' folder could contain a 'user_uploaded' folder which could then contain`'profile'. And of course you can add folders as you see fit, in one project I have a folder called 'uploaders' which just contains stand-alone upload scripts.

I also use convenience methods which help construct the filenames of what I want to load. For example, my loadView() will look for the view file in the current module directory, or if you pass an optional $module argument, it will look specifically within that module's folder.

I hope this helps.

Tags:

Php

Directory