Framework file structure?

If you have built your own MVC Framework, what is your file structure look like?

I am considering doing something like this:


index.php
innit.php 
/apps/
   controller/
   model/
   view/
/code/ 
    controller.php
    registry.php
    view.php
    db.php
    session.php
/www/
    img/
    script/
    css/

what do you think?

What is innit.php for? Also I would change some directories from singular to plural and the other way around - controllers instead of controller, app or application instead of apps. But that’s just me, you can do it anyway you want to.

innit.php? Typo? Most amusing none-the-less. :smiley:

I like keeping my root as clean as possible, and keeping everything in its own container.


/domain-name.app          <-- Root
  |---public
  |   \\---store
  |       |---css
  |       |---media
  |       \\---script
  |
  |   index.php
  |   web.conf            <-- For IIS
  |   .htaccess           <-- For Apache
  |   
  \\---system
      |---application
      |   \\---[module]
      |       |---controller
      |       |---model
      |       \\---view
      |           |---__shared
      |           \\---[page]
      |
      |   bootstrap.php
      |
      |---datastore
      |   \\---config
      |       global.xml
      |       [module].xml
      |
      |   main.db.sql     <-- SQLite
      |
      |---library
      |   \\---vendor      <-- Third-party: Zend, Sympony
      |
      \\---temp
          |---cache
          |---log
          \\---session


.
|-- app
|   |-- Controllers     # Controllers
|   |-- Data            # Data used by the app (user uploads, etc)
|   |-- Errors          # 404 pages
|   |-- Helpers         # random functions / factories
|   |-- Locale          # language files
|   |-- Models          # models
|   `-- Views           # views
|-- dev
|-- lib                 # My lib classes, same for all projects
|   `-- Common
|       |-- Bench
|       |-- Cache
|       |-- Controller
|       |-- DB
|       |-- DTO
|       |-- IO
|       |-- Loggers
|       `-- Template
|-- logs      # apache logs
`-- www       # images, htaccess file, etc

The conf file is in root.

I like to keep all information related to a certain model (so the model class, templates etc) in its own directory, so installation is a mere case of dropping in the directory and running the install file.

Here’s an example:


index.php
Settings.ini
./Application
------- / Abstract
--------------- Model.php   <- an abstract class defining default model behavior
------- / Classes
--------------- Application.php
--------------- Request.php
--------------- / Databases           <- All databases implement iDatabase
----------------------- MySQL.php   <-  Connection and communication with a MySQL database
----------------------- XML.php
----------------------- SQLite.php
------- / Functions
------- / Interfaces
--------------- / iDatabase.php
./Plugins
------- / Content
--------------- / Actions
------------------------ View.php   <- Simply outputs content based on an identifier
------------------------ Add.php     <- Controls actions related to adding, and outputs the form if there 
------------------------ Edit.php
------------------------ Delete.php
------------------------ Admin.php
--------------- / Classes
------------------------ Model.php
--------------- / Configuration
------------------------ Install.php
------------------------ Table.sql
./Templates
------- / Default
--------------- Main.php
--------------- Menu.php

The application class does the main work.

Each major class (databases, application, request) have a static getDefault function which loads the default values. So to start an ordinary request, index.php would have:

<?php
require_once 'Application/Application.php';
$Application = Application::getDefault();
$Application->initiate();
$Application->render();

The getDefault function starts the default database and the default request (which loads from the superglobal arrays) objects.

To start an application with dummy data, simply:

<?php
require_once 'Application/Application.php';
$Application = new Application();
$ExternalMySQL = new MySQLDatabase('000.000.0.0', 'database', 'user', 'pass');
$FakeRequest = new Request();
$FakeRequest->post( array( 'Action' => 'addContent', 'Title' => 'Test Title', 'Content' => 'Test Content' ) );
$FakeRequest->session( array( 'LoggedIn' => true, 'UserID' => 0) );
$FakeRequest->server( array('REQUEST_URI' => '/Content/Add') );
$Application->setDatabase($ExternalMySQL);
$Application->setRequest($FakeRequest);
$Application->initiate();
$Application->render();

Default settings are stored in Settings.ini, and all pages use require_once on any references they use. Its a habit I picked up from c++ which I stuck to. It means that I don’t have to include everything that isn’t a class at the beginning, and parts of the application can be extracted without huge problems.