├── app
├── Views
│ ├── .gitkeep
│ └── Demo
│ │ ├── Home
│ │ └── index.twig
│ │ └── Hello
│ │ └── index.twig
├── Services
│ ├── .gitkeep
│ ├── FlashMessagesService.php
│ ├── ControllerStrategyService.php
│ ├── ErrorHandlerService.php
│ ├── MonologService.php
│ └── TwigViewService.php
├── Controllers
│ ├── .gitkeep
│ └── Demo
│ │ ├── HomeController.php
│ │ └── HelloController.php
├── Routes
│ ├── app.php
│ └── demo.php
├── Kernel
│ ├── ServiceInterface.php
│ ├── VarDumper.php
│ ├── ControllerStrategy.php
│ ├── HtmlVarDumper.php
│ ├── MiddlewareAbstract.php
│ ├── ErrorHandler.php
│ ├── App.php
│ └── ControllerAbstract.php
└── Middlewares
│ └── ExampleMiddleware.php
├── .env.example
├── public
├── assets
│ ├── css
│ │ └── .gitignore
│ ├── imgs
│ │ └── .gitignore
│ └── js
│ │ └── .gitignore
└── index.php
├── storage
└── cache
│ └── twig
│ └── .gitignore
├── .gitignore
├── config
├── middlewares.php
├── logger.php
├── twig.php
├── services.php
└── app.php
├── bootstrap
├── kernel.php
├── app.php
└── helpers.php
├── composer.json
├── LICENSE
└── README.md
/app/Views/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/Services/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/Controllers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | APP_ENV = local
2 | APP_DEBUG = true
3 |
--------------------------------------------------------------------------------
/public/assets/css/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/public/assets/imgs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/public/assets/js/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/cache/twig/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 |
3 | /.env
4 | /.idea
5 | /composer.lock
6 |
--------------------------------------------------------------------------------
/app/Views/Demo/Home/index.twig:
--------------------------------------------------------------------------------
1 |
Welcome!
2 |
3 | {{ "now"|date("Y-m-d H:i:s") }}
4 |
--------------------------------------------------------------------------------
/config/middlewares.php:
--------------------------------------------------------------------------------
1 | Hello {{ name }}
2 |
3 | {{ "now"|date("Y-m-d H:i:s") }}
4 |
--------------------------------------------------------------------------------
/config/logger.php:
--------------------------------------------------------------------------------
1 | 'app',
5 | 'path' => storage_path() . '/logs/app.log',
6 | ];
7 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | get('/', 'App\Controllers\Demo\HomeController:index');
4 |
5 | $app->get('/hello/{name}', 'App\Controllers\Demo\HelloController:index');
6 |
--------------------------------------------------------------------------------
/config/twig.php:
--------------------------------------------------------------------------------
1 | env('APP_DEBUG', false),
5 | 'auto_reload' => env('APP_DEBUG', false),
6 | 'cache' => storage_path() . '/cache/twig',
7 | 'strict_variables' => env('APP_DEBUG', false),
8 | ];
9 |
--------------------------------------------------------------------------------
/bootstrap/kernel.php:
--------------------------------------------------------------------------------
1 | load();
10 |
11 | unset($_dotenv);
12 | }
13 |
--------------------------------------------------------------------------------
/config/services.php:
--------------------------------------------------------------------------------
1 | require config_path() . '/app.php']);
10 |
11 | $app->registerServices();
12 |
13 | $app->registerAppMiddlewares();
14 |
15 | require app_path() . '/Routes/app.php';
16 |
17 | $app->run();
18 |
--------------------------------------------------------------------------------
/app/Controllers/Demo/HomeController.php:
--------------------------------------------------------------------------------
1 | render('Demo/Home/index.twig');
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/config/app.php:
--------------------------------------------------------------------------------
1 | env('APP_DEBUG', false),
5 | 'determineRouteBeforeAppMiddleware' => false,
6 | // 'routerCacheFile' => storage_path() . '/cache/routes.php',
7 |
8 | 'middlewares' => require 'middlewares.php',
9 |
10 | 'services' => require 'services.php',
11 |
12 | 'logger' => require 'logger.php',
13 |
14 | 'twig' => require 'twig.php',
15 | ];
16 |
--------------------------------------------------------------------------------
/app/Controllers/Demo/HelloController.php:
--------------------------------------------------------------------------------
1 | render('Demo/Hello/index.twig', ['name' => $name]);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/Services/FlashMessagesService.php:
--------------------------------------------------------------------------------
1 | logger);
24 | };
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/Kernel/VarDumper.php:
--------------------------------------------------------------------------------
1 | dump((new VarCloner)->cloneVar($value));
20 |
21 | unset($dumper);
22 | } else {
23 | var_dump($value);
24 | }
25 |
26 | unset($value);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/Middlewares/ExampleMiddleware.php:
--------------------------------------------------------------------------------
1 | getBody()->write('-- BEFORE --
');
21 |
22 | $response = $next($request, $response);
23 |
24 | $response->getBody()->write('
-- AFTER --');
25 |
26 | return $response;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/Kernel/ControllerStrategy.php:
--------------------------------------------------------------------------------
1 | settings['logger'];
26 |
27 | $logger = new Logger($settings['name']);
28 |
29 | $logger->pushProcessor(new UidProcessor());
30 |
31 | $logger->pushHandler(new StreamHandler($settings['path'], Logger::DEBUG));
32 |
33 | unset($container, $settings);
34 |
35 | return $logger;
36 | };
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/Kernel/HtmlVarDumper.php:
--------------------------------------------------------------------------------
1 | 'background-color:#fff; color:#222; line-height:1.2em; font-weight:normal; font:12px Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:100000',
15 | 'num' => 'color:#a71d5d',
16 | 'const' => 'color:#795da3',
17 | 'str' => 'color:#df5000',
18 | 'cchr' => 'color:#222',
19 | 'note' => 'color:#a71d5d',
20 | 'ref' => 'color:#a0a0a0',
21 | 'public' => 'color:#795da3',
22 | 'protected' => 'color:#795da3',
23 | 'private' => 'color:#795da3',
24 | 'meta' => 'color:#b729d9',
25 | 'key' => 'color:#df5000',
26 | 'index' => 'color:#a71d5d',
27 | ];
28 | }
29 |
--------------------------------------------------------------------------------
/app/Services/TwigViewService.php:
--------------------------------------------------------------------------------
1 | settings['twig']
27 | );
28 |
29 | $view->addExtension(
30 | new TwigExtension(
31 | $container->router,
32 | $container->request->getUri()
33 | )
34 | );
35 |
36 | $view->getEnvironment()->addGlobal('flash', $container->flash);
37 |
38 | unset($container);
39 |
40 | return $view;
41 | };
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ricardoper/slim3-skeleton",
3 | "type": "library",
4 | "license": "MIT",
5 | "description": "PHP Slim Framework v3.5 Skeleton With Twig Views, Flash Messages, VarDumper And A Good Folder Organization",
6 | "keywords": [
7 | "PHP",
8 | "Slim",
9 | "Framework",
10 | "Skeleton",
11 | "Twig",
12 | "Flash",
13 | "VarDumper"
14 | ],
15 | "homepage": "https://github.com/ricardoper",
16 | "authors": [
17 | {
18 | "name": "Ricardo Pereira",
19 | "email": "github@ricardopereira.es",
20 | "homepage": "http://ricardopereira.es"
21 | }
22 | ],
23 | "require": {
24 | "php": ">=5.5.0",
25 | "slim/slim": "^3.5",
26 | "slim/twig-view": "^2.1",
27 | "slim/flash": "^0.1.0",
28 | "vlucas/phpdotenv": "^2.4",
29 | "symfony/var-dumper": "^3.1",
30 | "monolog/monolog": "^1.21"
31 | },
32 | "autoload": {
33 | "psr-4": {
34 | "App\\": "app/"
35 | },
36 | "files": [
37 | "bootstrap/helpers.php"
38 | ]
39 | },
40 | "config": {
41 | "optimize-autoloader": true
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Ricardo Pereira
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/Kernel/MiddlewareAbstract.php:
--------------------------------------------------------------------------------
1 | container = $container;
26 |
27 | unset($container);
28 | }
29 |
30 | /**
31 | * Middleware
32 | *
33 | * @param Request $request
34 | * @param Response $response
35 | * @param App $next
36 | * @return Response
37 | */
38 | abstract public function __invoke(Request $request, Response $response, $next);
39 |
40 | /**
41 | * Get Slim Container
42 | *
43 | * @return ContainerInterface
44 | */
45 | protected function getContainer()
46 | {
47 | return $this->container;
48 | }
49 |
50 | /**
51 | * Get Service From Container
52 | *
53 | * @param string $service
54 | * @return mixed
55 | */
56 | protected function getService($service)
57 | {
58 | return $this->container->{$service};
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/Kernel/ErrorHandler.php:
--------------------------------------------------------------------------------
1 | logger = $logger;
27 |
28 | unset($logger);
29 |
30 | parent::__construct(env('APP_DEBUG', false));
31 | }
32 |
33 | /**
34 | * Invoke error handler
35 | *
36 | * @param ServerRequestInterface $request The most recent Request object
37 | * @param ResponseInterface $response The most recent Response object
38 | * @param \Exception $exception The caught Exception object
39 | *
40 | * @return ResponseInterface
41 | * @throws UnexpectedValueException
42 | */
43 | public function __invoke(ServerRequestInterface $request, ResponseInterface $response, \Exception $exception)
44 | {
45 | // Log Critical Message //
46 | $this->logger->critical($exception->getMessage());
47 |
48 | return parent::__invoke($request, $response, $exception);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/Kernel/App.php:
--------------------------------------------------------------------------------
1 | getContainer();
18 |
19 | $services = $container->settings['services'];
20 |
21 | if (is_array($services) && !empty($services)) {
22 | foreach ($services as $service) {
23 | /**
24 | * @var $instance ServiceInterface
25 | */
26 | $instance = new $service();
27 |
28 | $container[$instance->name()] = $instance->register();
29 |
30 | unset($instance);
31 | }
32 | }
33 |
34 | unset($container, $services, $service);
35 | }
36 |
37 | /**
38 | * Register App Middlewares
39 | */
40 | public function registerAppMiddlewares()
41 | {
42 | /**
43 | * @var $container Container
44 | */
45 | $container = $this->getContainer();
46 |
47 | $middlewares = $container->settings['middlewares'];
48 |
49 | if (is_array($middlewares) && !empty($middlewares)) {
50 | foreach ($middlewares as $middleware) {
51 | $this->add($middleware);
52 | }
53 | }
54 |
55 | unset($container, $middlewares, $middleware);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/Kernel/ControllerAbstract.php:
--------------------------------------------------------------------------------
1 | container = $container;
27 |
28 | unset($container);
29 | }
30 |
31 |
32 | /**
33 | * Get Slim Container
34 | *
35 | * @return ContainerInterface
36 | */
37 | protected function getContainer()
38 | {
39 | return $this->container;
40 | }
41 |
42 | /**
43 | * Get Service From Container
44 | *
45 | * @param string $service
46 | * @return mixed
47 | */
48 | protected function getService($service)
49 | {
50 | return $this->container->{$service};
51 | }
52 |
53 | /**
54 | * Get Request
55 | *
56 | * @return Request
57 | */
58 | protected function getRequest()
59 | {
60 | return $this->container->request;
61 | }
62 |
63 | /**
64 | * Get Response
65 | *
66 | * @return Response
67 | */
68 | protected function getResponse()
69 | {
70 | return $this->container->response;
71 | }
72 |
73 | /**
74 | * Get Twig Engine
75 | *
76 | * @return Twig
77 | */
78 | protected function getView()
79 | {
80 | return $this->container->view;
81 | }
82 |
83 | /**
84 | * Render view
85 | *
86 | * @param string $template
87 | * @param array $data
88 | * @return string
89 | */
90 | protected function render($template, $data = [])
91 | {
92 | return $this->getView()->render($this->getResponse(), $template, $data);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/bootstrap/helpers.php:
--------------------------------------------------------------------------------
1 | dump($x);
17 | },
18 | func_get_args()
19 | );
20 | }
21 | }
22 |
23 | if (!function_exists('dd')) {
24 | /**
25 | * Dump the passed variables
26 | *
27 | * @param mixed
28 | * @return void
29 | */
30 | function dd()
31 | {
32 | array_map(
33 | function ($x) {
34 | (new VarDumper)->dump($x);
35 | },
36 | func_get_args()
37 | );
38 |
39 | die();
40 | }
41 | }
42 |
43 | if (!function_exists('env')) {
44 | /**
45 | * Gets the value of an environment variable
46 | *
47 | * @param string $key
48 | * @param mixed $default
49 | * @return mixed
50 | */
51 | function env($key, $default = null)
52 | {
53 | $value = getenv($key);
54 |
55 | if ($value === false) {
56 | return $default;
57 | }
58 |
59 | switch (strtolower($value)) {
60 | case 'true':
61 | case '(true)':
62 | return true;
63 | case 'false':
64 | case '(false)':
65 | return false;
66 | case 'empty':
67 | case '(empty)':
68 | return '';
69 | case 'null':
70 | case '(null)':
71 | return null;
72 | }
73 |
74 | $strLen = strlen($value);
75 |
76 | if ($strLen > 1 && $value[0] === '"' && $value[$strLen - 1] === '"') {
77 | return substr($value, 1, -1);
78 | }
79 |
80 | return $value;
81 | }
82 | }
83 |
84 | if (!function_exists('base_path')) {
85 | /**
86 | * Get the path to the base folder
87 | *
88 | * @return string
89 | */
90 | function base_path()
91 | {
92 | return dirname(__DIR__);
93 | }
94 | }
95 |
96 | if (!function_exists('app_path')) {
97 | /**
98 | * Get the path to the application folder
99 | *
100 | * @return string
101 | */
102 | function app_path()
103 | {
104 | return base_path() . '/app';
105 | }
106 | }
107 |
108 | if (!function_exists('config_path')) {
109 | /**
110 | * Get the path to the config folder
111 | *
112 | * @return string
113 | */
114 | function config_path()
115 | {
116 | return base_path() . '/config';
117 | }
118 | }
119 |
120 | if (!function_exists('public_path')) {
121 | /**
122 | * Get the path to the public folder
123 | *
124 | * @return string
125 | */
126 | function public_path()
127 | {
128 | return base_path() . '/public';
129 | }
130 | }
131 |
132 | if (!function_exists('storage_path')) {
133 | /**
134 | * Get the path to the storage folder
135 | *
136 | * @return string
137 | */
138 | function storage_path()
139 | {
140 | return base_path() . '/storage';
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PHP Slim Framework v3.5 Skeleton
2 |
3 | Use this skeleton application to quickly setup and start working on a new Slim Framework v3.5 application.
4 |
5 | **NOTE**: If you want a similar skeleton for **version 4**, go to: (https://github.com/ricardoper/slim4-twig-skeleton).
6 |
7 | This skeleton application was built for Composer. This makes setting up a new Slim Framework v3.5 application quick and easy.
8 |
9 | - [PSR-2](http://www.php-fig.org/psr/psr-2/ "PHP Framework Interop Group")
10 | - [PSR-4](http://www.php-fig.org/psr/psr-4/ "PHP Framework Interop Group")
11 | - PHP 5.5
12 | - Namespaced
13 |
14 | + Helpers
15 | + Services
16 | + Twig Views
17 | + Flash Messages
18 | + Symfony VarDumper
19 | + Logging with Monolog
20 | + Folders structure with sense
21 | + Environment variables with Dotenv
22 |
23 | ## How to install this skeleton
24 |
25 | Run this command from the directory in which you want to install your new Slim Framework v3.5 Skeleton.
26 |
27 | ```bash
28 | composer create-project ricardoper/slim3-skeleton [my-app-name]
29 | ```
30 |
31 | Replace ```[my-app-name]``` with the desired directory name for your new application. You'll want to:
32 | - Point your virtual host document root to your new application's ```public/``` directory.
33 | - Ensure ```storage/``` is web writeable.
34 |
35 | ## Most relevant skeleton folders
36 |
37 | - /app : Application code (App Namespace)
38 | + ./Controllers : Add your controllers here
39 | + ./Middlewares : Add your middlewares here
40 | + ./Routes : Add your routes here
41 | + ./Services : Add your services here
42 | + ./Views : Add your Twig views here
43 | - /config : Add/modify your configurations here
44 | - /public : Add your assets files here
45 |
46 | ## Controllers methods
47 |
48 | - getContainer() : Returns the Slim App container
49 | - getService(string $service) : Returns service from container by name
50 | - getRequest() : Returns HTTP Request
51 | - getResponse() : Returns HTTP Response
52 | - getView() : Returns Twig View
53 | - render(string $template, array $data) : Renders Twig page stored in Views folder
54 |
55 | ## Middleware methods
56 |
57 | - getContainer() : Returns the Slim App container
58 | - getService(string $service) : Returns service from container by name
59 |
60 | ## Helpers methods
61 |
62 | - d() : Symfony VarDumper and continue
63 | - dd() : Symfony VarDumper and die
64 | - env(string $variable, string $default) : Return environment variables with
65 | - base_path() : Returns base path location
66 | - app_path() : Returns app path location
67 | - config_path() : Returns config path location
68 | - public_path() : Returns public path location
69 | - storage_path() : Returns storage path location
70 |
71 | ## Middlewares
72 |
73 | You can add as many middlewares as you want in a clean way (```/app/Middlewares```).
74 |
75 | After add your middleware, you can enable or disable it in ```config/middlewares.php``` configuration file.
76 |
77 | ## Routes
78 |
79 | You can add as many routes files as you want (```/app/Routes```), but you need to enable these files in ```/apps/Routes/app.php``` file.
80 |
81 | ## Services
82 |
83 | You can add as many services as you want in a clean way (```/app/Services```).
84 |
85 | After add your service, you can enable or disable it in ```config/services.php``` configuration file.
86 |
87 | ## Configurations
88 |
89 | You can add as many configurations files as you want (```/config```), but you need to enable these files in ```/config/app.php``` file.
90 |
91 | ## Twig Globals
92 |
93 | flash : To get Flash Messages
94 |
95 | ## Demo pages
96 |
97 | Try the skeleton demo pages.
98 |
99 | #### Welcome page:
100 | http(s)://virtualhost.int/
101 |
102 | #### Hello user:
103 | http(s)://virtualhost.int/hello/[name]
104 |
105 | **NOTE:** Replace ```[name]``` with the desired User name
106 |
107 | --
108 |
109 | ### Enjoy the simplicity :oP
110 |
--------------------------------------------------------------------------------