GithubHelp home page GithubHelp logo

roydejong / enlighten Goto Github PK

View Code? Open in Web Editor NEW
4.0 3.0 1.0 248 KB

Enlighten is a PHP micro framework that is simple, lean, high-performance and future proof.

License: MIT License

PHP 97.02% HTML 2.98%

enlighten's Introduction

Enlighten PHP Framework

Documentation Status Build Status Latest Stable Version Latest Unstable Version License Test Coverage

Enlighten is a simple, lean, high-performance PHP micro framework that acts as the foundation for your web application.

This is a modern framework for PHP 5 that doesn't get in your way. Just the building blocks you need to accelerate your application development and simply get shit done.

  • Easy HTTP request and response management: forms, headers, cookies, files and more.
  • Razor fast routing with dynamic URL variables and dependency injection.
  • Application and route filters for handling authentication, exceptions, etc.

It's easy to use:

$app->get('/hello/$name', function ($name) {
    echo "Hi there, $name";
});

It is awesome because it is:

  • Built for ease of use and performance.
  • Low on fat: small code base with minimal external dependencies.
  • Stable: tested extensively with a battery of unit tests.
  • Future-proof: Fully compatible with HHVM and PHP 7.

Getting started

To get started, add Enlighten as a Composer dependency to your project:

composer require enlighten/framework

In the entry point (index.php) of your application, initialize and start Enlighten:

$app = new Enlighten();
$app->start();

You'll need to make sure that your web server redirects all requests you want to handle with Enlighten to this script. This code will initialize a blank application and process all incoming requests.

Next, you will want to define routes. Routes map an incoming request to an appropriate function or controller that can respond to it. It's easy to set up:

$app->get('/articles/$name', function ($name) {
    // Triggered for all GET requests to /articles/*
    echo "You requested an article with this name: $name";
});

Check out the full documentation and quickstart guide at https://enlighten.readthedocs.org/en/latest/.

enlighten's People

Contributors

roydejong avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

enlighten's Issues

Router: redirects

It would be useful to be able to configure simple redirects:

$router->redirect('/sourceuri', '/targeturi');

This should result in a simple, static 302 redirect. A redirectPermanently might be cool too.

Docs: Filters

Need to add docs on the Filters system:

  • Global (app) filters
  • Route-specific filters
  • Method chaining in Enlighten

Docs: HTTP Response

In addition to the Request docs (#33), we need its counterpart - the Response object:

  • How to access it (Context)
  • Manipulating the body via functions / echo via Enlighten
  • Sending headers
  • Sending cookies
  • Helper functions

Docs: Routing

Documentation is needed for the routing configuration, both via the Enlighten::route() API and direct / custom Router configuration.

Should encompass all routing features including:

  • Patterns (regex usage)
  • Targets (both controllers and closures)
  • Dynamic variables
  • Constraints
  • Enlighten config API
  • Custom routers

Can only be started once milestone v0.1 is complete (depends on #4, #5, etc).

Request: Header extraction

The Http\Request class should have utilities that make it easy to read headers sent in the request, in addition to the information available in the environment data.

Proposed API:

  • getHeader($key)
  • getHeaders()

Support subdirectories

It would be nice if Enlighten routing could support a fixed subdirectory.

For example, a simple $router->setSubdirectory('/projects/bla'); could automatically expect that part to be in each route / request URI.

404 Error pages

Need good way to handle 404 errors when a route cannot be resolved.

Current situation for unmatched requests: HTTP 404 Not Found status code is returned to the client, with a blank screen (no content). There is no way to control this behavior right now.

Proposed solution: throw a specific Exception that can then be caught in the appropriate filters (see #1). Or perhaps add a custom global filter event type (e.g. notFound).

Docs: File uploads

Need documentation and with info, API and best practices for handling file uploads, with a particular focus on validating and handling image uploads.

HTTP Request: Cookies

It should be possible to read a user's cookies via the Http\Request class.

Proposed API:

  • Request::getCookies(): Return all cookies as a key/value array
  • Request::getCookie($key, $default): Return a specific cookie or a default value if it is not found
  • Request::setCookies(array $cookies)

Context: Apply to filters

Thanks to Routing DI (#17) we have an awesome system for dependency injection. Now we need to make it more generic (not specifically for routing). In particular, the filters (#1) system would benefit from a system like this.

Closure context

At the moment when a routing function / closure is invoked, it is being passed a Request object as a first parameter and any dynamic routing variables after that.

This also means that these closures currently cannot access the Response object or any other useful context data.

Using the bindTo function, we should bind a context object to these anonymous functions that allows them to freely access such objects without polluting their parameter list. This should allow for more reasonable and readable code.

It is important that any context object design can be used for MVC barbones later as well.

HTTP HEAD: Content-Length not set properly

When a HEAD request is sent, the Enlighten class strips the response body.
This results in an incorrect Content-Length header.

Because there is a hint of doubt on the internet as to whether web servers always strip the response body correctly, I think it is still important that the framework forces a consistent response.

Proposed fix: set the Content-Length before stripping the response body OR determine that both apache and nginx handle this appropriately.

Route filters

It should be possible to apply filters to the routing system.

A filter is a piece of code that is executed during different stages of routing. This is useful for performing a variety of operations, like checking a user's authorization before granting them access to a specific page.

Some frameworks such as Slim, Laravel, etc describe this concept as middleware because it sounds fancy. ASP.NET uses the term filters, which I think is a bit easier to communicate.

Overall requirements:

  • Have option to define filters for a variety of event types (see below).
  • Filters should be able to be applied globally, or to specific routes.
  • Should integrate nicely into the current Enlighten routing API (such as Enlighten::get($pattern, $target)), without resorting to array-based configuration.
  • Nice to have: Filters should be able to get an optional priority (execution order). Specific filters should weigh heavier than any global filters.

Filter event types:

  • Before route invocation (before)
  • After route invocation (after)
  • On exception (onException)

Proposed configuration API:

$app = new Enlighten();

// Fluent API using the returned Route of ::get, ::post, etc
// For setting up route-specific filters
$app->get('/page.html', function () {
    echo 'Hi there!';
})
->after(function () {
    echo "Thanks for stopping by!";
})
->onException(function (Exception $ex) {
    echo "Oh dear!"
});

// For setting up global filters
$app->before(function () {
    // ..
});

HTTP Response: Cookies

It should be possible to send cookies using the Http\Response class.

Proposed API:

  • Request::sendCookie($key, $value, $ttl, [..])
  • Request::deleteCookie($key)

Context: Allow manual registrations

Example use case:

I created a custom session implementation. I initialize this session manager in a global before() filter. I want to expose my session manager to controllers, but I currently do not have the option to access the application Context, so I can't add custom objects to it.

Proposed solution:

Expose the Context via the Context dependency injection itself.

HTTP HEAD: Route to GET by default

According to the RFC, HTTP HEAD requests are really just aliasses for GET.

Currently, the framework would reject a HEAD request and reply with a 404 if only a GET route matched. That does not conform to HTTP standards.

Proposed fix: Remove HEAD as a configurable routing option. When GET routes are configured, the constraint should both allow for GET and HEAD methods.

Filters: Allow "before" filter to stop execution

Example use case:

I am creating a before() filter that checks user authentication. Currently I have to redirect the user away and throw exit to stop execution. This is a bit dirty, and I can't reliably use the Request class either.

It would be nice if the framework provided a cleaner way to do this, for example halting execution when the "before" function returns false.

Routing: Intelligent dependency injection

When we define a routing target function, we have some potential problems:

$app->get('/user/$name/$action', function ($action, $name) {
    // $action contains our $name and $name contains our $action :(
    $this->request->getPost(/* ... */); // IDE does not understand this
});

We have a fixed order for the function parameters. The name of the variables does not matter, only the order does - this is not ideal.

In the background we currently pass some secret variables (e.g. $this->getRequest()). Our IDE does not know this, cannot hint it, and will not understand it.

I propose a solution that fixes all of these problems and opens up a few nice future oppertunities: dependency injection:

  • Use reflection to determine the parameters in the target function
  • Map variables based on their names, ignore the ordering of variables
  • Use dependency injection to intelligently pass the variables a function wants, such as Request and Response objects

Example usage, desired situation:

$app->get('/user/$name/$action', function ($action, Request $request, $name) {
    // Our system has filled $action and $name with the appropriate route variables
    // Because we type-hinted the "Request" class, we injected that dependency, on demand
    // & no more need for dirty $this-> hacks.
});

Controllers

Controllers are an optional extension to the framework that act as a useful building block for MVC applications.

Requirements:

  • Extend the routing system to accept references to controller classes (my\ns\ControllerClass@invokeFunction)
  • Pass the relevant contextual data (see #4) to each controller
  • Pass the relevant dynamic variables to the controller functions specified

Context: Allow global access

Example use case:

I created a custom session implementation. I initialize this session manager in a global before() filter. I have exposed my session manager to the Context thanks to the enhancement in #35. But I also have a custom View implementation I want to pass my session manager to. I would like to rely on the Context here, rather than having to pass it over manually. But there is no way to do that currently.

HTTP Request: Additional request parsing utilities

I think the Request class needs a few utility / helper functions that extend past the basic functionality provided by #9 (i.e. getHeader()).

  • Ajax requests (isAjax(): bool)
  • Protocol information (isHttps(): bool, getProtocol(): string)
  • Get user IP address (getIp(): bool) - with IPv6 and proxy considerations

v0.1: The Big Refactor

Before v0.1 is released, there is a bunch of code that needs to be checked and refactored.

This ticket simply represents all the actions that need to be performed to achieve that and should act as a registry for those commits.

Goals:

  • Ensure PSR-0 and PSR-1 compliance across the code base.
  • Reduce verbosity of some APIs (e.g. ::getPostValue() should probably just be called ::post()).
  • Ensure function naming is consistent.
  • Ensure IDE type hinting works for all parts of the code, e.g. closures context need to be looked at in more detail.
  • Ensure that protection levels are logical and consistent.
  • Ensure that all PHPDoc is up to scratch.
  • Ensure that all unit tests are up to scratch and code coverage is 100% or very close to that.
  • etc

This is a blocking issue before v0.1 can be released.

Forms

The framework should provide a way for applications to quickly and easily validate and extract form-submitted data.

Requirements:

  • Automatic processing of forms, wrapping of Request object
  • Support for both POST and GET methods for data submission
  • Data retrieval directly through fields
  • Validation per form field with simple, extensible API

Possible extensions for the future:

  • Fully automatic HTML generation (out of the scope of Enlighten right now)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.