To build an ActiveRecord-style ORM for usage in small projects where something like Doctrine is too much or the project structure is rigid and cannot be easily incorporated with Doctrine/other ORMs.
Model:
<?php
class Book extends Model {
public function getTable () {
return "books";
}
/**
* This function overrides
* @return [type] [description]
*/
public function getColumns () {
return [
// Declare the column as a string by setting the type
'author' => 'string',
// Alternatively you can pass another object
'title' => [
'type' => 'string'
]
]
}
}
?>
Configuration:
<?php
// Set the database on a single function statically. This unfortunately
// will tightly couple the model with the static ORM but I'm looking for alternate ways
// which stil maintain simplicity
ORM::setDatabase ([
'type' => 'mysql',
// ...
]);
?>
Querying
This can be similar to eloquent's query system or many others. This is one of the few places I'd prefer to use reflection
<?php
ORM::query ('Book')
->andwhere ('author', 'J.K. Rowling')
->orWhere ('author', 'Robert Galbraith')
->findAll ();
// or maybe even this, if it's possible without using too much 'magic' methods
Book::query ()
->andwhere ('author', 'J.K. Rowling')
->orWhere ('author', 'Robert Galbraith')
->findAll ();
?>
Using Instances
<?php
$book = new Book ([
'author' => 'John',
'title' => "Ventriloquism for dummies"
]);
$book->save ();
// Getting and setting parameters
$book->set ('author', "Gabbo");
$author = $book->get ('author');
?>
I prefer not to use attributes or magic methods like setAuthor
but other more powerful getters/setters can be built on this minimal surface-area API because:
- We know what columns we should work with
- We know the type and information about all the columns.
Hopefully I would like to keep the core API minimal and allow traits to be used to have more powerful ways to work with the data on the model.
Relationships
<?php
class Author extends Model {
public function getTable () {
return "authors";
}
public function getColumns () {
return [
// Declare the column as a string by setting the type
'books' => [
'class' => 'Book',
'type' => Relationship::HAS_MANY,
'foreign_key' => 'book_id',
'local_key' => 'id' // On authors table
],
// Alternatively you can pass another object
'name' => [
'type' => 'string'
]
]
}
}
class Book extends Model {
public function getTable () {
return "books";
}
public function getColumns () {
return [
// Declare the column as a string by setting the type
'author' => [
'class' => 'Author',
'type' => Relationship::BELONGS_TO,
'foreign_key' => 'book_id',
'target_key' => 'id' // On authors table
],
// Alternatively you can pass another object
'title' => [
'type' => 'string'
]
]
}
}
// List books by an author
// Use `getMany` so an IDE/linter can get a clear hint that it's a set of records and not a single record
$books = $author->getMany ('books');
foreach ($books as $book) {
echo $book->get ('title');
}
// Find the author of a book
$author = $book->get ('author');
$author->get ('name');
?>