elie29 / core
Simple and clear framework
Requires
- php: ^7.1
- psr/container: ^1.0
Requires (Dev)
- mockery/mockery: ^1.2
- phpstan/phpstan: ^0.11.2
- phpstan/phpstan-mockery: ^0.11.0
- phpunit/phpunit: ^7.5
- symfony/var-dumper: ^4.2
- zendframework/zend-coding-standard: ^1.0
This package is auto-updated.
Last update: 2024-10-27 21:04:19 UTC
README
Introduction
PHP library to create a light straightforward project using PSR-11 container.
Installation
Run the command below to install via Composer:
composer require elie29/core
Getting Started
Core framework does not require a specific structure. Only some configuration should be provided.
Prepare the project structure
In order to configure the framework, we need to have a project structure. Let's assume we have the following standard structure:
- MY_PROJECT
- data:
- cache: Cache folder if cache is activated
- config:
- config.php: Project configuration
- container.php: Container configuration
- public
- index.php: Frontend controller
- src:
- Controllers
- HomeIndexController: Default Core Controller that extends AbstractController
- views
- layouts/layout.html: Layout used by Core Framework when rendering is html
- home/index.phtml: not required unless HomeIndexController uses fetchTemplate
- Controllers
- composer.json
- "php": "^7.1",
- elie29/core
- elie29/zend-phpdi-config: PHP-DI container configurator or choose your own
- data:
Prepare the config file
Regarding the defined structure above, config.php looks as follow:
// point out to MY_PROJECT $base = dirname(dirname(__DIR__)); // should return an array return [ // zend-phpdi-config 'dependencies' => [ 'aliases' => [ RouterInterface::class => Router::class, RenderInterface::class => Render::class, ], 'autowires' => [ Router::class, Render::class, HomeIndexController::class ], ], // Core configuration 'core' => [ // Router configuration: Query Protocol by default 'router' => [ RouterConst::NAMESPACE => 'Controllers\\' ], // Render configuration 'render' => [ RenderConst::VIEWS_PATH => $base . '/src/views', RenderConst::CACHE_PATH => $base . '/data/cache', RenderConst::CLEAN_OUTPUT => true, ], ], ];
Prepare the container
container.php
depends on the installed container. For zend-phpdi-config, it looks like:
// Protect variables from global scope return call_user_func(function () { $config = require __DIR__ . '/config.php'; $factory = new ContainerFactory(); // Container return $factory(new Config($config)); });
Create the index.php
Nothing more including autoload.php
and instanciating Core
class as follow:
chdir(dirname(__DIR__)); require 'vendor/autoload.php'; $container = require 'data/config/container.php'; $core = new Core($container); $core->run();
Create the layout
layout.phtml
is an html file with php variables assigned in the controller or returned by preRun
, run
or postRun
methods.
Example of a layout.phtml
:
<html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="<?php echo htmlentities($description, ENT_QUOTES, 'UTF-8') ?>"> </head> <body> <!-- tplContent should display tags --> <div><?php echo $tplContent ?></div> </body> </html>
Create the first Controller
In the config file, we specified Controllers\\
as a default namespace, but we did not specify a default controller and a default action. In this case, the controller will be home and the action will be index. Therfore, Controller class should be named HomeIndexController with Controllers as namespace.
Each controller should implement Elie\Core\Controller or extends Elie\Core\AbstractController:
namespace Controllers; class HomeIndexController extends AbstractController { public function doRun(): bool { $render = $this->container->get(RenderInterface::class); // true because cache_time is not defined in config.php return $render->hasLayoutExpired(); } public function run(array $params = []): array { $render = $this->container->get(RenderInterface::class); // global data for layout/templates $render->assign([ 'description' => 'first description', ]); // layout specific data return ['tplContent' => '<span>my content</span>']; } }
Create a template
A template is not required, but in order to have a dynamic layout with several contents, we cas use RenderInterface::fetchTemplate
. phtml templates should be under views_path.
Let's change run
method in order to fetch a template:
public function run(array $params = []): array { $render = $this->container->get(RenderInterface::class); // global data for layout/templates $render->assign([ 'description' => 'displayed description', ]); // layout specific data return ['tplContent' => $this->getMyTemplate()]; } protected function getMyTemplate(): string { $cacheID = sha1(__FILE__ . 'product/detail'); $cacheTime = 5; // 5 seconds in cache $render = $this->container->get(RenderInterface::class); // data is not needed when file is read from cache $data = []; // overrides keys assigned in run $render->assign([ 'description' => __METHOD__, ]); if ($render->hasTemplateExpired($cacheID, $cacheTime)) { $data = [ 'item' => time(), 'description' => 'overriden by assign method' ]; } // specific product/detail template under views_path return $render->fetchTemplate($data, 'product/detail', $cacheID, $cacheTime); }
detail.phtml
file under src/views/product
folder could be as follow:
<h1>Product detail Template</h1> <div><?php echo htmlentities($item, ENT_QUOTES, 'UTF-8') ?></div>
Development Prerequisites
Text file encoding
- UTF-8
Code style formatter
- Zend Framework coding standard
Composer commands
clean
: Cleans all generated filestest
: Launches unit testtest-coverage
: Launches unit test with clover.xml file generationcs-check
: For code sniffer checkcs-fix
: For code sniffer fixphpstan
: Launches PHP Static Analysis Toolcheck
: Launchesclean
,cs-check
,test
andphpstan