Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Feather

A modular, minimalist PHP microframework.

This project was the result of me attempting to write a PHP application from scratch, which somehow turned into a tiny microframework, which I extended so it can be used for full Projects instead of only static Websites.

Getting Started

Install Feather as a Composer dependency.

composer require fatalus/feather

Then simply copy the skeleton into your project

cp -r ./vendor/fatalus/feather/skeleton/* ./

Create a public/index.php file: Or copy the code from skeleton/ into your projects root and you're good to go!

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use Feather\Kernel;

define('FEATHER_ROOT', realpath(rtrim(__DIR__ . '/..', DIRECTORY_SEPARATOR)));

$kernel = new Kernel();

echo $kernel->handle();

If the entry point to your Web-Server is not located at public/index.php, remember to adjust the FEATHER_ROOT constant accordingly so it points to the project root. Note that if you do not use any of the Feather Components you do not have to define this constant, as it is soely used by Feahter's internal components.

Routing

Create a routes.php file in the project root.

<?php

$engine = new Feather\Engine();
$auth = new MyApp\Controller\AuthController();
$post = new MyApp\Controller\PostController();

return [
  'GET' => [
    '/' => fn() => $engine->render('home'),
    '/hello' => fn() => 'Hello, world!',
    '/posts/{post_id}' => fn($params) => $post->show($params),
  ],
  'POST' => [
    '/login' => fn() => $auth->login(),
  ],
];

Routes are matched using regex, to use named capture groups.

Templates

Create a templates/ directory in the project root like this. You can also structure them by putting them in seperating folders.

templates/
├── layouts/
    ├── app.phtml
    └── admin.phtml
├── admin/posts/
    └── edit.phtml
├── home.phtml
└── about.phtml

Templates can be rendered from anywhere using the Engine.

$engine = new Feather\Engine();

return [
  'GET' => [
    '/' => fn() => $engine->render('home'),
    '/' => fn() => $engine->render('admin/posts/edit'),
  ]
];

The actual syntax of the templates is highly inspired by Blade. If you are used to writing Blade or CakePHP templates, you'll feel pretty much at home. This template extends the layouts/app.phtml template and renders the content inside the content section in its designated place.

<?php $this->extend('layouts/app'); ?>
<?php $this->start('content'); ?>
  <div>
    My awesome website!
  </div>
<?php $this->end(); ?>

To understand this further, lets also take a look at the template we're extending here. This is basically just a bare html setup. And just like in Laravel or Cake we can also include different templates that we want to have in a different place using the include.

<body class="bg-gray-950 text-white container mx-auto">
    <header class="mb-8">
        <?= $this->include('partials/nav') ?>
    </header>
    <main>
        <?= $this->yield('content') ?>
    </main>
    <footer class="mt-8">
        <?= $this->include('partials/footer') ?>
    </footer>
</body>

At the moment:

  • Templates must be located inside templates/
  • Templates must use the .phtml extension
  • Templates should contain a complete HTML document
  • Some default templates, like 404 are located in the frameworks directory

Caching

A very simplified version of Caching any form of data in the json format. This is a component that is very optional and completely independent.

The cached data gets stored in your projects' root directory in the cache/ directory as {cache_name}.cache. Therefore the cached data can be retrieved from anywhere in your project.

You can Cache data and retrieve it again by simply doing this:

<?php

use Feather\Cache;

$my_data = [
  'test' => true,
  'dataset' [
    'new' => true,
    'creation_time' => time(),
    'data' => [
      1, 2, 3, 4
    ]
  ]
];

Cache::cacheData('my_data', json_encode($my_data));

$my_cached_data = Cache::get('my_data');

Extending Functionality

The Framework can be completely customized as it was built with the purpose of being completely Modular. As an example, if you want to change the Routing Component from the Default one Provided by Feather, you can simply create your own by implementing the Feather\Contracts\RoutingInterface class. Then you can pass your custom Router into the Kernel which will then handle the Routing for you. For this to work you'll need to adjust the index.php to include your custom router.

<?php

$kernel = new Kernel(new MyApp/Router(), new MyApp/Request());

Project Structure

A Feather Project should look something like this:

my-app/
├── public/
│   └── index.php
├── templates/
│   └── home.phtml
├── routes.php
├── development.php
├── vendor/
├── src/
└── composer.json

About

A modular, minimalist PHP microframework

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages