11# The µ PHP Microframework
22
3- [ ![ Code Climate] ( https://codeclimate.com/github/jeremeamia/mu/badges/gpa.svg )] ( https://codeclimate.com/github/jeremeamia/mu )
4-
5- A _ "real"_ microframework that fits in ** just 4 lines of code** .
3+ A _ "real"_ microframework that fits in ** just 3 lines of code** .
64
75The "microframeworks" out there weren't _ micro_ enough for me, so I brushed up on
86some of my code golfing skills to create ** µ** .
@@ -11,34 +9,34 @@ some of my code golfing skills to create **µ**.
119
1210## Features
1311
14- These 4 LOC come jam-packed with features!
12+ These 3 LOC come jam-packed with features!
1513
1614### Easy, regex-based routing system
1715
1816Follows the well-established route-to-callable microframework pattern.
1917
2018``` php
21- echo (new µ)
22- ->get('/hello', function ($app ) {
23- return "<p >Hello, world!</p >";
19+ (new µ)
20+ ->get('/hello', function () {
21+ echo "<p >Hello, world!</p >";
2422 })
2523 ->run();
2624```
2725
2826Allows you to access parameters from the URL.
2927
3028``` php
31- echo (new µ)
29+ (new µ)
3230 ->get('/hello/(?<name >\w+)', function ($app, $params) {
33- return "<p >Hello, {$params['name']}!</p >";
31+ echo "<p >Hello, {$params['name']}!</p >";
3432 })
3533 ->run();
3634```
3735
3836Supports all your favorite HTTP verbs.
3937
4038``` php
41- echo (new µ)
39+ (new µ)
4240 ->delete('/user/(?<id >\d+)', $fn)
4341 ->get('/user/(?<id >\d+)', $fn)
4442 ->head('/user/(?<id >\d+)', $fn)
@@ -48,38 +46,32 @@ echo (new µ)
4846 ->run();
4947```
5048
51- Supports wildcard verbs too, because sometimes you are just making a web page
52- and you really don't care about esoteric HTTP practices.
49+ ### Simple dependency/config container
5350
5451``` php
55- echo (new µ)
56- ->any('/', $fn)
57- ->run();
58- ```
59-
60- ### Simple, but powerful, dependency injection container
61-
62- ``` php
63- use Monolog\Logger;
6452use Monolog\Handler\StreamHandler;
53+ use Monolog\Logger;
6554
66- echo (new µ)
55+ (new µ)
6756 ->cfg('log.channel', 'your-app')
68- ->cfg('log.handler', function ($app ) {
69- return new StreamHandler('path/to/your.log', Logger::WARNING );
57+ ->cfg('log.handler', function () {
58+ return new StreamHandler('path/to/your.log', Logger::DEBUG );
7059 })
7160 ->cfg('log', function ($app) {
7261 $log = new Logger($app->cfg('log.channel'));
7362 $log->pushHandler($app->cfg('log.handler'));
7463 return $log;
7564 })
7665 ->get('/hello/(?<name >\w+)', function ($app, $params) {
77- $app->cfg('log')->addDebug ("Said hello to {$params['name']}. ");
78- return "<p >Hello, {$params['name']}!</p >";
66+ $app->cfg('log')->debug ("Said hello to {$params['name']}");
67+ echo "<p >Hello, {$params['name']}!</p >";
7968 })
8069 ->run();
8170```
8271
72+ If a callable is provided (like with ` log.handler ` above), then it is treated as a factory and is only called once to
73+ produce a singleton value for efficient, multiple accesses.
74+
8375### A truly _ elegant_ and fluent interface
8476
8577_ See previous example (I'm lazy)._
@@ -102,40 +94,50 @@ Templates are just PHP files—no mustaches and no frills.
10294
10395``` php
10496// index.php
105- echo (new µ)
97+ (new µ)
10698 ->cfg('views', __DIR__ . '/templates')
107- ->any ('/hello/(?<name >\w+)', function ($app, $params) {
108- return $app->view('hello', [
99+ ->get ('/hello/(?<name >\w+)', function ($app, $params) {
100+ echo $app->view('hello', [
109101 'greeting' => 'howdy',
110102 'name' => $params['name'],
111103 ]);
112104 })
113105 ->run();
114106```
115107
116- No twigs, plates , or blades to cut you or poke you.
108+ No Twigs, Plates , or Blades to cut you or poke you. That might feel a little _ dull _ , but it's simple .
117109
118110## Design constraints
119111
120112* Must have at least a Router, Container, and Templating System as features.
121113* Must attempt to incorporate usage patterns (e.g., chainable methods, closures
122114 as controllers) that resemble other contemporary microframeworks.
123115* Must work with ` error_reporting ` set to ` -1 ` (all errors reported).
124- * Must not exceed 4 lines of code (LOC), where each line is <= 120 characters.
116+ * Must not exceed 3 lines of code (LOC), where each line is <= 120 characters.
125117* Must not have dependencies on other packages.
126- * May break traditional coding conventions for the sake of brevity.
127- * Must be hand-written.
118+ * May break traditional coding conventions/styles for the sake of brevity.
119+ * Must be hand-written, not minified/obfuscated by any tools .
128120
129121## It works, but it's really just a joke.
130122
131123Don't use this in production, or really anywhere. It's just for fun. :smile :
132124
133- If you want to use a production-quality _ microframework_ , try one of these:
125+ If you want to use a production-quality _ microframework_ , try [ Slim ] ( http://www.slimframework.com/ ) .
134126
135- * [ Slim] ( http://www.slimframework.com/ )
136- * [ Lumen] ( http://lumen.laravel.com/ )
137- * Zend [ Diactoros] ( https://docs.zendframework.com/zend-diactoros/ ) or [ Expressive] ( https://docs.zendframework.com/zend-expressive/ )
127+ ## Examples
138128
139- ## Is there a PHP 7 Version?
129+ The code examples in this README are also shipped as working examples in the ` /examples ` directory.
140130
141- Not yet. Waiting for 7.4 with shorthand closures before I attempt anything.
131+ To run an example, use the built-in PHP server.
132+ ``` bash
133+ # For the hello1 example:
134+ php -S localhost:8000 examples/hello1.php
135+ ```
136+ Then access ` http://localhost:8000 ` in your browser or via cURL.
137+
138+ ## Tests
139+
140+ A very basic test suite is included, and can be run via:
141+ ``` bash
142+ php test.php
143+ ```
0 commit comments