PHPackages                             momentphp/docs - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. momentphp/docs

ActiveLibrary[Framework](/categories/framework)

momentphp/docs
==============

MomentPHP | Framework documentation

11791HTML

Since May 11Pushed 10y ago1 watchersCompare

[ Source](https://github.com/momentphp/docs)[ Packagist](https://packagist.org/packages/momentphp/docs)[ RSS](/packages/momentphp-docs/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

MomentPHP is a lightweight and intuitive PHP mini-framework enabling modular app design. The *mini* prefix means that it can be put somewhere between micro and full-stack frameworks. It offers bare minimum of functionality required in order to create web sites and web applications. Most importantly it gives "structure" to your code, leaving free choice about inclusion of additional tools. It is built on top of well-known (amongst the PHP community) libraries and solutions:

- [Slim](http://www.slimframework.com/) micro-framework
- [Twig](http://twig.sensiolabs.org/) / [Smarty](http://www.smarty.net/) templating engines (both supported out of the box)
- components responsible for database access, configuration and caching from [Laravel](http://http://laravel.com/) framework
- [Composer](https://getcomposer.org/) dependency manager

The framework (as well as its building blocks) embraces popular web software design patterns such as:

- [Model-View-Controller](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)
- [Front Controller](https://en.wikipedia.org/wiki/Front_Controller_pattern)
- [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) / service container

Installation
============

[](#installation)

MomentPHP requires following software stack in order to run:

- a web server such as Apache or Nginx (read more about [web server setup](http://www.slimframework.com/docs/start/web-servers.html) in Slim's documentation)
- PHP 5.5.9 or above (works with PHP 7 too!)
- free [ionCube Loader](https://www.ioncube.com/loaders.php) module to be installed and made available to PHP (if you are looking for non-encoded version write an email - you can find relevant address at the bottom of homepage)
- [Composer](https://getcomposer.org/) dependency manager

It is also recommended (but not required) to enable following PHP modules:

- [mbstring](http://php.net/manual/en/book.mbstring.php)
- [intl](http://php.net/manual/en/book.intl.php)

Local setup
-----------

[](#local-setup)

Here is step-by-step guide on how to setup framework locally using [XAMPP](https://www.apachefriends.org/) on Windows:

- create project folder: `C:\xampp\htdocs\momentphp`
- within project folder issue following command (this will install app skeleton along with its dependencies):

```
composer create-project momentphp/app . --stability=dev
```

- create domain to serve the application (`momentphp.local` in this example). Do that by adding following vhost configuration inside `C:\xampp\apache\conf\extra\httpd-vhosts.conf`:

```

    DocumentRoot "C:\xampp\htdocs\momentphp\web"
    ServerName momentphp.local

        Options All
        AllowOverride All
        Require all granted

```

- add new domain definition to OS hosts file (`C:\WINDOWS\system32\drivers\etc\hosts`):

```
127.0.0.1 momentphp.local
```

- restart Apache web server

After completing above steps, point your browser to `http://momentphp.local` and you should see framework welcome page with some debug information.

Services
========

[](#services)

Put simply, a **service** is usually a PHP object that performs some sort of task such as sending emails, rendering templates or persisting information into a database. A **service container** (or dependency injection container) is a PHP object that manages the instantiation of services (with their dependencies). MomentPHP uses default service container provided by Slim - [Pimple](http://pimple.sensiolabs.org/). You can register and retrieve services via `$app` object (available as a property within framework classes), which is an instance of `momentphp\App` class.

Example ways of retrieving `config` service from the container via `$app` instance:

```
$app->get('/', function () { // inside route callable
    $config = $this->app->config;
});
$this->app->config // inside controller, model etc.
{{ this.app.config }} // inside Twig template
{$this->app->config} // inside Smarty template
```

You can also retrieve services using service container directly:

```
$config = $app->getContainer()->get('config');
// or
$app->get('/', function () {
    $config = $this->get('config');
});
```

There is also a global helper function `app()` which allows accessing services in the container. It can be used just about anywhere (for example in configuration files):

```
return [
    'compile' => path([app('pathStorage'), 'templates', 'smarty', app()->fingerprint()]),
]
```

Note that if you do not supply service name, the `app()` function will return application instance.

Registering services
--------------------

[](#registering-services)

In order to register a new service, it must be given a **name**. Service name should be unique and in [camelCase](https://en.wikipedia.org/wiki/CamelCase)format. You may use handy `momentphp\App::service()` helper method to register a service which returns **the same shared instance**of the object for all calls:

```
$app->service('someService', function ($container) {
    $otherService = $container->get('otherService'); // you may access other services in the container
    return new Object($otherService);
});
```

You may need to use service container directly in order to register non-shared services. For example if you want a **different instance** to be returned for all calls:

```
$app->service('someService', $app->getContainer()->factory(function ($container) {
    return new Object;
}));
```

You can also register **anonymous function as a service**. The function will be returned without being invoked:

```
$app->service('someService', $app->getContainer()->protect(function ($name) {
    return 'Hello ' . $name;
}));
```

In some cases you may want to **modify a service after it has been defined**:

```
$app->getContainer()->extend('someService', function ($service, $container) {
    $service->setParam();
    return $service;
});
```

Service providers
-----------------

[](#service-providers)

Service providers are classes responsible for registering services and are located inside `/providers` folder within bundle. Service provider class should extend `momentphp\Provider` and implement `__invoke()` method:

```
namespace bundles\welcome\providers;

class TestProvider extends \momentphp\Provider
{
    public function __invoke()
    {
        $this->app->service('test', function() {
            return 'Test Service';
        });
    }
}
```

Service providers are loaded via configuration. In order to load above service provider you must put following line in `/config/app.php`:

```
'providers' => [
    'test' => 'TestProvider',
],
```

You can also unload service provider loaded by previous bundle (see [Bundle inheritance](#bundles-bundle-inheritance)):

```
'providers' => [
    'test' => false
]
```

Note that you may put default service provider options in `/config/providers.php` and later access those options within the class via `$this->options()` - see [Instance configuration](#instance-configuration).

You may also implement `Provider::boot()` method. This method is called after all other service providers have been registered, meaning you have access to all other services that have been registered.

Important framework services
----------------------------

[](#important-framework-services)

Most framework features are buit as services. Important ones with their names and short descriptions are presented in the following table:

  name description   `$app->app` application instance (manages loaded bundles)   `$app->env` application environment name (`production`, `development`, etc.)   `$app->environment` server environment data   `$app->request` initial request object   `$app->response` initial response object   `$app->debug` application debug flag   `$app->console` application console flag   `$app->pathBase` application skeleton installation path   `$app->pathWeb` web server document root path   `$app->pathStorage` framework generated files path (logs, compiled templates, etc.)   `$app->config` object that manages configuration   `$app->registry` object that manages loaded "global" instances of various classes like models, controllers, etc.   `$app->database` object that manages database connections   `$app->cache` object that manages cache stores   `$app->log` object that manages loggers   `$app->router` object that manages routes   `$app->view` view object that allows to render templates   `$app->error` object that registers framework error handlers Bundles
=======

[](#bundles)

One of the most powerful features of MomentPHP is its bundles system. Bundles are mini-apps offering certain functionality. Have a great user management module, simple blog, or web services module in one of your applications? Package it as bundle so you can reuse it in other applications and share with the community. Your application can use multiple bundles.

Creating a new bundle
---------------------

[](#creating-a-new-bundle)

By default bundles are placed inside `/bundles` folder (assuming you are using [app skeleton](https://github.com/momentphp/app)). Each bundle should have its own **unique namespace**. If we were to create `helloWorld` bundle we should start by creating bundle class file `/bundles/helloWorld/Bundle.php` with following content:

```
namespace bundles\helloWorld;

class Bundle extends \momentphp\Bundle
{
}
```

The location of bundle class file determines bundle root folder. Within that folder you can place various bundle resources (configuration, routes, templates) and classes (models, controllers, etc.). Theoretically bundle can be placed anywhere in the filesystem as long as Composer's autoloader is able to locate bundle class file.

Each bundle has **an alias**, which is the lower-cased version of the bundle namespace where namespace separators (`\`) are replaced with dots:

  namespace alias   `bundles\helloWorld` `bundles.helloworld` Aliases are used across various framework parts - i.e. to load templates from specific bundle. You can get bundle object via `$app->bundles('bundles.helloworld')` method. Also you may alter default alias with custom one while loading bundle:

```
$app = new momentphp\App([
    bundles\helloWorld\Bundle::class => ['alias' => 'hello'],
]);
```

`momentphp\Bundle::boot()` callback is invoked (if implemented) just before response is sent to the client. It can be used to perform some logic (i.e. to set some global PHP settings):

```
namespace bundles\helloWorld;

class Bundle extends \momentphp\Bundle
{
    public function boot()
    {
        ini_set('memory_limit', '2048M');
    }
}
```

Bundle folder structure
-----------------------

[](#bundle-folder-structure)

  folder or file holds   `/config` configuration files   `/controllers` controllers classes   `/helpers` helpers classes   `/templates` templates   `/middlewares` middlewares classes   `/providers` providers classes   `/models` models classes   `routes.php` routes   `Bundle.php` bundle main class file Loading bundles
---------------

[](#loading-bundles)

Appliation loads bundles in main `index.php` file which serves as a front controller responding for all incoming requests:

```
$app = new momentphp\App([
    bundles\helloWorld\Bundle::class,
    ...
]);
```

While loading a bundle, apart from defining custom alias, you may choose to disable loading of certain resources or classes:

```
/**
 * Do not load configuration, routes and models from helloWorld bundle
 */
$app = new momentphp\App([
    bundles\helloWorld\Bundle::class => [
        'skipResource' => ['config', 'routes'],
        'skipClass' => ['models'],
    ],
]);
```

Bundle inheritance
------------------

[](#bundle-inheritance)

Bundle inheritance is one of the most powerful features of MomentPHP. As stated earlier application can use multiple bundles. The order in which bundles are loaded matters. Resources from previous bundle can be overriden in next bundle in chain. To illustrate this process let's assume that application loads two bundles:

```
$app = new momentphp\App([
    bundles\first\Bundle::class,
    bundles\second\Bundle::class
]);
```

### Configuration

[](#configuration)

In order to override configuration from `first` bundle you need to create config file with the same name in `second` bundle but only with options you wish to override (see [Configuration](#configuration)).

### Routes

[](#routes)

In order to override route from `first` bundle you need to create a route in `second` bundle with the same URL pattern but different handler (see [Routes](#routes)).

### Templates

[](#templates)

In order to override specific template from `first` bundle:

```
/bundles/first/templates/partials/post.tpl
```

create the template file with the same name in `second` bundle:

```
/bundles/second/templates/partials/post.tpl
```

See [Templates](#templates) for more information.

### Classes

[](#classes)

In order to override class-based resources (like [controllers](#controllers), [models](#models), etc.) create corresponding class file with the same name and extend suitable parent class:

```
namespace bundles\second\models;

class PostModel extends \bundles\first\models\PostModel
{
    public function index()
    {
        return parent::index();
    }
}
```

Configuration
=============

[](#configuration-1)

Configuration is stored in plain PHP files inside `/config` folder in each bundle. Each file should return an array of options. It is advisable to create separate file for each category of configuration options. If we would like to store API keys for our application we could create `/config/api.php` file with following content:

```
return [
    'Google' => [
        'Recaptcha' => [
            'publicKey' => 'fc2baa1a20b4d5190b122b383d7449fd',
            'privateKey' => '4f14fbe4af13860085e563210782da88'
        ]
    ],
    'Twitter' => 'f561aaf6ef0bf14d4208bb46a4ccb3ad'
];
```

Config service allows you to access above configuration values anywhere:

```
$app->config->get('api.Google.Recaptcha.publicKey'); // returns single key
$app->config->get('api'); // returns whole array
```

You may also specify a default value to return if the configuration option does not exist:

```
$app->config->get('api.Instagram', 'bf083d4ab960620b645557217dd59a49');
```

Configuration values can also be set at run-time:

```
$app->config->set('api.Yahoo', '241fe8af1e038118cd817048a65f803e');
```

There is also a handy method for checking existence of given configuration key:

```
$app->config->has('api.Github'); // false
```

Environment specific configuration
----------------------------------

[](#environment-specific-configuration)

It is often helpful to have different configuration values based on the environment the application is running in. By default application environment is set to `production`. You can change environment setting inside main `index.php` file:

```
$app = new momentphp\App([...], [
    'env' => 'development',
    'pathBase' => $pathBase,
    'pathWeb' => __DIR__,
]);
```

To override configuration for development environment (set above) simply create a folder within the `/config` directory that matches environment name. Next, create the configuration files you wish to override and specify the options for that environment. For example, to override the debug flag for the development environment, you would create a `/config/development/app.php` file with the following content:

```
return [
    'displayErrorDetails' => true
]
```

Default configuration file names
--------------------------------

[](#default-configuration-file-names)

Framework stores its configuration in a set of pre-defined files:

  file name description   `app.php` application configuration   `bundles.php` bundles configuration (see [Instance configuration](#instance-configuration))   `cache.php` cache stores configuration   `controllers.php` controllers/cells configuration (see [Instance configuration](#instance-configuration))   `database.php` database connections configuration   `helpers.php` helpers configuration (see [Instance configuration](#instance-configuration))   `loggers.php` loggers configuration   `middlewares.php` middlewares configuration (see [Instance configuration](#instance-configuration))   `models.php` models configuration (see [Instance configuration](#instance-configuration))   `providers.php` service providers configuration (see [Instance configuration](#instance-configuration)) Instance configuration
======================

[](#instance-configuration)

Many framework classes are using configuration capabilities provided by `momentphp\traits\OptionsTrait`. It provides clean solution for configuring instances without the need to create unnecessary class properties. Firstly you may hard code configuration inside a class:

```
class PostModel extends Model
{
    protected $defaults = [
        'listing' => [
            'perPage' => 10
        ]
    ];
}
```

Hard-coded options are merged with options passed to constructor function during object initialization. For [controllers](#controllers), [models](#models), [helpers](#templates-helpers), [service providers](#services-service-providers) and [middlewares](#middlewares) you can define configuration options passed to constructor by creating appropriate configuration file. For `PostModel` above we could create `/config/models.php` file with following content:

```
return [
    'Post' => [
        'listing' => [
            'perPage' => 20,
            'more' => true,
        ]
    ]
];
```

You can get and set model configuration after instance creation via `options()` method:

```
$this->Post->options('listing.perPage'); // get
$this->Post->options('listing.perPage', 5); // set
```

Models
======

[](#models)

Model classes in MVC pattern are responsible for providing controllers with data from various sources: databases, files on disk or even external web services. MomentPHP model classes are located inside `/models` folder within bundle.

Here is a simple example of a model definition from hypothetical `blog` bundle:

```
namespace bundles\blog\models;

class PostModel extends \momentphp\Model
{
    public function findAll()
    {
        return $this->db()->table('posts')->get();
    }

    public function findById($id)
    {
        return $this->db()->table('posts')->where('id', $id)->first();
    }
}
```

Within model methods, you can access database connection object via `momentphp\Model::db()` method. Please refer to Laravel's documentation on how to create simple and advanced queries using this object:

- [Database](http://laravel.com/docs/5.1/database)
- [Queries](http://laravel.com/docs/5.1/queries)

Note that connections are lazily loaded when they are needed so a model may not use database at all - and can talk to web service for instance.

Connections
-----------

[](#connections)

By default all model classes will use default database connection. In `/config/database.php` file within bundle you may define all of your database connections, as well as specify which connection should be used by default.

You may tell model class to use different connection by specifying `$connection` property:

```
class PostModel extends \momentphp\Model
{
    protected $connection = 'connection2';
}
```

Moreover, you can access just about any defined connection by passing it's name to `$this->db()` method:

```
$this->db('connection5')->table('posts')->where('id', $id)->first();
```

You may also access the raw, underlying [PDO](http://php.net/manual/en/book.pdo.php) instance following way:

```
$pdo = $this->db()->getPdo(); // inside model class
$pdo = $this->app->database->connection()->getPdo(); // via $app object elsewhere
```

Accessing models
----------------

[](#accessing-models)

You can access model instance via `$app->registry` service:

```
$this->app->registry->models->Post->findAll();
```

Above creates "global" model instance which is initialized with configuration from `/config/models.php`:

```
return [
    'Post' => [
        'perPage' => 25
    ]
]
```

If needed, you can create as many model instances as you wish manually via `momentphp\Registry::factory()` method. Using this way you must pass configuration in second param:

```
$Post = $this->app->registry->factory('PostModel', ['perPage' => 25]);
```

Inside controller and model classes you can access other models with more concise syntax:

```
$this->Post->findAll();
```

Model callbacks
---------------

[](#model-callbacks)

`momentphp\Model::initialize()` callback lets you perform some logic just after model creation:

```
class PostModel extends \momentphp\Model
{
    public function initialize()
    {
        // extecuted after model creation
    }
}
```

Caching model methods
---------------------

[](#caching-model-methods)

There is convenient caching mechanism built into model layer. By specifying `cache` key in model configuration you can control its behaviour:

```
return [
    'Post' => [
        'cache' => [
            'ttl' => 60 // cache all methods calls for 60 minutes
        ]
    ]
];
```

Following table shows a list of all supported options:

  option data type default value description   `store` `string` not set the name of cache store to use (will use default store if not set - see [Caching](#caching))   `enabled` `boolean` `true` cache method calls by default   `ttl` `integer` `30` default time to live (in minutes)   `ttlMap` `array` `30` maps method to ttl (in order to create non-default ttl for given method)   `cacheMethods` `array` `[]` list of methods to cache (if `enabled` is set to `false`)   `nonCacheMethods` `array` `[]` list of methods to no-cache (if `enabled` is set to `true`) Controllers
===========

[](#controllers)

Controllers classes are located under `/controllers` folder inside a bundle. In a typical scenario controller is responsible for interpreting the request data, making sure the correct models are called, and the right response or template is rendered. Commonly, a controller is used to manage the logic around a single model.

Controller actions
------------------

[](#controller-actions)

Methods inside controller class are called **actions**. You map incoming URL to given controller action by creating corresponding [route](#routes). Let's create simple route:

```
$app->get('/hello/{name}', 'HelloController:say');
```

and corresponding controller class:

```
namespace bundles\helloWorld\controllers;

class HelloController extends \momentphp\Controller
{
    protected function say($name)
    {
        return 'Hello ' . $name;
    }
}
```

Controller action must be `protected` and can return:

- a string (sent to browser as `text/html`)
- a response object
- nothing

In case nothing is returned from action default action template will be rendered: `/templates/controllers/Hello/say.twig`. You can specify which template should be rendered by interacting with controller's view object:

```
$this->view->template('say2'); // will render: /templates/controllers/Hello/say2.twig
// or
$this->view->template('/say2'); // will render: /templates/say2.twig
```

You can also force controller to use template from specific bundle (referenced by alias):

```
// following will render: /templates/controllers/Hello/say2.twig from "hello" bundle
$this->view->template('say2')->bundle('hello');
```

If client asks for JSON (or XML) and your application is using [NegotiationMiddleware](#middlewares-default-middlewares)templates are rendered in following manner:

```
// client asks for JSON
$this->view->template('say2'); // will render: /templates/controllers/Hello/json/say2.twig
// client asks for XML
$this->view->template('say2'); // will render: /templates/controllers/Hello/xml/say2.twig
```

The `momentphp\Controller::set()` method is the main way to send data from your controller to your template:

```
// send variable to the template inside controller action:
$this->set('color', 'pink');
// or
$this->view->set('color', 'pink');

// access variable inside a template
You have choosen {{ color }} color. // Twig
You have choosen {$color} color. // Smarty
```

The `set()` method also takes an associative array as its first parameter.

Controller callbacks
--------------------

[](#controller-callbacks)

If you need to perform some logic before or after controller action is invoked, you can use following callbacks:

```
class HelloController extends \momentphp\Controller
{
    public function beforeAction($action)
    {
        if ($action === 'say') {
            // extecuted before say() action
        }
    }

    public function afterAction($action)
    {
        if ($action === 'say') {
            // extecuted after say() action
        }
    }

    protected function say($name)
    {
        return 'Hello ' . $name;
    }
}
```

There is also `momentphp\Controller::initialize()` callback which is fired just after controller creation.

Request object
--------------

[](#request-object)

You can access current request object inside actions using `$this->request` property. You may fetch an associative array of query string parameters with `getQueryParams()` method. This method returns an empty array if no query string is present:

```
$queryParams = $this->request->getQueryParams();
```

To fetch request parameter value from body OR query string (in that order):

```
$foo = $this->request->getParam('foo'); // $_POST['foo'] or $_GET['foo']
$bar = $this->request->getParam('bar', 'default'); // setting default value if param not set
```

You can find more information about request object in [Slim’s](http://www.slimframework.com/) documentation:

- [Request object](http://www.slimframework.com/docs/objects/request.html)

Response object
---------------

[](#response-object)

You can access current response object inside actions using `$this->response` property. Response object can be returned from action. To return redirect response:

```
class HelloController extends \momentphp\Controller
{
    protected function say($name)
    {
        return $this->response->withRedirect('/login');
    }
}
```

To return [JSON](https://en.wikipedia.org/wiki/JSON) response:

```
class HelloController extends \momentphp\Controller
{
    protected function say($name)
    {
        return $this->response->withJson(['name' => $name]);
    }
}
```

To render 404 - page not found:

```
class HelloController extends \momentphp\Controller
{
    protected function say($name)
    {
        $this->abort();
    }
}
```

You can find more information about response object in [Slim’s](http://www.slimframework.com/) documentation:

- [Response object](http://www.slimframework.com/docs/objects/response.html)

Cells
-----

[](#cells)

Cells are small mini-controllers that can invoke view logic and render out templates. Cells are ideal for building reusable page components that require interaction with models, view logic, and rendering logic. A simple example would be the cart in an online store, or a data-driven navigation menu in a CMS. Cells do not dispatch sub-requests. Cells classes are placed under `/controllers/cells` folder within bundle.

Let's create sample `ShoppingCart` cell. Create cell class file `bundles/helloWorld/controllers/cells/ShoppingCartController.php`with following content:

```
namespace bundles\helloWorld\controllers\cells;

class ShoppingCartController extends \momentphp\Controller
{
    protected function display($items = 5)
    {
        // grab some data and set it to the template
    }
}
```

Our newly created cell may be invoked inside any template:

```
{{ this.cell('ShoppingCart') }} // Twig
{$this->cell('ShoppingCart')} // Smarty
```

You can also invoke any cell action and pass additional arguments:

```
{{ this.cell('ShoppingCart:display', 10) }} // Twig
{$this->cell('ShoppingCart:display', 10)} // Smarty
```

Cell templates are placed inside `/templates/controllers/cells` subfolder. In case no action is specified while invoking cell, `display` action will be invoked, rendering following template: `bundles/helloWorld/templates/controllers/cells/ShoppingCart/display.twig`.

Flash messages
--------------

[](#flash-messages)

Flash messages are one-time notifications displayed after processing a form or acknowledging data.

```
class ContactController extends \momentphp\Controller
{
    protected function form()
    {
        if ($this->request->isPost()) {
            if ($formIsOk) {
                // will be rendered using /templates/partials/flash/success.tpl
                $this->app->flash->success('Your message has been sent');
                return $this->response->withRedirect('/');
            } else {
                // will be rendered using /templates/partials/flash/error.tpl
                $this->app->flash->error('Please correct form errors');
            }
        }
    }
}
```

Messages are rendered inside template in following manner:

```
{$this->app->flash->render()} // Smarty
{{ this.app.flash.render() }} // Twig

```

Templates
=========

[](#templates-1)

Out of the box framework supports [Smarty](http://www.smarty.net/) and [Twig](http://twig.sensiolabs.org/) templating engines. Templating engines are exposed as services (named `smarty` and `twig` respectively) implementing a common interface and are configured inside `/config/providers.php`. You pick which service should be used by default by setting appropriate value inside `/config/app.php`:

```
[
    'viewEngine' => 'smarty'
]
```

Template files should be placed inside `/templates` folder within bundle. Templates should fall into pre-defined folders presented below:

  folder description   `/templates/controllers` templates for controllers actions   `/templates/partials` sub-templates - templates that are included by other templates   `/templates/layouts` layout templates The `this` variable inside templates represents `\momentphp\Template` instance and allows you to access various objects inside template file:

  Smarty Twig description   `{$this->app}` `{{ this.app }}` app object   `{$this->request}` `{{ this.request }}` request object   `{$this->Html}` `{{ this.Html }}` HtmlHelper object You can include template from specific bundle (referenced by alias - `hello` in following example) via following syntax:

```
{include file='[hello]partials/debugTable.tpl'} // Smarty
{% include '@hello/partials/debugTable.twig' %} // Twig

```

Helpers
-------

[](#helpers)

Helpers are classes for the presentation layer of your application. They contain presentational logic that is shared between many templates, partials or layouts. Helpers may assist in creating well-formed markup, aid in formatting text, times and numbers etc. Helper classes are placed under `/helpers` folder within bundle. Let's create sample `TextHelper`. Create class file under `bundles/helloWorld/helpers/TextHelper.php` with following content:

```
namespace bundles\helloWorld\helpers;

class TextHelper extends \momentphp\Helper
{
    public function uppercase($text)
    {
        return strtoupper($text);
    }
}
```

Now, the helper is ready to be used inside templates:

```
Here is uppercase post title: {$this->Text->uppercase($post.title)} // Smarty
Here is uppercase post title: {{ this.Text.uppercase(post.title) }} // Twig
```

Inside helper methods you may access:

```
$this->app // app object
$this->template // Template object
$this->template->request // request object
$this->template->vars // template variables
$this->options() // helper configuration set in "/config/helpers.php"
```

Routes
======

[](#routes-1)

Routes are a way to map URL-s to the code that gets executed only when a certain request is received at the server. Routes are defined in `/routes.php` file inside bundle. Each route consists of three elements:

- HTTP method
- URL pattern
- route handler

Here is sample route definition:

```
$app->any('/docs', 'DocsController:index');
```

With above definition, any HTTP request (`GET`, `POST`, `...`) to `/docs` URL will invoke handler - that is `DocsController::index()` method. Handler can also be defined as anonymous function which takes `$request`, `$response` and `$args` params:

```
$app->any('/docs', function ($request, $response, $args) {
    $debugFlag = $this->debug; // accessing $app->debug service
    return $response->write('Hello world');
});
```

Note that you will have access to the service container instance inside of the Closure via the `$this` keyword.

You can find more information about router and routes in [Slim's](http://www.slimframework.com/) documentation:

- [Router](http://www.slimframework.com/docs/objects/router.html)

Middlewares
===========

[](#middlewares)

Middleware is a callable which is invoked during application request/response lifecycle. Please find more detailed information about middleware in [Slim's](http://www.slimframework.com/) documentation:

- [Middleware](http://www.slimframework.com/docs/concepts/middleware.html)

In order to create simple `Auth` middleware create class file `/middlewares/AuthMiddleware.php` with content:

```
namespace bundles\helloWorld\middlewares;

class AuthMiddleware extends \momentphp\Middleware
{
    public function __invoke($request, $response, $next)
    {
        $cookies = $request->getCookieParams();
        if (!isset($cookies['auth'])) {
            return $response->withRedirect('/login');
        }
        return $next($request, $response);
    }
}
```

Middleware can be attached at application level via `app.middlewares.app` configuration key:

```
'middlewares' => [
    'app' => [
        'auth' => 'AuthMiddleware',
    ],
]
```

Also you can attach middleware only to certain routes via `app.middlewares.route` configuration key:

```
'middlewares' => [
    'route' => [
        'auth' => 'AuthMiddleware',
    ],
]
```

```
$app->any('/pages/{page:.+}', 'PagesController:display')->add('auth');
```

Default middlewares
-------------------

[](#default-middlewares)

By default MomentPHP ships with following middlewares:

  name description   `AssetsMiddleware`  Allows to serve bundle assets placed inside `/web` folder via properly constructed URL: `/bundles/{bundleAlias}/css/style.css`. Note that is's just a quick solution (files are served via PHP) and you should symlink your assets for performance reasons in production.    `NegotiationMiddleware` Will automatically switch response content type from HTML to JSON (or XML) if client asks for it. Events
======

[](#events)

Events allows objects to notify other objects and anonymous listeners about changes. For example you may define custom `user.create` event for your app which will be triggered when a new user signs up:

```
class UserModel extends \momentphp\Model
{
    public function create($data)
    {
        $id = $this->db()->table('users')->insertGetId($data);
        $this->app->eventsDispatcher()->fire('user.create', [$id]);
        return $id;
    }
}
```

Later other parts of your code can listen and act upon defined event:

```
namespace bundles\mailer;

class Bundle extends \momentphp\Bundle
{
    public function boot()
    {
        $this->app->eventsDispatcher()->listen('user.create', function ($userId) {
            // do something (send welcome email, etc.)
        });
    }
}
```

When you have multiple listeners to an event, sometimes you will want to stop the remaining listeners from running. To do that you can return `false` from the current listener.

Framework events
----------------

[](#framework-events)

Some core events are already defined by the framework. You can subscribe to them in the same way that you subscribe to your own custom events:

  event parameters   `model.{name}.initilize` (i.e. `model.Post.initialize`) `$model`   `controller.{name}.initilize` `$controller`   `controller.{name}.beforeAction` `$controller, $action`   `controller.{name}.afterAction` `$controller, $action` Note that Laravel’s components (database and cache) used by MomentPHP are also emitting some events. Please refer to Laravel’s documentation for more information:

- [Events](http://laravel.com/docs/5.1/events#framework-events)

Caching
=======

[](#caching)

MomentPHP uses caching component from Laravel framework. Cache manager instance is available as `cache` service. The cache configuration is located at `/config/cache.php`. In this file you may specify which cache driver you would like used by default throughout your application. By default, framework is configured to use the file cache driver, which stores the serialized, cached objects in the filesystem.

Storing an item in the cache:

```
$app->cache->put('key', 'value', $minutes);
```

Retrieving an item from the cache:

```
$app->cache->get('key', 'default'); // retrieving an item or returning a default value
```

Checking for existence in cache:

```
if ($app->cache->has('key'))
{
    //
}
```

Sometimes you may wish to retrieve an item from the cache, but also store a default value if the requested item doesn't exist. You may do this using the `remember()` method:

```
$value = $app->cache->remember('users', $minutes, function () use ($app) {
    return $app->registry->models->User->findAll();
});
```

When using multiple cache stores, you may access them via the `store()` method:

```
$value = $app->cache->store('foo')->get('key');
```

Please refer to Laravel’s documentation for more information about cache manager features:

- [Cache](http://laravel.com/docs/5.1/cache)

Logging
=======

[](#logging)

By default `log` service will use default logger. In `/config/loggers.php` file within bundle you may define all of your loggers, as well as specify which logger should be used by default. Framework uses popular [Monolog](https://github.com/Seldaek/monolog) library so under the hood each logger is an instance of `Monolog\Logger` class.

Adding records to the log:

```
$app->log->addDebug('Foo', ['some' => 'data']);
// or
$app->log->log(\Psr\Log\LogLevel::DEBUG, 'Foo', ['some' => 'data']);
```

You man access any configured logger via the `logger()` method:

```
$app->log->logger('error')->addDebug('Foo', ['some' => 'data']);
```

Error logging
-------------

[](#error-logging)

You may want to log PHP errors. In order to do so please set appropriate logger name in `/config/app.php`:

```
'error' => [
    'log' => 'error' // set to `false` to disable PHP errors logging
]
```

Error handling
==============

[](#error-handling)

MomentPHP converts all PHP errors to exceptions. You can set PHP error reporting level by setting `app.error.level` configuration key to appropriate value:

```
'error' => [
    'level' => -1 // report all errors
]
```

By default framework will display all errors as exceptions using the [Whoops!](http://filp.github.io/whoops/) package if the `app.displayErrorDetails`switch is turned on OR hide them and use `ErrorController` to render client-friendly messages if the switch is turned off.

The value of `app.displayErrorDetails` configuration setting is available as a `$app->debug` service.

To sum up - setting `app.displayErrorDetails` to `false` changes the following types of things:

- PHP errors are not displayed
- uncaught exceptions and fatal errors will render default internal server error page - using `ErrorController::error()`
- uncaught `\Slim\Exception\NotFoundException` will render default not found page - using `ErrorController::notFound()`
- templates are not re-compiled when changed

Command line
============

[](#command-line)

MomentPHP application can also be invoked in command line mode. This comes handy when you need to setup some background processing tasks invoked by cron daemon for instance.

First, setup a `GET` route in `/routes.php`:

```
if ($app->console) {
    $app->get('/background/task', function($request, $response, $args) {
        // perform some tasks using models etc.
        ...
    });
}

```

Then, issue following command (where `index.php` is application's front controller):

```
php index.php background/task

```

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/a7c918f54bb848b1ab6ac0f623e0aba72e565865aa15b77b4e7eeba354e38256?d=identicon)[kminek](/maintainers/kminek)

---

Top Contributors

[![kminek](https://avatars.githubusercontent.com/u/373962?v=4)](https://github.com/kminek "kminek (52 commits)")

### Embed Badge

![Health badge](/badges/momentphp-docs/health.svg)

```
[![Health](https://phpackages.com/badges/momentphp-docs/health.svg)](https://phpackages.com/packages/momentphp-docs)
```

###  Alternatives

[laravel/passport

Laravel Passport provides OAuth2 server support to Laravel.

3.4k85.0M532](/packages/laravel-passport)[nolimits4web/swiper

Most modern mobile touch slider and framework with hardware accelerated transitions

41.8k177.2k1](/packages/nolimits4web-swiper)[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k36.7M259](/packages/laravel-dusk)[laravel/prompts

Add beautiful and user-friendly forms to your command-line applications.

712181.8M596](/packages/laravel-prompts)[cakephp/chronos

A simple API extension for DateTime.

1.4k47.7M121](/packages/cakephp-chronos)[laravel/pail

Easily delve into your Laravel application's log files directly from the command line.

91545.3M590](/packages/laravel-pail)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
