The Get Things Done

PHP Framework

Simle, Fast, Flexible.

Class cProducts extends OObject{

	// output a list of products as HTML view
	public function outList( $params=array() ){
		$products = $this->route('/m/mProducts/get/?with=inventory|images|categories')->data;
		include 'views/vProductsList.php';
		$this->html = ob_get_clean();

Born from pure necessity to get things done.


Nothing to install, nothing to compile, and no commands to memorize. At it's core there are only four files, yet all the functionality you need to build complex applications.


Because Obray is simple there is little between your application and the raw power of PHP. It also means you have to less to learn to get your application off the ground.


Be creative. The right balance of flexibility and structure to allow you to unlock your creative prowess and create the application that only exist in your thoughts.

Download GitHUB    Get Started

No Nonsense Routing

OObject Route

// Setup a few routes in your settings file
define('__OBRAY_ROUTES__',serialize( array(
	// Custom Routes
	"m" => dirname(__FILE__)."/models/",
	// System Routes
	"obray" => __OBRAY_PATH_TO_CORE__
) ));

Set it up Once, Leave it Alone

Once you setup your initial routes just drop your OObject class files in the directory structure you want. No need to create a new route for every new class you write. That's right, even if you want to organize them in subdirectories!

// put mProducts in models directory and route it like this:
$products_obj = $this->route('/m/mProducts/');

// or put in a cart subdirectory with mProducts in it and route like this:
$product_obj = $this->route('/m/cart/mProducts/');

// call you class functions like this:
$products = $product_obj->get()->data; // get all products

// or a shortcut to create your object and get your products
$products = $this->route('/m/cart/mProducts/get')->data;

There's a lot more to routing see be sure to learn more.

Nuts and Bolts ORM


// write a simple ODBO class with a table definition

Class mProducts extends ODBO{

	public function __construct(){
		$this->table = 'products';
		$this->tabel_definition = array(
			'id' =>			array( 'primary_key'=>TRUE ),
			'title' =>		array( 'data_type'=>'varchar(255)' ),
			'description' =>	array( 'data_type'=>'text'  ),
			'price'=>		array( 'data_type'=>'float' ),
			'quantity'=>		array( 'data_type'=>'integer' )

Write a Little, Do a Lot

After providing a table definition you can call add, update, get, delete, and more to modify and access your database:

// returns array of products
$products = $this->route('/m/mProducts/get/')->data;

// adds a product to db
$product = $this->route('/m/mProducts/add/',array(
	'title' => 'My Test Product',
	'description' => 'Description for my test product.',
	'price' => 9.98,
	'quantity' => 10

// update your new product
$product = $this->route('/m/mProducts/update/',array(
	'id' => $product->id,
	'title' => 'My Test Product with New Title',

// delete your new product
$product = $this->route('/m/mProducts/delete/',array(
	'id' => $product->id

There's even more to ODBO like "with" and math functions.

Manage Your Users


// extend Obray's native user management class and control external access to routes

Class mUsers extends OUsers{


Make Routes Available for External Consumption

Add a permissions array to your OObject or ODBO class and define what user level has access to what routes.

// add permission array to mProducts
$this->permissions = array(
	'object' => 'any',	// make object accessible to everyone
	'get' => 'any',
	'add' => 1		// restrict add to only users with permission level 1

With this permission array you can now access your route with an external request, like from a browser: http://mysite/m/mProducts/get/, outputs as content-type applicaiton/json:

	"object": "mProducts",
	"data": [
			"title":"My Test Product",
			"description": "This is a description of my test product.",
			"price": 9.98,
			"quantity": 1
	"recordcount": 1,
	"runtime": 1.01ms

Any attempt to call add without first logging in will result in the request being rejected, but otherwise you can quickly rollout a publicly accessible JSON feed or a private API.