আগামী ৩০ নভেম্বর-২০১৭ তারিখ থেকে শুরু হচ্ছে পাঁচ মাস ব্যাপী Professional Web Design and Development with HTML, CSS PHP,MySQL,JavaScript, AJAX, JQUERY, Bootstrap and Live Project কোর্সের ৮৭ তম ব্যাচ এবং ২৪ নভেম্বর-২০১৭ তারিখ থেকে শুরু হচ্ছে চার মাস ব্যাপী Zend PHP-7 Certified PHP Engineering (Advance PHP) কোর্সের ৩৫ তম ব্যাচ। প্রত্যেকটি কোর্স এর ফী নির্ধারণ করা হয়েছে ৩০,০০০/= আগ্রহীদেরকে অতিসত্বর মাসুদ আলম স্যার এর সাথে যোগাযোগ করতে অনুরোধ করা যাচ্ছে। স্যার এর মোবাইল: 01722 81 75 91

CRUD with Fat Free Framework

We have learnt some good and useful features of F3 in some previous posts. We have already learnt “Routing and Event Handlers “, “Framework Variables” and “Templating“. So hope we are prepared to start practice with database.

Here we will try to create a CRUD system using F3, MVC design pattern and Bootstramp.

Before start, you can take a look at live demo:: .

So let start::

First of all we will download the F3 from :: Download link. Put the framework contents in Web root. Here we will make a new directory named “f3-crud” and put framework contents into it.

contents_of_f3

So “f3-crud” directory will has contents like above screen shot.
Since we will follow MVC pattern so we will create our own choice directory structure. F3 gives us a lot of flexibility to have a folder structure that as we like. Just need to set the appropriate F3 global variables.

1) config :: make a “config” directory in “f3-crud”, here we will keep routing and config related files.
2) tmp :: make a “tmp” directory in “f3-crud”, here F3 will store all cache files.
3) app :: make a “app” directory in “f3-crud”, here we will keep controller, model and views related files.
4) controllers :: make a “controllers” directory in “app” for keep all controller’s related files.
5) models :: make a “models” directory in “app” for keep all model’s related files.
6) views :: make a “views” directory in “app” for keep all view’s/template’s related files.

So our “f3-crud” application’s directory structures will look like below (red marked are newly created)::

fat free framework

Now its time to clean up F3‘s default things.

1) Open “f3-crud -> index.php” file. Remove all lines but only except below tow lines::

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

$f3->run();

2) Remove all files and directories from “f3-crud -> UI” directory. so our UI directory is now empty.

“f3-crud” is ready for develop our desired crud application.

Create new file “config.ini” in directory “f3-crud -> config”, in this file we will define some F3 Framework Variable and our own config variable.
add below lines::

[globals]

DEBUG=3

Here we defined one F3 variable “DEBUG” and set the value 3 so that we can see our error.

Create a new file “routes.ini” in directory “f3-crud -> config”, in this file we will keep all our routes.
just for now add one line in this file like below::

[routes]

Now download Twitter Bootstrap and put all three directory in “f3-crud -> UI”. So “UI” directory will look like as below::

fat free framework

Now we will create a mysql table in our database. The table name will be “users”.
Create a new table using below query::

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) CHARACTER SET latin1 NOT NULL,
  `email` varchar(150) CHARACTER SET latin1 NOT NULL,
  `mobile` varchar(20) CHARACTER SET latin1 NOT NULL,
  `address` varchar(255) CHARACTER SET latin1 NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=21 ;

And populate this “users” table using below query::

INSERT INTO `users` (`id`, `name`, `email`, `mobile`, `address`) VALUES
(1, 'Aaa Mii', 'al@min.com', '6546464', 'Dhaka,Bangladesh'),
(2, 'Saa Hee', 's@hed.com', '987979', 'Dhaka, Bangladesh'),
(3, 'Maa Muu', 'm@mun.com', '646465', 'Dhaka,Bangladesh'),
(9, 'Foo Saa', 'f@sa.com', '1234556', 'Dhaka, Bangladesh.');

Now this is time to start coding. First of all we will create a Base controller name “Controller” to initialize our database connection and F3‘s instance of “Base” Class. In directory “fr-crud -> app -> controllers” create a new file named “Controller.php”. and fill it with below class ::

class Controller {

    protected $f3;
    protected $db;

    function beforeroute() {
    }

    function afterroute() {
    }

    function __construct() {

        $f3=Base::instance();

        $db=new DB\SQL(
            $f3->get('db_dns') . $f3->get('db_name'),
            $f3->get('db_user'),
            $f3->get('db_pass')
        );

	$this->f3=$f3;
	$this->db=$db;
    }
}

In this “Controller” class we have two protected properties “f3” and “db”. Two Event Handler method, we will use these later. And the “__construct” where we initialized our protected properties.

You can see, we used some variables “db_dns”, “db_name”, “db_user” and “db_pass”, those variable will content database related information. so we have to define these variable in “config.ini” at directory “f3-crud -> config”, lets open it and add below lines and put your own database information.

db_dns=mysql:host=your_database_host_name;port=3306;dbname=
db_name=your_database_name
db_user=your_user_name
db_pass=your_password

Now we will create some common template like “header”, “footer” and “content”. To do this goto “f3-crud -> app -> views” directory and create three files named “header.htm”, “footer.htm” and “layout.htm”.

As content of “header.htm” put below code ::

<!DOCTYPE html>
<html lang="en">
    <head>
        <base href="{{ @BASE.'/'.@UI }}" />
        <title>{{ @site }}</title>
        <!-- Bootstrap -->;
        <link href="../../ui/css/bootstrap.min.css" rel="stylesheet" media="screen">
    </head>

    <body>

        <div class="container">

Here we set “site” for page title and used bootstrap css “bootstrap.min.css” which is located at “f3-crud -> ui ->css”.

As content of “footer.htm” put below code ::

    </div>

    <script src="http://code.jquery.com/jquery.js"></script>
    <script src="../../ui/js/bootstrap.min.js"></script>

    </body>
</html>

In “footer.htm”, we just include “jquery” and “bootstrap” js files and added necessary end tags.

As content of “layout.htm” file just put bollow two line code ::

<include href="header.htm" />
<include href="footer.htm" />

Here we included our header and footer template files by using F3‘s directive “include”.

In base controller “f3-crud -> app -> controllers -> Controller.php” we have a we have two event handler functions, one of these is named “afterroute”. Just add below line in this function ::

echo Template::instance()->render('layout.htm');

So it will render our output at the end.

We have already create a table “users” in our mysql database. Now we will create a model class for this table. We will use F3‘s data mapper mathod, so we will extend “DB\SQL\Mapper” in this model class.

Create a new file named “User.php” in directory “f3-crud -> app -> models” and put below code ::

class User extends DB\SQL\Mapper {

    public function __construct(DB\SQL $db) {
        parent::__construct($db,'users');
    }

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

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

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

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

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

Since we have to include/autoload our classes in this application, so we will add define our controller and model class’s path to F3‘s “AUTOLOAD” variable.
Open config.ini file from “f3-crud -> config” and put below line to it ::

AUTOLOAD=app/controllers/|app/models/

Here we separated two directory locations by pipe (|) separator. Now F3 will autoload all classes from these two location when need.

Now need to add another tow lines in this “config.ini”, one for assign the location of views/templates files and a global variable “site” which we used in out header.htm file. So add below two lines ::

UI=app/views/

site="F3 CRUD"

So our “config.ini” will look like below::

[globals]

AUTOLOAD=app/controllers/|app/models/

DEBUG=3

db_dns=mysql:host=localhost;port=3306;dbname=
db_name=test
db_user=root
db_pass=root

UI=app/views/

site="F3 CRUD"

Now we want to see list of users. so have to a routing in file routes.ini at “f3-crud -> config”, add below line ::

GET /=UserController->index

It means by GET request from url “http://localhost/f3-crud/” we want to see users list. now need to create a new controller file named “UserController.php” and new “index” method in this. create a php file in “f3-crud -> app -> controllers” with name “UserController.php” and put below code::

class UserController extends Controller {

    public function index()
    {
        $user = new User($this->db);
        $this->f3->set('users',$user->all());
        $this->f3->set('page_head','User List');
        $this->f3->set('view','user/list.htm');
    }
}

In “index” method we assigned “users” variable with all users, getting from method “all” model class “User” we have already created. assigned a “page_head” string and a new template file.
Now we will create a new template file in “f3-crud -> app -> views -> user”, so we have to create a new directory “user” and a file “list.htm” in it. and put below html table code ::

<table width="600" cellpadding="5" class="table table-hover table-bordered">
    <thead>
    <tr>
        <th scope="col">Name</th>
        <th scope="col">Email</th>
        <th scope="col">Mobile</th>
        <th scope="col">Address</th>
        <th scope="col">Action</th>
    </tr>
    </thead>

    <tbody>
    <repeat group="{{ @users }}" value="{{ @user }}">
        <tr>
            <td>{{ trim(@user.name) }}</td>
            <td>{{ trim(@user.email) }}</td>
            <td>{{ trim(@user.mobile) }}</td>
            <td>{{ trim(@user.address) }}</td>
            <td><a href="{{ @BASE.'/user/update/'. @user.id }}" class="btn btn-primary"><i class="icon-edit icon-white"></i> Edit</a>
                  <a href="{{ @BASE.'/user/delete/'. @user.id }}" class="btn btn-danger"><i class="icon-remove icon-white"></i>
                    Delete</a></td>

        </tr>
    </repeat>
    </tbody>

</table>

Open “layout.htm” from “f3-crud -> app -> views” and include the “view” between header and footer include, so changed our “layout.htm” will contain below code ::

Now need to add our custom “config.ini” and “routes.ini” in F3. just open “index.php” file from “f3-crud” and add below two lines between preview two line ::

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

So this “index.php” will contain four lines code like below::

$f3=require('lib/base.php');
$f3->config('config/config.ini');
$f3->config('config/routes.ini');
$f3->run();

So now if we access our application “http://localhost/f3-crud/ ” we will get output like below::
fat free framework

Wow this is our first output.

Now we want to add out page head string and a manu. Open “header.htm” from “f3-crud -> app -> views” and add below lines next to container div.

            <div class="jumbotron">
                <h1>{{ @page_head }}</h1>
            </div>

            <include href="user/nav.htm" />

So our “header.htm” file will look like below::

<!DOCTYPE html>
<html lang="en">
    <head>
		<base href="{{ @BASE.'/'.@UI }}" />
        <title>{{ @site }}</title>
        <!-- Bootstrap -->
        <link href="../../ui/css/bootstrap.min.css" rel="stylesheet" media="screen">
        <link href="../../ui/css/crud.css" rel="stylesheet" media="screen">
    </head>

    <body>

        <div class="container">

			<div class="jumbotron">
                <h1>{{ @page_head }}</h1>
            </div>

            <include href="user/nav.htm" />

Create a new template file “nav.htm” in “f3-crud -> app -> views -> user” and put below code into it::

<div class="navbar">
    <div class="navbar-inner">
        <ul class="nav">

            <li <check if="{{ @page_head == 'User List' }}">class="active"</check>><a href="{{ @BASE.'/' }}"><i class="icon-th icon-black"></i> Read</a></li>
            <li <check if="{{ @page_head == 'Create User' }}">class="active"</check>><a href="{{ @BASE.'/user/create' }}"><i class="icon-plus-sign icon-black"></i> Create</a></li>

            <check if="{{ @page_head == 'Update User' }}">
            <li class="active"><a href="javascript:void(0);"><i class="icon-plus-sign icon-black"></i> Update</a></li>
            </check>
        </ul>
    </div>
</div>

Access the application we can see a nice page Head and Menu.

Create new user:: add a new router in router.ini like below::

GET|POST /user/create=UserController->create

We taking here two type of request GET and POST, GET request will use for get the create user FORM and POST request will use for save new user.

Open “UserController.php” and add below method in this the class::

public function create()
{
    if($this->f3->exists('POST.create'))
    {
        $user = new User($this->db);
        $user->add();

        $this->f3->reroute('/');

    } else
    {
        $this->f3->set('page_head','Create User');
        $this->f3->set('view','user/create.htm');
    }
}

In this method we are checking if POST request has “create” field then we are calling “add” method of model class “User” and it will take all POST value from F3’s POST variable and save it to mysql table “users” then redirect it to home page.
Otherwise it will just render a FORM.

Create a new template file “create.htm” in “f3-crud -> app -> views -> user” and put below FORM code into it::

<form action="{{ @BASE.'/user/create' }}" method="post" class="form-horizontal">

    <div class="input-prepend">
        <span class="add-on"><i class="icon-user icon-black"></i> Name</span>
        <input type="text" id="name" name="name" value="" class="input-xlarge" />
    </div>
    <br/><br/>

    <div class="input-prepend">
        <span class="add-on"><i class="icon-envelope icon-black"></i> Email</span>
        <input type="text" id="email" name="email" value="" class="input-xlarge" />
    </div>
    <br/><br/>

    <div class="input-prepend">
        <span class="add-on"><i class="icon-headphones icon-black"></i> Mobile</span>
        <input type="text" id="mobile" name="mobile" value="" class="input-xlarge" />
    </div><br/><br/>

    <div class="input-prepend">
        <span class="add-on add-on-area "><i class="icon-home icon-black"></i> Address</span>
        <textarea row="5" id="address" name="address" class="input-xlarge"></textarea>
    </div><br/><br/>

    <div class="control-group">
        <div class="">
            <input type="hidden" name="create" value="create" />
            <button type="submit" class="btn btn-primary"><i class="icon-ok icon-white"></i> Add User</button>
        </div>
    </div>

</form>

If you click “Create” button from menu then you will get a FORM like below::
fat free framework

Create users as you wish. 🙂

Update User:: like create user, now we have to a routing first, so open “routes.ini” and add below routing::

GET /user/update/@id=UserController->update
POST /user/update=UserController->update

First one is for get the update FORM of selected user and second one is for save the changes data.

Open “UserController.php” and add below method “update” in this the class::

public function update()
{
    $user = new User($this->db);

    if($this->f3->exists('POST.update'))
    {
        $user->edit($this->f3->get('POST.id'));
        $this->f3->reroute('/');

    } else
    {
        $user->getById($this->f3->get('PARAMS.id'));
        $this->f3->set('user',$user);
        $this->f3->set('page_head','Update User');
        $this->f3->set('view','user/update.htm');
    }
}

If the request is for update then it will updated the selected user otherwise it will render the update FORM.

Create a new template file “update.htm” in “f3-crud -> app -> views -> user” for render update FORM.
Put below FORM code into this file::

<form action="{{ @BASE.'/user/update' }}" method="post" class="form-horizontal">

    <div class="input-prepend">
        <span class="add-on"><i class="icon-user icon-black"></i> Name</span>
        <input type="text" id="name" name="name" value="{{ @POST.name }}" class="input-xlarge" />
    </div><br/><br/>

    <div class="input-prepend">
        <span class="add-on"><i class="icon-envelope icon-black"></i> Email</span>
        <input type="text" id="email" name="email" value="{{ @POST.email }}" class="input-xlarge" />
    </div>
    <br/><br/>

    <div class="input-prepend">
        <span class="add-on"><i class="icon-headphones icon-black"></i> Mobile</span>
        <input type="text" id="mobile" name="mobile" value="{{ @POST.mobile }}" class="input-xlarge" />
    </div><br/><br/>

    <div class="input-prepend">
        <span class="add-on add-on-area "><i class="icon-home icon-black"></i> Address</span>
        <textarea row="5" id="address" name="address" class="input-xlarge">{{ @POST.address }}</textarea>
    </div><br/><br/>

    <div class="control-group">
        <div class="">
            <input type="hidden" name="id" value="{{ @POST.id }}" />
            <input type="hidden" name="update" value="update" />
            <button type="submit" class="btn btn-primary"><i class="icon-edit icon-white"></i> Update</button>
        </div>
    </div>

</form>

So if you click “Edit” button from “User list” page you will get a edit form then click “Update” button to save your changes.

Delete User:: the last action. open “routes.ini” file and add below routing::

GET /user/delete/@id=UserController->delete

Open “UserController.php” and add below method “delete” in this the class::

public function delete()
{
    if($this->f3->exists('PARAMS.id'))
    {
        $user = new User($this->db);
        $user->delete($this->f3->get('PARAMS.id'));
    }

    $this->f3->reroute('/');
}

If the request is for delete and has an “id” then it will delete user with given user’s “id”.

That’s all we have did all four action “create”, “read”, “Update” and “delete” using MVC design pattern and f3‘s data mapper.

Demo:: , you can see a live demo here.

Download Source:: , download source code from github of this example. You will get sql dump at “f3-crud -> db” directory.

I am a student of Web Application Development courses at Google University.

10 comments on “CRUD with Fat Free Framework
    • Yes, To follow MVC design pattern i did some extra work. Otherwise it can be done within few lines.

      Also F3 does not has auto generator that we an do any crud by few clicks.
      Thanks for comment.

  1. Hi
    I downloaded your project from github and changed in the config.ini to our database.
    Localhost runs correctly and displays a list of records, but when I press the CREATE displayed 404:

    Not Found
    The requested URL / user / create was not found on this server.
    Apache/2.2.22 (Ubuntu) Server at localhost Port 80

    Do you know what might be the cause of this error?

    • Please check your “routes.ini” that it has proper routing for create event
      “GET|POST /user/create=UserController->create”
      And controller “UserController” has “create” function.
      And in dir “app/views/user” has template file “create.htm”.

      you can set “DEBUG=2” at “config.ini” to see error message well.
      Thanks.

  2. Nice and easy to understand tutorial – just right for a beginner to learn MVC and use jquery/json.
    Thank you!
    Although I had a small problem running the downloaded version on my localhost (windows, apache, magic_quotes_gpc = off): “create” worked, “read” didn’t. When I disabled the magic_quote-function in the controller, ist was the other way round.
    So there still seems to be a problem with this function. I easily solved it with an “if ($_POST[‘action’] != ‘get_users’) { ….”.
    It seems, the May 11th was not enough! 🙂

  3. Hello Foysal Mamun. Good Morning(as per IST).

    Yesterday, I have downloaded F3 framework and started developing your F3-CRUD app. All went well but, suddenly when I try to run the app in my localhost, it started showing me an Error called “Internal Server Error” & also “Unable to open list.htm” But I have written code in list.htm & placed in right dir only. Can you help me to solve this issue please?

    Thanks,

    Regards,

    L CH RAJKUMAR

Leave a Reply to L CH RAJKUMAR Cancel reply

Your email address will not be published. Required fields are marked *