Reference Documentation
From Outlet
{{#hierarchy-top:}}
Contents |
Overview
Outlet provides database persistence for PHP objects in a transparent, unobtrusive way. It let's you define and instantiate entity classes that are completely independent of the code that saves them to the database. The data is persisted through the use of proxies. Whenever you 'save' an object, Outlet decorates the object with a sub-class that performs the database operations behind the scenes.
Let's say we start out with an entity object such as: <source lang="php"> class Bug {
public $Title; public $ProjectID;
private $project;
function getProject () {
return $this->project;
}
function setProject (Project $p) {
$this->project = $p;
}
} </source>
Whenever you instantiate, populate, and save it to the database with code like: <source lang="php"> $con = Outlet::getInstance();
$bug = new Bug; $bug->Title = "error on page"; $bug->ProjectID = 1;
$con->save( $bug ); //performs an insert </source>
Outlet is replacing your $bug variable of type Bug with a proxy called Bug_OutletProxy: <source lang="php"> print_r($bug); // after it's been saved </source>
outputs:
Bug_OutletProxy Object
(
[Title] => error on page
[ProjectID] => 1
[project:private] =>
)
Since the proxy is a subclass of the entity (Bug_OutletProxy extends Bug), you can use the proxy wherever you would have used the original entity. Even the following code evaluates to true:
<source lang="php"> // since the bug has been saved it is now an instance of Bug_OutletProxy if ($bug instanceof Bug) echo "It seems to be a Bug too"; </source>
Now here's where the magic happens, when you call a method such a $bug->getProject(), the proxy automatically populates the $project property with data from the database behind the scenes: <source lang="php"> $project = $bug->getProject();
print_r($bug); </source>
outputs:
Bug_OutletProxy Object
(
[Title] => error on page
[ProjectID] => 1
[project:private] => Project_OutletProxy Object
(
[ID] => 1
[Name] => My Project
)
)
Configuration
The configuration consists of an associative array with the elements: <source lang="php"> <?php return array(
'connection' => array(...), // connection config 'classes' => array(...) // class mappings config
); </source>
- connection
- Database connection settings
- classes
- Mapping configuration for each of the entity classes
Database Connection
<source lang="php"> array(
'dsn' => 'mysql:hostname=myhost.com;dbname=testdb', 'username' => 'testdbuser', 'password' => 'testdbpass'
) </source>
- dsn
- A PDO connection string
- username
- A username if the database driver requires it
- password
- A password if the database driver requires it
Classes
<source lang="php"> array(
'User' => array( 'props' => array(...), // properties mappings 'associations' => array(...) // relationships mappings ), 'Project' => ...
) </source>
An array of class mappings indexed by the name of the entity class. Each class mapping is an associative array with the elements:
- props
- An array of property mappings
- associations
- An array of association mappings
Properties
<source lang="php"> array(
'ID' => array('user_id', 'int', array('pk'=>true, 'autoIncrement'=>true)),
'FirstName' => array('first_name', 'varchar'),
...
) </source>
- The indexes are the properties of the class being mapped.
- The first element of each mapping is the name of the column.
- The second is the column type, which can be either int or varchar.
- The third element is an array of optional settings:
- pk
- Whether this field is (part of) the primary key. Defaults to false.
- autoIncrement
- Whether this field is automatically incremented by the database. Defaults to false.
Associations
<source lang="php"> array(
array('one-to-many', 'Bug', array('key'=>'BugID')),
array('many-to-one', 'Project', array('key'=>'ProjectID')),
...
) </source>
- The first element of an association mapping is the type, it can be either one-to-many or many-to-one.
- The second element is the entity class that this relation refers to (related entity).
- The third element is a set of options which differ depending on the type of association.
- one-to-many
-
- key
- The name of the property on the related entity that contains the primary key of this entity.
- name
- Optional. Defaults to the name of the related entity.
- The name to give the relationship. If this association defines the relationship between a bug and the people who are assigned to it (one-to-many from Bug to User), and you set the name to 'Assignee', the method names on the bug object will be 'getAssignees', 'setAssignees', and 'addAssignee'.
- many-to-one
-
- key
- The name of the property on this entity that contains the primary key of the related entity.
- name
- Optional. Defaults to the name of the related entity.
- The name to give the relationship. If this association defines the relationship between a bug and the user who reported it (many-to-one from Bug to User), and you set the name to 'Reporter', the method names on the bug object will be 'getReporter' and 'setReporter'.
- optional
- Optional. Defaults to false.
- Whether to allow this relationship to be optional (allow null).
Usage
Selecting
A query with outlet is just a regular SQL statement except for the ability to refer to columns by their class member names. Simply wrap the identifier in curly braces and outlet will automatically replace it with the corresponding table or column name. You can even add aliases: <source lang="php"> $bugs = $outlet->select("Bug", "INNER JOIN {Project p} ON {Bug.ProjectID} = {p.ProjectID}"); // this code will be transformed to // SELECT bugs.* // FROM bugs // INNER JOIN projects p // ON bugs.project_id = p.project_id </source>
Although referring to the columns by their class member name is recommended, you're always free to simple use straight sql.
select
<source lang="php"> <?php $outlet = Outlet::getInstance(); // retrieve an array of Bug objects by using a prepared statement $bugs = $outlet->select("Bug", "WHERE {Bug.StatusID} = ?", array(1)); </source>
load
<source lang="php"> <?php $outlet = Outlet::getInstance(); // retrieve a Bug by primary key $bug = $outlet->load("Bug", 1); </source>
Inserting and Updating
<source lang="php"> <?php $outlet = Outlet::getInstance(); // insert a bug $bug = new Bug; $bug->Title = 'This is a test bug'; $bug->ProjectID = 1;
$outlet->save( $bug ); // executes an insert statement
// now that the bug is saved and we're dealing with a proxy, // any subsequent calls to $outlet->save() will execute an update statement $bug->Title = 'New Title';
$outlet->save( $bug ); // executes an update statement </source>
Relationships
You can also use the query syntax to filter what's returned through a relationship method: <source lang="php"> <?php $outlet = Outlet::getInstance(); $project = $outlet->load('Project', 1);
$bugs = $project->getBugs('WHERE {Bug.StatusID} = 1'); </source>
{{#hierarchy-bottom:}}

