Tag: php

Learning – Fat-Free PHP Framework (Template Hierarchy)

Learning - Fat-Free PHP Framework (Template Hierarchy)

Template Hierarchy

Copy from bootstrap

  • Go to https://getbootstrap.com/getting-started/#examples, select Dashboard.

  • Copy dashboard.htm to app/views/dashboard.htm

  • Copy dashboard.css into app/css/dashboard.css

  • Create app/views/header.htm

    • Move html header in dashboard.htm into header.htm
    • Delete unecessary javascript for IE8
    • Update bootstrap.min.css to CBN version
    • Update the path of dashboard.css
  • Create app/views/layout.htm

<include href="header.htm" />
<include href="{{ @view }}" />
  • Update MainController class
<?php

class MainController extends Controller {
    function render() {
        $this->f3->set(&#039;view&#039;, &#039;dashoboard.htm&#039;);
        $template = new Template;
        echo $template->render(&#039;layout.htm&#039;);
    }
}
  • Create nav.htm

Move the body contents before Dashboard div into file nav.htm

<body>
    ...
    ...
            <ui class="nav nav-sidebar">
                ...
            </ui>
        </div>

References

Template Hierarchy in Fat-Free PHP Framework Sample Project

Learning – Fat-Free PHP Framework – Posts List

Learning - Fat-Free PHP Framework - Posts List

This is the summary list of my posts during learning.

References

Learning - Fat-Free PHP Framework
Learning - Fat-Free PHP Framework (Bootstrap & Authentication)
Learning - Fat-Free PHP Framework (Template Hierarchy)
Learning - Fat-Free PHP Framework (Data Sets)

Learning – Fat-Free PHP Framework (Data Sets)

Learning - Fat-Free PHP Framework (Data Sets)

Data Sets

Do some RESTfull, serializable...

Display messages

  • Create Nav Sidebar Menu /messages
<li><a href="/messages">Messages on UI f3 template</a></li>
  • Update routes.ini

    Add following

GET /messages=MainController->displayMessages
  • Update MainController.php

    Add displayMessages in MainController class

class MainController extends Controller
{
    ...

    function displayMessages() {
        $messages = new Messages($this->db);

        $this->f3->set('messages', $messages-all());
        $this->f3->set('view', 'messages.htm');
        $template = new Template;
        echo $template->render('layout.htm');
    }
}
  • Create view messages.htm
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
    <h1 class="page-header">Messages UI from template</h1>

    <repeat group="{{ @messages }}" value="{{ @message }}">
        <p>{{ @message.id }} {{ @message.key }} {{ @message.message }}</p>
    </repeat>
</div>

Dipplay messages as JSON using AJAX call

  • Create Nav Sidebar Menu /api/messages
<li><a href="/api/messages">Messages JSON REST API</a></li>
  • Update routes.ini

    Add following

GET /api/messages=MainController->apiMessages
  • Update MainController.php

    Add displayMessages in MainController class

class MainController extends Controller
{
    ...

    function apiMessages() {
        $messages = new Messages($this->db);
        $data = $messages->all();

        $json = array();

        foreach ($data as $row)
            $items = array();

            foreach ($row as $key => $value) {
                $items[$key] = $value;
            }

            array_push($json, $items);
        }

        echo json_encode($json);
    }
}

Note: The echo json_encode($data); doesn't work, because $messages->all() from model has returned some non public attributes

*Note: As the output is the JSON data, no view need to be defined.

Display messsages using REST API

Create new display messages page utilizes the REST API.

  • Add menu in app/views/nav.htm
<li><a href="/messageajaxview">Message UI with AJAX</a></li>
  • Create route in routes.ini
GET /messageajaxview=MainController->displayMessagesAjaxView
  • Create function in app/controllers/MainController.php
function displayMessagesAjaxView() {
    $this->f3->set('view', 'messagesajax.htm');
    $template=new Template;
    echo $template->render('layout.htm');
}
  • Create template app/views/messageajx.htm
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
    <h1 class="page-header">Message UI with AJAX</h1>

    <button type="button" class="btn btn-default btn-lg">Fetch messages</button>

    <div id="msg-container"></div>
</div>
  • Create javascript file app/js/f3sample.js

  • Include jquery and javascript in app/views/header.htm

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="app/js/f3sample.js"></script>

Then the f3sample.js should be shown the resources in browser development tools.

References

Displaying data sets and creating a Rest API with the Fat-Free PHP Framework

Learning – Dockerfile

Learning - Dockerfile

This is to refresh my Dockerfile knowledge.

alphine

Create Dockerfile

FROM alphine:3.4
MAINTAINER Mark Takacs mark@takacsmark.com

RUN ark update
RUN ark add vim
RUN apk add curl

Build

docker build -t taka/alpine-smarter:1.0 .

Intermediate images

The Docker intermediate images can speed up the rebuilding process.

docker images -a

To reduce number of intermediate images, update Dockerfile as below

FROM alphine:3.4
MAINTAINER Mark Takacs mark@takacsmark.com

RUN ark update && \
       ark add vim && \
       apk add curl

Clean up dangling image

docker images --filter "dangling=true"
docker rmi $(docker images -q --filter "dangling=true")

python

Dockerfile

  • For normal python
FROM python:3.6.1

RUN pip install numpy
  • For alpine version takes much longer time to build
FROM python:3.6.1-alpine

RUN apk update && apk add build-base
RUN ln -s /usr/include/locale.h /usr/include/xlocale.h

RUN pip install numpy scipy

conda3

  • miniconda3
docker run --rm -ti continuumio/miniconda3 /bin/bash
conda list
conda install numpy
  • anaconda3
docker run --rm -ti continuumio/anaconda3 /bin/bash
conda list

phpslim

Dockerfile

Choose php:7.1.2-apache

Got to https://getcomposer.org, and run installation commands in container

FROM php:7.1.2-apache

RUN ....

COPY ./composer.json /var/www/html/

RUN apt-get update & apt-get install -y git

RUN composer install

Map directory

To run docker container with option -v /var/www/html/vendor to indicate using image /var/www/html/vendor folder.

docker run --rm -v $(pwd):/var/www/html/ -v /var/www/html/vendor -p 80:80 takacsmark/phpslim-tut:1.0

As the result, the /var/www/html is mapped to local directory, but /var/www/html/vendor is image directory.

Change DocumentRoot

Add following line into Dockerfile to change the DocumentRoot to /var/www/html/public

RUN set -i 's/DocumentRoot.*$/DocumentRoot \/var\/www\/html\/public/' /etc/apache2/sites-enabled/000-default.conf

Enable default hello message

Create a file /var/www/html/public/.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

Run following command in container to enable module rewrite

a2enmod rewrite

Then add following line in Dockerfile

RUN a2enmod rewrite

Options

COPY

COPY ./config.txt /usr/src/config.txt

ADD

  • Add URL file from internet

  • Add tar file

  • Add compressed file

RUN

EXPOSE

Port

USER

WORKDIR

ARG

LABEL

ENTRYPOINT & CMD

To run command echo Welcome after container created, following configuration can be used.

CMD "Welcome"
ENTRYPOINT echo

The CMD option can be replace using docker run command line, ENTRYPOINT can't. For example, following command will run echo Hello.

docker run echo_image 'Hello'

ENV

References

Dockerfile Tutorial by Example - ( Part I - Basics )
Dockerfile Tutorial by Example - ( Part II - Best practices )
Dockerfile Tutorial by Example - ( Part III - Creating a docker PHP Slim image )

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