PHPackages                             pyrsmk/lumy - 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. pyrsmk/lumy

Abandoned → [pyrsmk/lumy3](/?search=pyrsmk%2Flumy3)ArchivedLibrary[Framework](/categories/framework)

pyrsmk/lumy
===========

A minimal CLI/HTTP framework

2.9.3(9y ago)2391MITPHPPHP &gt;=5.4.0

Since Jan 28Pushed 9y ago1 watchersCompare

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

READMEChangelog (3)Dependencies (4)Versions (14)Used By (0)

Lumy 2.9.3
==========

[](#lumy-293)

**Lumy 2 repository is now unmainted in favor of [Lumy 3](https://github.com/pyrsmk/Lumy3). This new version is a big turn since the whole framework has been replaced by [Slim](http://www.slimframework.com). We just kept a little wrapper around Slim to be able to use [Chernozem](https://github.com/pyrsmk/Chernozem) too.**

Lumy is a [minimal](https://en.wikipedia.org/wiki/Minimalism_(computing)) micro CLI/HTTP framework that aims to be quick, effective and simple to extend as you want with any external component. It is heavily based on [Chernozem](https://github.com/pyrsmk/Chernozem) to provide an efficient way for dependencies injection.

Lumy is born with the fact that micro-frameworks, like [Silex](http://silex.sensiolabs.org/) or [Slim](http://slimframework.com/), are still too big and handle behaviors that can be managed by many existing libraries. They're often too web-oriented too : PHP is also great with CLI environment.

It is shipped with a CLI/HTTP router, environment objects and a middleware stack.

Install
-------

[](#install)

Pick up the source or install it with [Composer](https://getcomposer.org/) :

```
composer require pyrsmk/lumy

```

If you're not installing it with Composer, don't forget to load its dependencies too : [Chernozem](https://github.com/pyrsmk/Chernozem), [LongueVue](https://github.com/pyrsmk/LongueVue).

A quick example
---------------

[](#a-quick-example)

```
$lumy=new Lumy\Http;

// Add a middleware to configure our template engine (with [Twig](http://twig.sensiolabs.org/))
$lumy->middleware(function($middlewares) use($lumy){
    $lumy['twig']=new Twig_Environment(
        new Twig_Loader_Filesystem($lumy['dirs']['templates']),
        $options
    );
    $middlewares->next();
});

// Add a basic route that do nothing but display our index page
$lumy->get('/',function() use($lumy){
    // Provide a rooturi variable to the template is really useful for CSS, images, scripts inclusion
    echo $lumy['twig']->render('index.tpl',array(
        'rooturi' => $lumy['environment']->getRootUri()
    ));
});

// Specify an error handler, throwed when an exception has been catched
$lumy->error(function($e) use($lumy){
    echo $lumy['twig']->render('error.tpl',array(
        'rooturi' => $lumy['environment']->getRootUri(),
        'message' => $e->getMessage()
    ));
});

// Run the application and print the response body
echo $lumy->run();
```

Basics
------

[](#basics)

The Lumy object is a singleton and can be retrieved/instantiated with :

```
$lumy=Lumy\Http::getInstance();
```

### Adding CLI routes

[](#adding-cli-routes)

The basic way to add a route in a CLI environment is :

```
$lumy->route('--help',function(){
    // Will print 'Some help' when the 'your_app --help' command is called
    echo 'Some help';
});
```

We can specify an array of route chains :

```
$chains=array('--help','-h');
$lumy->route($chains,function(){
    echo 'Some help';
});
```

Since the routing system is based on [LongueVue](https://github.com/pyrsmk/LongueVue), we can use slugs to extract options :

```
$lumy->route('install {directory}',function($directory){
    // Some actions
});
```

There're cases where we need to verify if the command syntax is valid. We can achieve it by using regexes to validate the command. If the specified regex does not match the route neither :

```
$lumy->route('remove user {id}',function($id){
    // Some actions
},array(
    'directory' => '\d+'
));
```

There're also some other cases where we want to have a default value from some of our slugs :

```
// The 'show' command will show tables by default
$lumy->route('show {arg}',function($arg){
    // Some actions
},array(
    'arg' => 'databases|tables'
),array(
    'arg' => 'tables'
));
```

### Adding routes with HTTP environment

[](#adding-routes-with-http-environment)

HTTP routes work the same as in CLI context but the `route()` method has been replaced in favor of `get()`, `post()`, `put()` and `delete()`. Here's some examples to clarify the situation :

```
$lumy->get('/gallery',function(){
    // Display the gallery
});

$lumy->put('/gallery',function(){
    // Add a new picture
});

$lumy->delete('/gallery/{id}',function($id){
    // Delete the specified picture
});
```

Please note that `PUT` and `DELETE` requests work like the `POST` request. Their data will be available from the `$_POST[]` array. If you need to add a custom route, use the `map()` method :

```
$lumy->map('SEARCH','/gallery/{terms}',function($terms){
    // Display the gallery
});
```

The HTTP context adds some new constants to ease the writing of routes :

- `%scheme%` : matches `http` and 'https'
- `%host%` : matches the current host
- `%requesturi%` : matches the request URI (it's the root URI plus the resource URI)
- `%rooturi%` : matches the root URI (everything between the host and the relative path of your website)
- `%resourceuri%` : matches the resourceuri URI (the specific URI that belongs to your website)

```
$lumy->get('%scheme%://{user}.mywebsite.com/profile',function($user){
    // Show the requested user profile
},array(
    'user' => '\w+'
));
```

If needed, you can assemble an URL using a predefined route :

```
// Name the route to register
$lumy->get('/gallery/{id}',function(){
    // Some actions
},null,null,'gallery');

// ...

// Assemble an URL to include to your page/template
// This will print '/gallery/72'
echo $lumy->assembleUrl('gallery',array('id'=>72));
```

As you may already guess, the HTTP context makes REST requests. But the `PUT` and `DELETE` requests are [not supported in HTML](https://programmers.stackexchange.com/questions/114156/why-are-there-are-no-put-and-delete-methods-on-html-forms). So, to know which request is sent, Lumy watch the `$_POST['_METHOD']` variable for the method to use. Add an `` in your form. There's also a [library](https://github.com/pyrsmk/RIP) that simplifies the whole thing by making synchroneous REST requests on-the-fly.

### Registering custom values and services

[](#registering-custom-values-and-services)

Since Lumy is built on top of Chernozem (we advise you to read its [documentation](https://github.com/pyrsmk/Chernozem)), it supports variables containing and, more interesting, services :

```
// Define the 'session' closure
$lumy['session']=function(){
    return new Session();
};
// Set the closure as a service
$lumy->service('session');
```

Now, when the service is retrieved, the `Session` object is automatically instantiated. It permits us to only load objects that we really want for the requested page to render.

```
// The Session object is ready
$lumy['session']['auth']=true;
```

### Middlewares

[](#middlewares)

In Lumy, we're using middlewares to modularize applications. Each middleware is a simple closure/callback that is called at run time one by one, in the order they're defined. Each middleware need to call the next middleware itself, it permits to wrap all middlewares in one function. When Lumy is run, a middleware is automatically created to run routing functions. Then, keep in mind that you can wrap the entire application with any middleware.

```
$lumy->middleware(function($middlewares){
    // Define our session service
    $lumy['session']=function(){
        return new Session();
    };
    $lumy->service('session');
    // Call the next middleware
    $middlewares->next();
    // Clean up session when the application has been runned
    unset($lumy['session']['cache']);
});
```

### Handling errors

[](#handling-errors)

The error handler is defined by the `error()` method which takes a callback :

```
$lumy->error(function($exception){
    // Print the encountered error
    echo $exception->getMessage();
});
```

### Run the application

[](#run-the-application)

When you're good you can :

```
$lumy->run();
```

The request object
------------------

[](#the-request-object)

All request objects have a `getChain()` method that returns the whole request/command chain for the request. You can retrieve this object with `$lumy['request']`.

### CLI

[](#cli)

The CLI request object is pretty concise. It implements two methods to deal with the command chain (the following examples are based on the `myapp install install/path/` command) :

- `getArguments()` : gets an array of arguments for the passed command (for example : `['install', 'install/path/']`)
- `getApplicationName()` : gets the application name (for example : `myapp`)

### HTTP

[](#http)

The HTTP request object implements several useful functions to deal with HTTP requests (the following examples are based on the `http://mywebsite.com/app/gallery/7` request) :

- `getScheme()` : get the scheme of the request, either `http` or `https`
- `getHost()` : get the host (example : `mywebsite.com`)
- `getPort()` : get the port for the request (example : `80`)
- `getRequestUri()` : get the request URI (the request chain relative to the current host) (example : `/app/gallery/7`)
- `getRootUri()` : get the root URI (it's the path relative to your application/website for the request) (example : `/app`)
- `getResourceUri()` : get the resource URI (it's the path relative to the specific request for your application/website) (example : `/gallery/7`)
- `getMethod()` : get the method for the request (generally `GET`, `POST`, `PUT` or `DELETE`)
- `isAjax()` : true if it's an AJAX request
- `isFlash()` : true if it's an AMF request
- `isSecure()` : true if it's an HTTPS request
- `getClientIp()` : get the IP of the client

The response object
-------------------

[](#the-response-object)

Response objects implement 4 methods for managing the response body. You can retrieve this object with `$lumy['response']`.

It also implements a `__toString()` function to print directly the response object returned by Lumy when the application has runned :

```
echo $lumy->run();

```

Here's how we're managing the response body :

- `setBody($body)` : set the body for the response object
- `prependBody($body)` : prepend contents to the body
- `appendBody($body)` : append contents to the body
- `getBody()` : returns the body

### CLI

[](#cli-1)

The CLI response object has methods for setting/getting environment variables and set ANSI colors :

- `setVariable($name,$value)` : set an environment variable
- `getVariable($name)` : get an environment variable
- `unsetVariable($name)` : unset a variable
- `colorize($color,$background,$style)` : return an ANSI color
- `reset()` : return the ANSI code to reset colors and styles

For convenience, this response object is shipped with constants for ANSI codes you can use with `colorize()` :

- colors : `BLACK`, `RED`, `GREEN`, `YELLOW`, `BLUE`, `PURPLE`, `CYAN`, `GREY`
- styles : `BOLD`, `DIM`, `UNSERLINE`, `BLINK`, `HILIGHT`, `HIDE`, `STROKE`

### HTTP

[](#http-1)

The HTTP response object can manage headers, status code and provide some useful functions to deal with the browser :

- `setHeader($name,$value)` : set a header
- `getHeader($name)` : get a header
- `unsetHeader($name)` : unset a header
- `setStatus($code)` : set the status code to send to the browser
- `getStatus()` : get the status code
- `redirect($url,$status)` : redirect to the specified absolute/relative URL; the status code sent by default is `302`
- `send($path)` : force the browser to send a download
- `display($path)` : force the browser to display a file (generally an image)

Public directories
------------------

[](#public-directories)

Since we often encounter several different servers in one project (at least, your local and remote ones), Lumy has like a firewall option that allow or forbid access to your files if needed. Point all requests in your `.htaccess` (or whatsoever) to your application file (`index.php`) : now all requets are passing through Lumy. We just need to allow/deny what we need.

```
// The user will freely access to the files in images/, uploads/ and config/
$lumy->publish('/images');
$lumy->publish('/uploads');
$lumy->publish('/config');

// But he won't access to sensible data
$lumy->unpublish('/config/database.json');
```

Advanced use of routes
----------------------

[](#advanced-use-of-routes)

The routing mechanism is used internally and we generally don't have to bother about it, otherwise there's some cases where we want to deal with routes directly. For that, we should name our routes by passing a name as the last argument of `route()`, `get()`, `post()`, etc :

```
// Add a 'gallery' route
$lumy->get('/gallery',function(){
    // Some actions
},null,null,'gallery');
```

Then you can get the route with `$lumy['router']['gallery']` and access to the following methods :

- `match($chain)` : match the specified chain against the route chain
- `getChain()` : return the route chain
- `getMatcher()` : return the matcher object used to verify if the route chain is valid against the current request (for more informations, see the [LongueVue](https://github.com/pyrsmk/LongueVue) project)
- `getController()` : return the registered controller with this route

License
-------

[](#license)

Lumy is published under the [MIT license](http://dreamysource.mit-license.org).

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity65

Established project with proven stability

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.

###  Release Activity

Cadence

Every ~40 days

Recently: every ~63 days

Total

13

Last Release

3636d ago

PHP version history (2 changes)2.8.0PHP &gt;=5.3.0

2.8.7PHP &gt;=5.4.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/7f97d81cfd6d30587cdae24925bc0899331394d723d04ee4b76eb9435a565fe9?d=identicon)[pyrsmk](/maintainers/pyrsmk)

---

Tags

httpcliframeworkmicro

### Embed Badge

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

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

###  Alternatives

[clue/framework-x

Framework X – the simple and fast micro framework for building reactive web applications that run anywhere.

936736.7k8](/packages/clue-framework-x)[igniphp/framework

Swoole, PSR-7, PSR-15 modular micro anti-framework.

2651.0k1](/packages/igniphp-framework)[phprest/phprest

PHP Rest Framework.

3049.3k](/packages/phprest-phprest)[hprose/hprose-yii

Hprose Server for Yii 2

357.1k](/packages/hprose-hprose-yii)

PHPackages © 2026

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