Fat-Free Framework

Version 3.6 - Release Notes

What's included?

 

  • a lot of performance and stability improvements
  • console-friendly CLI mode
  • cache tags for SQL
  • custom FORMATS
  • refactored SMTP plugin
  • Mapper, Image, Web plugin tweaks
  • new WebSocket server (RFC6455)
  • lightweight OAuth2 client
  • optimized config and language file parsing
  • reduced cache queries
  • improved float support for SQL mapper
  • new option to skip startup (server) errors

 

Important changes

 

  • PHP 5.4 is now the required minimum version
  • ALIASES isn't automatically resolved at start anymore
    • it's still build-up within template sandbox
    • use Base->alias in controllers or the alias template filter to resolve named routes:
      {{ @pageX | alias }}
  • Wildcards now matching empty strings
    • /foo* matches /foo/bar and /foo
    • /* matches / as well as /foo and everything else
    • NEW: PARAMS.* contain wildcard segments
  • cached HIVE keys are only updated when a $ttl is set

More Alias routing

reroute

The URL argument can now be used as array for aliasing:

$f3->route('GET @filter: /search/@a/@b', function( \Base $f3) {});

// old way, but still valid
$f3->reroute('@filter(a=foo,b=bar)?time=3');

// new
$f3->reroute(['filter','a=foo,b=bar','time=3']);
// or
$f3->reroute(['filter',['a'=>'foo','b'=>'bar'],['time'=>3]]);

this will reroute to:

http://domain.com/search/foo/bar?time=3

The existing aliasing methods have been updated to match the new wildcard behaviour. Furthermore you'll find little tweaks like the following:

New in Base

extend

A simple way to add some default values to an array

$f3->set('settings',[
	'foo'=> 1,
	'bar'=> 'baz',
	'colors'=>[
		'blue'=>1,
		'green'=>2
	]
]);
$f3->set('defaults',[
	'foo'=>0,
	'zzz'=>2,
	'colors'=>[
		'red'=>3,
		'blue'=>4
	],
]);
$settings = $f3->extend('settings','defaults');
print_r($settings);
Array
(
    [foo] => 1
    [zzz] => 2
    [colors] => Array
        (
            [red] => 3
            [blue] => 1
            [green] => 2
        )

    [bar] => baz
)

Error Handling

 

F3 usually checks for system errors on initialization.

This ensures that you get notified about common server issues, misconfiguration and problems in loaded third-party libs.

Unfortunately, this can also be a problem on some hosting environments, where you don't have a chance to fix that.

Hence, here is a simple way to skip those startup error checks:

error_reporting(0);
$f3 = require('lib/base.php');


// or as one-liner:

@$f3 = require('lib/base.php');
// or
$f3 = @require('lib/base.php');

Error Level

 

The ERROR variable additionally contains the error level now:

$f3->set("ONERROR", function($f3, $params) {
  if ($f3->{'ERROR.level'} == E_WARNING ) {
    // Don't stop at warnings:
    $f3->HALT = false;
    return true;

  } else {
    // Process more serious problems:
    echo "Error: ".$f3->get('ERROR.text')."\n";
    $f3->HALT = true;
    return false;
  }
});

Config Files

When you use .ini files, you now have the possibility to add a caching option, which can be utilized by special HIVE vars:

 

 

LOCALES = /path/to/lexicons | 3600

It's also possible to write custom section parsers now:

 

 

[widget > Config->parse]
option1 = foo
option2 = bar
class Config extends \Prefab {

	/** @var static \Base */
	protected $f3;

	function __construct() {
		$this->f3 = \Base::instance();
	}

	public function parse($key, $value, $scope) {
		$this->f3->set($scope.'.'.$key, $value);
	}
}

Custom FORMATS

The Base->format method and it's template filter can be used to format your strings in several ways. It's now possible to specify custom format rules to add support for multiple localization formats or other cases:

 

 

;en.ini
score = Score: {0, plural, zero {0}, one {1 point}, other {# points}}
;pl.ini
score = Wynik: {0, polish, 1 {1 punkt}, 2 {# punkty}, 5 {# punktów}}
<p>{{ @score, 1202 | format }}</p>

In your template:

You would declare two dictionary files:

$f3->set('FORMATS.polish','FormatHelper->polish');

Register a custom formatter (see this snippets page for code samples):

English: "Score: 1202 points"
Polish: "Wynik: 1202 punkty"

Output:

CLI mode

A new optimized cli-mode allows writing a command line tool, to be more developer friendly with these added options:

[routes]
GET /log/show [cli]      = CLI\Log->show
GET /log/clear [cli]     = CLI\Log->clear
GET /cache/clear [cli]   = CLI\Cache->clear
GET /help [cli]          = CLI\Help->index
GET /help/@command [cli] = CLI\Help->@command

Easier to use CLI attributes:
(options are stored in the QUERY string)

Configuration Options (.ini file):

-v => ?v=
-n=23            => ?n=23
--force          => ?force=
--grep=foo       => ?grep=foo
-long            => ?l=&o=&n=&g=
-ab -c=4 --debug => ?a=&b=&c=4&debug=
$ php index.php help cache --grep=foo

Examples:

$ php index.php cache clear -fvi

would request: GET /help/cache?grep=foo

 would request: GET /cache/clear?f=&v=&i=

New HIVE variable: CLI

It's a boolean variable, that is TRUE, when the script is called from console.

SQL Cache Tags

Does your application use caching at the database layer and sometimes need to remove only a certain subset of cache entries? Now you can easily invalidate those by using cache tags.

// controller1
$db->exec($sql,$args,[3600,'product']); // <-- tag that query as 'product' related
$mapper->find($filter1,$opts,[3600,'product']); // idem

// controller2
$mapper->find($filter2,$opts,[3600,'product']); // idem

// controller3
$mapper->find($filter3,$opts,[7200,'customer']); // different tagging here

// controller 4 (clear 'product' related cached queries)
$cache->reset('product');
// the default way of caching with an integer $ttl (3600 = 1 hour)
$db->exec($sql, $args, 3600);
$mapper->find($filter1, $opts, 3600);

Now you can set an array as argument to the $ttl parameter

Cache Growth

New framework variable: SEED

SERVER-NAME            SEED
-------------------------------------
cdn.domain.com    =    h6qqa2jvtoez
domain.com        =    3awbd3dh8n400

It's used as a globally customizable prefix name for cache entries and temp filenames. In case you use multiple domains with your application, the auto-generated SEED value would be different to avoid collisions.

If you want to share a common cache and temp file storage across both domains, set a custom SEED before initializing the CACHE:

# index.php
$f3->set('SEED', $f3->hash('myDomainSEED'));
$f3->set('CACHE', TRUE);
# config.ini
SEED = myRandomAppSEED
CACHE = TRUE

Less Hype, More Meat

Even if it sometimes might get quiet around the corner, the F3 enthusiasts are constantly improving the performance and stability of the core, which wouldn't be possible without your great ideas and friendly feedback - Thank You!

That being said, you are using one of the fastest PHP frameworks out there - now even proven by independent benchmarks:

TechEmpower Framework Benchmarks Round 13 (2016-11-16)

Thanks to all contributors

For the full list of features, fixes and updates in v3.6,

please see the CHANGELOG.

(c) 2016 - F3::Factory

Fat-Free Framework v3.6

By ikkez

Fat-Free Framework v3.6

Release Notes

  • 3,044