Fat-Free Framework

Álvaro José Agámez Licha - @CodeMaxter

MedellinPHP

Medellín - Colombia, 2014/09/11

A powerful yet easy-to-use PHP micro-framework designed to help you build dynamic and robust web applications - fast!

Caraterísticas

  1. Full-featured toolkit
  2. Super lightweight code base with just ~65kb
  3. Easy to learn, use and extend
  4. Optional plug-ins that extend its capabilities
  5. High-performance URL routing
  6. Support for multilingual i18n applications
  7. Easy built-in template system
  8. ReST: Representational State Transfer make easy

¿Por qué usar F3?

No se mete en tu camino

F3 no establece ningún extraño patrón MVC preestablecido que debamos seguir.

Podemos seguir el patrón MVC, RMR o simplemente procedural

Es increíblemente rápido

Debido a la simplicidad y reusabilidad de cada componente de F3 es increíblemente veloz

F3 soporta bases de datos SQL estándar y NoSQL: MySQL, SQLite, MSSQL/Sybase, PostgreSQL, DB2 y MongoDB. También viene con poderosos Mapeadores objeto-relacional para la abstracción y modelado de datos, que son tan ligeros como el framework. No es necesaria ninguna configuración adicional.

¿Bases de Datos?

Instalación

Fat-Free puede ser instalado vía composer muy fácilmente.

{
    "name": "fat-free/medellin-php",
    "require": {
        "bcosca/fatfree": "3.3.0"
    },
    "authors": [
        {
            "name": "YourName",
            "email": "your.email@outlook.com"
        }
    ]
}

composer init

completar los datos requeridos

composer install

Verificación

Una vez instalado fat-free podemos verificar que todo esté correcto y el soporte que tengamos configurado en nuestro PHP iniciando un servidor local en el directorio donde instalamos fat-free y navegador a http://localhost:8000/vendor/bcosca/fatfree/

php -S localhost:8000

SHOW ME THE CODE

Hello, World: The Less-Than-A-Minute Fat-Free Recipe

<?php

require(__DIR__ . '/vendor/autoload.php');
$f3 = require(__DIR__ . '/vendor/bcosca/fatfree/lib/base.php');

$f3->route('GET /', function() {
        echo 'Hello, world!';
    }
);

$f3->run();

Routing Engine

F3 trae consigo un routing engine bastante potente y a la vez simple de usar; podemos generar rutas hacia funciones anónimas, métodos públicos de objetos o métodos estáticos públicos de clases.

$f3->route('GET /about', function() {
        echo 'Donations go to a local charity... us!';
    }
);

class WebPage
{
    function display()
    {
        echo 'I cannot object to an object';
    }
}

$f3->route('GET /about','WebPage->display');

$f3->route('GET /login','Auth::login');

Routes and Tokens

$f3->route('GET /brew/@count', function($f3) {
        echo $f3->get('PARAMS.count').' bottles of beer on the wall.';
    }
);

$f3->route('GET /brew/@count', function($f3,$params) {
        echo $params['count'].' bottles of beer on the wall.';
    }
);

$f3->route('GET /brew/*', function() {
        echo 'Enough beer! We always end up here.';
    }
);

F3 nos permite definir rutas con token en ellas, donde recibiremos parámetros que podemos recuperar muy fácilmente.

Named Routes

El routing engine de F3 nos permite definir nombres para nuestras rutas y así poder usarlas de manera más cómoda, por ejemplo en las vistas.

$f3->route('GET @beer_list: /beer', 'Beer->list');

<a href="{{@ALIASES.beer_list}}">view beer list</a>

// a named route is a string value
$f3->reroute('@beer_list'); // note the single quotes

// if more than one token in your route is needed
$f3->route('GET @beer_village_list: /beer/@country/@village', 'Beer->byvillage');
$f3->reroute('@beer_village_list(@country=Germany,@village=Rhine)');

Rerouting

Hacer redirección de rutas en F3 es muy sencillo, como todo en F3:

$f3->route('GET|HEAD /obsoletepage', function($f3) {
        $f3->reroute('/newpage');
    }
);

Triggering a 404

$f3->error(404);

En tiempo de ejecución, F3 genera automáticamente un error HTTP 404 cuando ve que una solicitud HTTP entrante no coincide con ninguna de las rutas definidas en la aplicación. Sin embargo, hay casos cuando necesitamos activarlo por nosotros mismos.

Representational State Transfer

Desarrollar un servicio ReST con F3 es supremamente sensillo, ya que el framework me permite mapear una clase con una ruta específica y F3 se encargará de enrutar las peticiones a los correspondientes métodos

class Item
{
    function get()
    {
    }
    function post()
    {
    }
    function put()
    {
    }
    function delete()
    {
    }
}

$f3=require('lib/base.php');
$f3->map('/cart','Item');
$f3->run();

Views and Templates

En F3 puedes usar PHP como template o el sistema de templates integrado del framework.  Personalmente me gusta este sistema y es el que aconsejo usar.

<p>Hello, <?php echo $name; ?>!</p>

<p>Hello, <?= $name ?></p>

$f3 = require('lib/base.php');
$f3->route('GET /',
    function($f3) {
        $f3->set('name','world');
        $view = new View;
        echo $view->render('template.htm');
        // Previous two lines can be shortened to:
        // echo View::instance()->render('template.htm');
    }
);
$f3->run();

A Quick Look at the F3 Template Language

<p>Hello, {{ @name }}!</p>

$f3->set('buddy', ['Tom','Dick','Harry']);

<p>{{ @buddy[0] }}, {{ @buddy[1] }}, and {{ @buddy[2] }}</p>

$f3->set('func',
    function($a,$b) {
        return $a.', '.$b;
    }
);

{{ @func('hello','world') }}

¿Y qué hay del rendimiento de este sistema de plantillas?

Compiled Templates

En tiempo de ejecución, F3 analiza y compila/convierte una plantilla F3 a código PHP la primera vez que se visualiza mediante $template->render().  F3 utiliza este código compilado en todas las llamadas subsiguientes. Por lo tanto, el rendimiento debe ser igual a los templates PHP, si no mejor debido a la optimización de código realizada por el compilador de plantillas cuando están involucradas plantillas complejas.

Conditional Segments

<check if="{{ @page=='Home' }}">
    <false><span>Inserted if condition is false</span></false>
</check>
<check if="{{ @gender=='M' }}">
    <true>
        <div>Appears when condition is true</div>
    </true>
    <false>
        <div>Appears when condition is false</div>
    </false>
</check>

Repeating Segments

<repeat group="{{ @fruits }}" value="{{ @fruit }}">
    <p>{{ trim(@fruit) }}</p>
</repeat>

<repeat group="{{ @div }}" key="{{ @ikey }}" value="{{ @idiv }}">
    <div>
        <p><span><b>{{ @ikey }}</b></span></p>
        <p>
        <repeat group="{{ @idiv }}" value="{{ @ispan }}">
            <span>{{ @ispan }}</span>
        </repeat>
        </p>
    </div>
</repeat>

Multilingual Support

No podría ser de otra manera, el manejo de la internacionalización en F3 es muy simple de realizar:

<?php
return array(
    'love'=>'I love F3',
    'today'=>'Today is {0,date}',
    'pi'=>'{0,number}',
    'money'=>'Amount remaining: {0,number,currency}'
);
<h1>{{ @love }}</h1>
<p>
{{ @today,time() | format }}.<br />
{{ @money,365.25 | format }}<br />
{{ @pi }}
</p>
$f3->set('LOCALES','dict/');
$f3->set('LANGUAGE','en');

Connecting to a Database Engine

Fat-Free está diseñado para hacer que el trabajo con bases de datos SQL sea muy fácil.

$db = new DB\SQL('sqlite:/absolute/path/to/your/database.sqlite'));

$db = new DB\SQL(
    'mysql:host=localhost;port=3306;dbname=mysqldb',
    'admin',
    'p455w0rD'
);

Querying the Database

Ya vimos que es muy fácil establecer una conexión con nuestras bases de datos, ¿pero cómo ejecuto sentencias SQL?

$f3->set('result', $db->exec('SELECT brandName FROM wherever'));
echo Template::instance()->render('abc.htm');

<repeat group="{{ @result }}" value="{{ @item }}">
    <span>{{ @item.brandName  }}</span>
</repeat>

Transactions

Fat-Free realmente hace que todo sea muy fácil, así que el método exec puede recibir un array de sentencias SQL e iniciará una transacción por nosotros, haciendo rollback si algo falla, todo automágicamente.

$db->exec([
    'DELETE FROM diet WHERE food="cola"',
    'INSERT INTO diet (food) VALUES ("carrot")',
    'SELECT * FROM diet'
]);

// También podemos iniciar y finalizar una transacción programativamente:
$db->begin();
$db->exec('DELETE FROM diet WHERE food="cola"');
$db->exec('INSERT INTO diet (food) VALUES ("carrot")');
$db->exec('SELECT * FROM diet');
$db->commit();

// Para obtener una lista de todas las instrucciones sobre la base de datos:
echo $db->log();

Parameterized Queries

Los queries parametrizados nos ayudan a protegernos de los ataques más comunes de inyección SQL; Fat-Free nos hace nuevamente fácil la vida implementándolos.

$db->exec(
    'SELECT * FROM users WHERE userID=?',
    $f3->get('POST.userID')
);

$db->exec([
        'DELETE FROM diet WHERE food=:name',
        'INSERT INTO diet (food) VALUES (?)',
        'SELECT * FROM diet',
    ], [
        [':name' => 'cola'],
        [1 => 'carrot'],
        NULL,
    ]
);

CRUD (But With a Lot of Style)

F3 viene con Mapeadores objeto-relacional (ORM) fáciles de usar, que se integran entre nuestra aplicación y los datos (haciendo mucho más fácil y más rápido el escribir programas que manejen operaciones de datos comunes) como crear, consultar, actualizar y eliminar (CRUD) información de bases de datos SQL y NoSQL.

 

CRUD (But With a Lot of Style)

CREATE TABLE users (
    userId VARCHAR(30),
    password VARCHAR(30),
    visits INT,
    PRIMARY KEY(userID)
);

$db = new DB\SQL(
    'mysql:host=localhost;port=3306;dbname=mysqldb',
    'admin',
    'wh4t3v3r'
);

$user = new DB\SQL\Mapper($db, 'users');
$user->load(['userId = ?', 'codemaxter']);

$db = new DB\Mongo('mongodb://localhost:27017', 'testdb');
$user = new DB\Mongo\Mapper($db, 'users');
$user->load(['userId'=>'codemaxter']);

Fat-Free for the win

Fat-Free contiene muchas más funcionalidades de las aquí presentadas, así que los invito a visitar la guía de usuario oficial para aprender mucho más

Gracias...

Fat-free PHP

By Alvaro Agamez

Fat-free PHP

  • 1,255