PHPackages                             shift/shift - 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. shift/shift

ActiveLibrary[Framework](/categories/framework)

shift/shift
===========

A event-driven MOVE framework

109[3 issues](https://github.com/wouterj/shift-php/issues)PHP

Since Jan 3Pushed 12y ago4 watchersCompare

[ Source](https://github.com/wouterj/shift-php)[ Packagist](https://packagist.org/packages/shift/shift)[ RSS](/packages/shift-shift/feed)WikiDiscussions master Synced 3d ago

READMEChangelogDependenciesVersions (1)Used By (0)

ShiftPHP
========

[](#shiftphp)

Welcome at ShiftPHP, a very simple event driven, MOVE oriented framework for PHP.

Installation
------------

[](#installation)

Install the ShiftPHP framework using Composer:

```
$ php composer.phar require shift/shift:0.*

```

MOVE
----

[](#move)

ShiftPHP is MOVE oriented: Model, Operation, View and Events. To learn more about this, see "[MVC is dead, it's time to MOVE on](http://cirw.in/blog/time-to-move-on.html)".

Usage
-----

[](#usage)

The core framework doesn't provide the things you would expect. It only provides an Event Dispatcher and some facades for it. This means you can do everything you want and you can use everything you want. The standard Shift Edition provide integration with some Symfony components, but you can also use it with other tools.

The main facade is `Event`, the three others (`Operation`, `Model` and `Application`) provides shortcuts for this facade.

### Application

[](#application)

Make sure you always boot your application before using it, booting it makes sure the Event Dispatcher is added to the `Event` facade. To boot it, use `Application::boot()`:

```
use Wj\Shift\Facade\Application;

Application::boot();

```

### Event

[](#event)

Use `Event::on($event_name)` to attach a listener to an event. This returns an `AttachingEvent`, on which you must set the target (using `->asA` / `->asAn`) and the listeners (using `->call`). A target is the context of the event, for instance a class name or class type. The listener can be any kind of callable:

```
use Wj\Shift\Facade\Event;

Event::on('some_event')->forA('the_target')->call(function ($event) {
    // ... do something nice
});

```

Use `Event::trigger($event_name)` to trigger an event, this will call all its listeners. This method returns a `TriggeringEvent`, on which you must set the target (`->forA` / `->forAn`) and the event class (can be `null`):

```
use Wj\Shift\Facade\Event;

$event = new SomeEvent();
// ... set up event class

Event::trigger('some_event')->forA('the_target')->with($event);

```

### Operation

[](#operation)

Operations are executed when a certain event is called, use `Operation::on()` to attach an operation to an event. This returns an `AttachingEvent` which has set the target to `operation`. You are able to change this.

```
use Wj\Shift\Facade\Operation;

Operation::on('some_event')->call(function ($event) {
    // ... perform an operation
});

```

### Model

[](#model)

Models also listen to events and can be attached using `Model::on()`. This returns an `AttachingEvent` with the target set to `model`.

```
use Wj\Shift\Facade\Model;

Model::on('some_event')->call(function ($event) {
    // ... do some modelish things
});

```

### View

[](#view)

Views also listen to events and can be attached using `View::on()`. This returns an `AttachingEvent` with the target set to `view`.

```
View::on('some_event')->call(function ($event) {
    // ... render view
});

```

### Operators

[](#operators)

Operators are classes which holds multiple operations. Operator classes implement `Wj\Shift\Operator\OperatorInterface`. This requires a static method called `getOperations` which returns an array of methods and events to listen to:

```
namespace Acme\Operator;

use Wj\Shift\Operator\OperatorInterface;

class UserOperator implements OperatorInterface
{
    public static function getOperations()
    {
        return array(
            // key is the event and value is the method
            'save_user' => 'onSaveUser',
            // you can also attach multiple methods to one event
            'find_user' => array('onFindUser', 'onSecondFindUser'),
        );
    }
}

```

After this, you can register the Operator using `Operation::add()`:

```
Operation::add('Acme\Operator\UserOperator');

```

Bundles
-------

[](#bundles)

Operators can also be grouped/bundled into bundles. This means you can easily activate multiple bundles. A bundle must implement `Wj\Shift\Bundle\BundleInterface`. This requires one method called `getOperators` which must return a list of classnames.

ShiftPHP provides a basic `Bundle` class, which searches for `*Operator.php` files in the root of the bundle and checks if the class in there implements the `OperatorInterface`.

A common bundle looks like:

```
namespace Amce\Bundle\DemoBundle;

use Wj\Shift\Bundle\Bundle;

class AcmeDemoBundle implements Bundle
{ }

```

To register a bundle, use `Application:registerBundle()`:

```
Application::registerBundle(new \Acme\Bundle\DemoBundle\AcmeDemoBundle());

```

Contributing
------------

[](#contributing)

A framework can only get good with the contributions of other people. Issues, discussions and pull requests are very welcome! There are not many rules, as long as you stick to the [Symfony Standards](http://symfony.com/doc/current/contributing/code/standards.html).

License
-------

[](#license)

The Shift framework is licensed under the MIT license.

###  Health Score

21

—

LowBetter than 19% of packages

Maintenance14

Infrequent updates — may be unmaintained

Popularity11

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.9% 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/e6155db5d38999238ba21fc58a9e613adb354d846f6e74936dfd7fd505fb48bd?d=identicon)[Wouter J](/maintainers/Wouter%20J)

---

Top Contributors

[![wouterj](https://avatars.githubusercontent.com/u/749025?v=4)](https://github.com/wouterj "wouterj (86 commits)")[![lucapette](https://avatars.githubusercontent.com/u/124274?v=4)](https://github.com/lucapette "lucapette (1 commits)")

### Embed Badge

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

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

###  Alternatives

[laravel/telescope

An elegant debug assistant for the Laravel framework.

5.2k67.8M192](/packages/laravel-telescope)[spiral/roadrunner

RoadRunner: High-performance PHP application server and process manager written in Go and powered with plugins

8.4k12.2M84](/packages/spiral-roadrunner)[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.

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

A simple API extension for DateTime.

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

PHPackages © 2026

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