BwFramework
- a lightweight MVC framework for PHP
If you're not familiar with the MVC pattern, I recommend you to read up on that before continue reading here. Still here? Ok, lets show you an example.
File structure:
/approot/
/application/
/controllers/
IndexController.php
/models/
/* Your models here */
/views/
top.tpl
bottom.tpl
/index/
index.tpl
/BwFramework/
/* Framework files */
/www/
/javascripts/
mootools-1.2.4-yc.js
default.js
/stylesheets/
default.css
.htaccess
index.php
The IndexController.php:
<?php /* All controllers should inherit from the base Controller. The IndexController is the default controller of the application, when a client visits http://www.domain.com/ the default controller is called (IndexController) and the default action (indexAction()) */ class IndexController extends Controller { /* Those of you familiar with Zend Framework recognizes this. This is the default action of the controller. */ public function indexAction () { $this->assign ('pageTitle', 'BwFramwork demo'); $this->assign ('pageHeading', 'Demo of BwFramework!'); } }
Smarty global template, top.tpl
<html>
<head>
<title>{$pageTitle}</title>
</head>
<body>
Smarty global template, bottom.tpl
</body>
</html>
Smarty indexAction template, index/index.tpl
{include file="../top.tpl"} <h1>{$pageHeading}</h1> <p>Welcome!</p> {include file="../bottom.tpl"}
For the framework to work appropiatly, we have to enable URL rewriting in our .htaccess file. The file named "rename to .htaccess" should be renamed to ".htaccess" before you continue. In .htaccess, just pass all incoming traffic to index.php, unless a specific file was requested.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L]
Now we have one controller ready, lets tie it all up - time to see index.php
<?php /* Before doing anything else, BwFramework requires some defined constants for correct paths to your application files */ define ('APP', realpath ('../application/')); define ('FRAMEWORK', realpath ('../BwFramework/')); /* Now we need to get the main file of BwFramework, and lets set the include path to point to our BwFramework folder */ set_include_path (get_include_path () . PATH_SEPARATOR . FRAMEWORK); /* Instantiate, initialize and dispatch the requested controller. The init()-method of BwFramework reads the request and serves the appropiate controller (or the ErrorController if no matching controller was found). */ $bw = new BwFramework (); /* For development environment, with FirePHP active: */ $bw->environment (BwFramework::$DEV); /* For production environment, with FirePHP inactive: */ $bw->env (BwFramework::$PRODUCTION); $bw->init (); $bw->dispatch ();
Adding more controllers
It's easy to add more controllers, just create your controller in
APP/controllers/
and add the appropriate views in
APP/views/controller-name/
<?php
class GalleryController extends Controller {
/*
The init()-method in a controller is always executed
before any *Action()-method.
*/
public function init () {
$this->assign ("pageTitle", "You're in the gallery!");
}
public function indexAction () {
/*
If no call to assign() is made, the framework won't
look for a view. Instead, the *Action()-method is treated
as a void-returning function.
*/
echo 'No content here';
}
public function imagesAction () {
/*
Since we're using Smarty, assignments can be made to
objects, arrays, or anything you'd like!
*/
$this->assign ('images', $myDAL->getImages ());
}
public function videosAction () {
/*
The base Controller supply the controllers with a
redirect method,
redirect ([string controller [, string action [, array variables]]])
A call to redirect() without any parameters, redirects
the client to http://www.domain.com/
The following call to redirect() will redirect the
client to http://www.domain.com/videos/show
- i.e. the showAction() in the VideosController
*/
$this->redirect ('videos', 'show');
}
}
GET-variables - where did they go?!
- or SEO friendly URLs
The URL structure of BwFramework is the following:
http://www.domain.com/controller/action/param_0/param_1/.../param_n
or
http://www.domain.com/videos/play/my_cat_kisses_my_dog (1)
or
http://www.domain.com/users/view/sweden/bjrn (2)
The URL example (1) would point to the playAction() in the VideosController class. To obtain the first parameter (value: my_cat_kisses_my_dog), a call to the controller method getParam() should be made. Controller example:
<?php // URL: http://www.domain.com/videos/play/my_cat_kisses_my_dog class VideosController extends Controller { public function playAction () { /* The parameters are indexed in the order of the URL */ $videoName = $this->getParam(0); // $videoName=='my_cat_kisses_my_dog' $video = $myDAL->getVideoByName($videoName); $this->assign ('video', $video); } }
The URL example (2) would point to the viewAction() in the UsersController class. Controller example:
<?php // URL: http://www.domain.com/users/view/sweden/bjrn class UsersController extends Controller { public function viewAction () { $country = $this->getParam(0); // $country=='sweden' $username = $this->getParam(1); // $username=='bjrn' $stmt = $pdoObject->prepare (" SELECT id, email, firstname FROM Users WHERE country=:country AND username=:username "); $stmt->bindParam (":country", $country); $stmt->bindParam (":username", $username); ... } }
URL Rewriting
BwFramework has a nice feature for URL rewrites, where you can match a URL-part to a certain controller and action.
An example: Say you want to load the VideoController (http://www.domain.com/video) when people request http://www.domain.com/youtube. Instead of creating yet a controller (YoutubeController) you can simply tell BwFramework that all requests to /youtube should be handled in the VideoController. This is done in index.php:
<?php define ('APP', realpath ('../application/')); define ('FRAMEWORK', realpath ('../BwFramework/')); set_include_path (get_include_path () . PATH_SEPARATOR . FRAMEWORK); $bw = new BwFramework (); /* Create an array to define the rewrites, alias as key and controller as value */ $rewrites = array ( 'youtube' => 'video' ); /* Then pass the rewrites array to BwFramework: */ $bw->setURIRewrites ($rewrites); $bw->init (); $bw->dispatch ();
The same goes for actions. If you want to load the showAction() in VideoController (http://www.domain.com) when people request http://www.domain.com/video/play, you simply put another URL rewrite rule in index.php. Or if you want to load the showAction() in VideoController when your visitors request http://www.domain.com/youtube, you simply specify a rule:
<?php define ('APP', realpath ('../application/')); define ('FRAMEWORK', realpath ('../BwFramework/')); set_include_path (get_include_path () . PATH_SEPARATOR . FRAMEWORK); $bw = new BwFramework (); $rewrites = array ( 'video/play' => 'video/show', 'youtube' => 'video/show' ); $bw->setURIRewrites ($rewrites); $bw->init (); $bw->dispatch ();
Now your visitors can request either http://www.domain.com/video/play, http://www.domain.com/video/show or http://www.domain.com/youtube to access the showAction() method in your VideoController!