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.