Day: December 15, 2021

Learning Fat-Free PHP Framework

Learning Fat-Free PHP Framework

Fat-Free PHP Framework is used to create MVC application.

Make Fat-Free work

Install composer

  • Go to https://getcomposer.org

  • Select Installation => Globally

  • Download installer and run it using php, then composer.phar is created

  • Move composer.phar to system directory

mv composer.phar /usr/local/bin/composer

Install Fat-Free

  • Create a new project folder

  • Init composer, and answer some questions, then composer.json is created

composer init
  • Go to http://getcomposer.org, select Browse Packages, then go to https://packagist.org.

  • Search fatfree to find out package name, bcosca/fatfree

  • Install bcosca/fatfree

    • by editing composer.json file

    Add following lines

      "require": {
        "bcosca/fatfree": 3.5.0
      }
    }

    Run composer update, to install fatfree in vendor directory, and composer.lock is created

    • by command
    composer require bcosca/fatfree

Autoload

There is an autoload.php file in vendor/composer directory, this is to load packages

In base.php

  • Singleton Base class extends from abstract class Prefab

  • $hive has all configuration, context

  • Function set is to set variables

  • Function get is to read variables

  • Function run needs to be called to make F3 work and running

Create index.html

require_once("vendor/autoload.php");

$f3 = Base::instance();

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

...

$f3->run();

Note, if don't use composer, then will be like

$f3 = require('path/to/base.php');
...
$f3->run();

Launch PHP server

php -S localhost:8088 -t .

Config, Controller, View

Set/get global variables

$f3->set('message', 'Hello, World!');

$f3->route('GET /',
  function($f3) {
    echo $f3->get('message');
  }
);

Create route class

class MainController {
  function render() {
    echo 'Hello, World!';
  }
}

$f3->route('GET /', 'MainController->render');

beforeroute and afterroute function

Mainly for session management

class Controller {
  function beforeroute() {
    echo 'before';
  }

  function afterroute() {
    echo 'after';
  }
}

class MainController extends Controller {

}

configuration variables

  • DEBUG

  • AUTOLAD - to load a folder which contains the classes

  • CACHE

  • UI - location of UI templates, separate folders using delimiter

$f3->set('DEBUG', 1);

Create config.ini

In config.ini file

[globals]

DEBUG=1
messagehello=Hello hello!

In index.php

$f3->config('config.ini');

class MainController extends Controller {
  function render($f3) {
    echo $f3->get('messagehello');
  }
}

Create routes.ini

In routes.ini

[routes]

GET /=MainController->render
GET /hello=MainController->sayhello
GET /about=AboutPage->render

In index.php

$f3->config('routes.ini');

Templates

In normal php

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

In F3

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

In index.php

  function render($f3) {
    $f3 ->set('name', 'world');
    $template = new Template;
    echo $template->render('template.htm');
  }

Template file template.htm

<!DOCTYPE html>
<html>
<head>
    <title>Tutorial page</title>
</head>
<body>
    <p>Hello, {{ @name }}!</p>
</body>
</html>

Create project structure

In project folder

project/index.php
project/config.ini
project/routes.ini
project/app
project/app/controllers
project/app/controllers/Controller.php
project/app/controllers/MainController.php
project/app/views
project/app/views/template.htm

In config.ini file

[globals]

DEBUG=3
UI=app/views/
AUTOLOAD=app/controllers/

In index.php file

<?php

require_once("vendor/autoload.php");

$f3 = Base::instance();

$f3->config('config.ini');
$f3->config('routes.ini');

$f3->run();

Model (database)

Create database

  • Install PHP development environment XAMPP or MAMP

  • Install MySQL workbench

apt install mysql-workbench
  • Create database

  • Create schema

database Connection

  • Update database info in config.ini
devdb = "mysql:host=127.0.0.1;port=3306;dbname=f3MVC"
devdbusername = "f3admin"
devdbpassword = "f3admin"

Update Controller class

class Controller {
    protected $f3;
    protected $db;

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

        $db = new DB\SQL(
            $f3->get('devdb'),
            $f3->get('devdbusename'),
            $f3->get('devdbpassword'),
            array( \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION )
        );

        $this->db = $db;
    }
}

For other classes

$this->f3

Create project models

Create folder and a file project/models/Messages.php, which is reading all data from messages table, and then create objects.

<?php

class Messages extends DB\SQL\Mapper {
    public function __construct(DB\SQL $db) {
        parent::__construct($db, 'messages');
    }

    public function all() {
        $this->load();
        return $this->query;
    }
}

Update config.ini

AUTOLOAD=app/controllers/|app/models/

Update render function in MainController class

$messages = new Messages($this->db);
$msg = $messages->all()[0];

$f3->set('msg', $msg);

Update template.htm

<p>Hello, {{ @msg.message }}</p>

Standard implementation of model

<?php

class Messages extends DB\SQL\Mapper {
    public function __construct(DB\SQL $db) {
        parent::__construct($db, 'messages');
    }

    public function all() {
        $this->load();
        return $this->query;
    }

    public function getById($id) {
        $this->load(array('id=?', $id));
        return $this->query;
    }

    public function add() {
        $this->copyFrom('POST');
        $this->save();
    }

    public function edit() {
        $this->load(array('id=?', $id))
        $this->copyFrom('POST');
        $this->update();
    }

    public function delete($id) {
        $this->load(array('id=?', $id))
        $this->erase();
    }
}

Note: copyFrom also can do from hashmap

Save record

$message = new Messages($this->db);
$message->key = 'Secondmessage';
$message->message = 'This is the second message inserted from code.';
$message->save();

Change global to class protected variable

This allow all functions in the class do not need to pass f3 as parameter

class Controller {
    ...
    protected $f3;

    ...
}

class MainController extends Controller {
    function render() {         // Don't need f3 as parameter
        ...
        $this->f3->set('msg', $msg);
        ...
    }
}

getById

$msg = $messages->getById(8)[0];

References

Fatfree PHP Framework Tutorial - 1
Fatfree PHP Framework Tutorial - 2
Fatfree PHP Framework Tutorial - 3
Fatfree PHP Framework Tutorial - 4

Disable Apple mouse swipe action

Disable Apple mouse swipe action

It is very easy for Apple mouse understands wrongly, and take action to back to my previous page. As the result, my few hours working on WordPress disappered.

Change mouse

Then I start using normal mouse, but hard to change between screen using keyboard, my remote control and virtual machine doesn't understand the keys, and holding keyboard actions made wrong password in login screen.

Disable swipe action

Then I found the way to disable swipe action as below

system preferences>trackpad or mouse>more gestures tab>uncheck "swipe between pages".

References

I just accidentally swiped right on my web page...how do I get it back?