├── 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 | --------------------------------------------------------------------------------