dev-master
9999999-dev http://swiftlet.orgQuite possibly the smallest MVC framework you'll ever use.
MIT
The Requires
- php >=7
by Elbert Alias
framework
Swiftlet is quite possibly the smallest MVC framework you'll ever use. And it's swift., (*1)
Licensed under the MIT license., (*2)
โ Micro-Framework
โ Loosely coupled
โ Unit tested
โ Namespaced
โ Pluggable
โ Composer
โ PSR-4
โ PHP7
โ MVC
โ OOP, (*3)
โ ORM, (*4)
composer dump-autoload
.Let's create a page. Each page consists of a controller and at least one view., (*5)
The controller does most of the work; views should be limited to simple presentation logic (loops and switches)., (*6)
Controller src/HelloWorld/Controllers/Foo.php
, (*7)
view->helloWorld = 'Hello world!'; } } ``` Important: class names are written in [CamelCase](http://en.wikipedia.org/wiki/CamelCase) and match their filename. **View `views/foo.php`** ```php= $this->pageTitle ?></h1>
= $this->helloWorld ?> , (*8)
The controller can set variables directly on the view. Values are automatically
made safe for use in HTML, use $this->get('variable', false)
on values that
should be treated as code., (*9)
You can now view the page by navigating to http://<swiftlet>/foo
in your web
browser!, (*10)
If you get a "404 Not Found" you will need to enable rewrites in the web server
configuration. Alternatively you can navigate to http://<swiftlet>?q=foo
., (*11)
Swiftlet can be invoked from the command line (e.g. to run cron jobs). Simply
run php public/index.php -q foo
., (*12)
Notice how you can access the page at /foo
by simply creating a controller
named Foo
. The application maps URLs to controllers, actions and arguments., (*13)
Consider this URL: /foo/bar
, (*14)
In this case foo
becomes the name of the controller and view and bar
the
name of the action. Actions are public methods on the controller class., (*15)
You can specify a different view for an action using $this->view->setName()
.
The view name is a filename relative to the src\<namespace>\views
directory,
without the .php
suffix., (*16)
If the controller or action is not specified they default to index
(/
will call index()
on \HelloWorld\Controller\Index
)., (*17)
Underscores in the controller name are translated to directory separators, so
/foo_bar
will point to src/HelloWorld/Controllers/Foo/Bar.php
., (*18)
Dashes in routes are ignored; /foo-bar/baz-qux
calls bazqux()
on
\HelloWorld\Controllers\Foobar
., (*19)
Custom routes, (*20)
Automatic routing is convenient but more granular control is often desirable. In these cases custom routes can be defined., (*21)
A route maps a URL to an action (method)., (*22)
URL segments can be replaced with a "wildcard" placeholder (a variable name prefixed with a colon). This value becomes available for use in the controller., (*23)
Consider this route: bar/:qux
, (*24)
Navigating to <controller>/bar/something
matches this route. The value of
$args['qux']
becomes something
., (*25)
<?php namespace HelloWorld\Controllers; use \Swiftlet\Abstracts\Controller as ControllerAbstract; class Foo extends ControllerAbstract { protected $routes = array( 'hello/world' => 'index', 'bar/:qux' => 'bar' ); public function index(array $args = []) { // You navigated to foo/hello/world } public function bar(array $args = []) { // You navigated to foo/bar/<something> // $args['qux'] contains the second URL argument } }
Let's throw a model into the mix and update the controller., (*26)
Model src/HelloWorld/Models/Foo.php
, (*27)
<?php namespace HelloWorld\Models; use \Swiftlet\Abstracts\Model as ModelAbstract; class Foo extends ModelAbstract { public function getHelloWorld() { return 'Hello world!'; } }
Controller src/HelloWorld/Controllers/Foo.php
, (*28)
<?php namespace HelloWorld\Controllers; use \Swiftlet\Abstracts\Controller as ControllerAbstract; use \HelloWorld\Models\Example as ExampleModel; class Foo extends ControllerAbstract; { protected $title = 'Foo'; public function index() { // Get an instance of the Example class // See src/HelloWorld/Models/Example.php $example = new ExampleModel; $this->view->helloWorld = $example->getHelloWorld(); } }
A model typically represents data. This can be an entry in a database or an object such as a user., (*29)
<?php use \HelloWorld\Models\User as UserModel; $user = new UserModel; $user->setEmail('example@example.com'); $user->save();
Loading and saving data should almost always happen in a model. You can create as many models as you like; they aren't tied to controllers or views., (*30)
Listeners listen for events. When an event is triggered all relevant listeners are called and can be used to extend functionality., (*31)
Swiftlet has a few core events and additiontal ones can be triggered pretty much
anywhere using $this->app->trigger($event)
., (*32)
Listener src/HelloWorld/Listeners/Foo.php
, (*33)
<?php namespace HelloWorld\Listeners; use \Swiftlet\Abstracts\Controller as ControllerAbstract; use \Swiftlet\Abstracts\Listener as ListenerAbstract; use \Swiftlet\Abstracts\View as ViewAbstract; class Foo extends ListernerAbstract { public function actionAfter(ControllerAbstract $controller, ViewAbstract $view) { // Overwrite our previously set "helloWorld" variable $view->helloWorld = 'Hi world!'; } }
This listener listens for the core actionAfter
event and changes the view
variable helloWorld
from our previous example to Hi world!
., (*34)
Listeners don't need to be installed or activated, all files in the
src/HelloWorld/Listeners/
directory are automatically included and their
classes instantiated. Listeners are called in alphabetical order., (*35)
The core events are:, (*36)
actionBefore
Called before each action, (*37)
actionAfter
Called after each action, (*38)
Reusable components such as code to send an email or generate a thumbnail image should go in a separate library class., (*39)
<?php use \HelloWorld\Libraries\Email as EmailLibrary; $email = new EmailLibrary; $email->send($to, $subject, $message);
No configuration is needed to run Swiftlet. If you're writing a model that
does require configuration, e.g. credentials to establish a database connection,
you may use the application's setConfig
and getConfig
methods:, (*40)
<?php $this->app->setConfig('variable', 'value'); $value = $this->app->getConfig('variable');
Values can be set in config/main.php
or a custom file., (*41)
Application Swiftlet\App
, (*42)
App dispatchController()
Determine which controller to use and run it, (*43)
App serve()
Serve the page, (*44)
mixed getConfig(string $variable)
Get a configuration value, (*45)
App setConfig(string $variable, mixed $value)
Set a configuration value, (*46)
App registerHook(string $hookName, array $params)
Register a hook, (*47)
View Swiftlet\View
, (*48)
mixed get(string $variable [, bool $htmlEncode = true ])
Get a view variable, encoded for safe use in HTML by default, (*49)
View set(string $variable [, mixed $value ])
Set a view variable, (*50)
mixed get(string $variable [, bool $htmlEncode ])
Get a view variable, pass false
as the second parameter to prevent values from
being HTML encoded., (*51)
string getRootPath()
Absolute client-side path to the website root, (*52)
mixed htmlEncode(mixed $value)
Recursively make a value safe for HTML, (*53)
mixed htmlDecode(mixed $value)
Recursively decode a previously encoded value to be rendered as HTML, (*54)
View render(string $path)
Render the view, (*55)
Quite possibly the smallest MVC framework you'll ever use.
MIT
framework