Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and Restful APIs.
Webpage http://www.slimframework.com/
There are two ways:
1. Manual installation
index.php
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
$app->get('/hello/:name', function ($name) {
echo "Hello, $name";
});
$app->run();
2. Composer installation
index.php
require 'vendor/autoload.php';
$app = new \Slim\Slim();
$app->get('/hello/:name', function ($name) {
echo "Hello, $name";
});
$app->run();
...That's it!
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
Don’t forget!
GET
$app->get('/books/:id', function ($id) {
//Show book identified by $id
});
POST
$app->post('/books', function () {
//Create book
});
PUT
$app->put('/books/:id', function ($id) {
//Update book identified by $id
});
DELETE
$app->get('/books/:id', function ($id) {
//Show book identified by $id
});
Method Override
Unfortunately, modern browsers do not provide native support for HTTP PUT and DELETE requests. To work around this limitation, ensure your HTML form’s method attribute is "post", then add a method override parameter to your HTML form like this:
<form action="/books/1" method="post">
... other form fields here...
<input type="hidden" name="_METHOD" value="PUT"/>
<input type="submit" value="Update Book"/>
</form>
$app->get('/books/:one/:two', function ($one, $two) {
echo "The first paramter is " . $one;
echo "The second parameter is " . $two;
});
$app->get('/archive(/:year(/:month(/:day)))', function ($year = 2010, $month = 12, $day = 05) {
echo sprintf('%s-%s-%s', $year, $month, $day);
});
That was the routing but Slim has much more...
Composer is a Dependency Manager for PHP
Composer is very easy to install:
Go to http://getcomposer.org and download the installer
Or
Run this in your terminal
curl -s https://getcomposer.org/installer | php
Into the Root of your project create the file:
composer.json
{
"require": {
"slim/slim": "2.*"
}
}
To get the dependencies
run in the terminal
composer install
To Update the dependencies
run in the terminal
composer update
It is the main Composer repository
There you can browse and search for packages.
Composer generates a vendor/autoload.php file
You can simply include this file and you will get autoloading
require 'vendor/autoload.php';
You can even add your own code to the autoloader by adding an autoload field to composer.json.
{
"autoload": {
}
}
There are two ways to autoload your classes:
Here you define a mapping from namespaces to paths, relative to the package root
{
"autoload": {
"psr-0": {
"Monolog": "src/",
"Vendor\\Namespace\\": "src/",
"Vendor_Namespace_": "src/"
}
}
}
This is the recommended way though since it offers greater flexibility
After adding the autoload field, you have to re-run:
composer install
You can use the classmap generation support to define autoloading for all libraries that do not follow PSR-0
{
"autoload": {
"classmap": ["src/", "lib/", "Something.php"]
}
}
After adding a new class or file, you have to run:
composer update
You can use Composer to create new projects from an existing package.
This is the equivalent of doing a git clone/svn checkout followed by a composer install of the vendors.
composer create-project slim/slim-skeleton [my-app-name]
Installing Slim with Composer in Fortrabbit Server
Laravel comes with several tools to use with databases:
Provides methods for creating and modifying your database tables.
Create tables
Schema::table('users', function($table)
{
$table->create();
$table->increments('id');
$table->string('username');
$table->string('email');
$table->string('phone')->nullable();
$table->text('about');
$table->timestamps();
});
Methods allow you to add columns
$table->increments('id'); //Incrementing ID to the table
$table->string('email'); //VARCHAR equivalent column
$table->string('name', 100); //VARCHAR equivalent with a length
$table->integer('votes'); //INTEGER equivalent to the table
$table->float('amount'); //FLOAT equivalent to the table
$table->decimal('amount', 5, 2); //DECIMAL with a precision and scale
$table->boolean('confirmed'); //BOOLEAN equivalent to the table
$table->date('created_at'); //DATE equivalent to the table
$table->timestamp('added_on'); //TIMESTAMP equivalent to the table
$table->timestamps(); //Adds created_at and updated_at columns
$table->text('description'); //TEXT equivalent to the table
$table->blob('data'); //BLOB equivalent to the table
->nullable() //Designate that the column allows NULL values
->default($value) //Declare a default value for a column
->unsigned() //Set INTEGER to UNSIGNED
Defining indexes
$table->primary('id'); //Adding a primary key
$table->primary(array('fname', 'lname')); //Adding composite keys
$table->unique('email'); //Adding a unique index
$table->fulltext('description'); //Adding a full-text index
$table->index('state'); //Adding a basic index
The Fluent Query Builder is Laravel's powerful fluent interface for building SQL queries and working with your database.
All queries use prepared statements and are protected against SQL injection.
You can begin a fluent query using the table method on the DB class. Just mention the table you wish to query
$query = DB::table('users');
Retrieving records
$users = DB::table('users')->get();
$user = DB::table('users')->first();
$user = DB::table('users')->find($id);
$email = DB::table('users')->where('id', '=', 1)->only('email');
$user = DB::table('users')->get(array('id', 'email as user_email'));
$user = DB::table('users')->distinct()->get();
Building Where Clauses
return DB::table('users')
->where('id', '=', 1)
->or_where('email', '=', 'example@gmail.com')
->first();
DB::table('users')->where_in('id', array(1, 2, 3))->get();
DB::table('users')->where_not_in('id', array(1, 2, 3))->get();
$users = DB::table('users')
->where('id', '=', 1)
->or_where(function($query)
{
$query->where('age', '>', 25);
$query->where('votes', '>', 100);
})
->get();
Table Joins
DB::table('users')
->join('phone', 'users.id', '=', 'phone.user_id')
->get(array('users.email', 'phone.number'));
DB::table('users')
->left_join('phone', 'users.id', '=', 'phone.user_id')
->get(array('users.email', 'phone.number'));
Ordering results
return DB::table('users')->order_by('email', 'desc')->get();
return DB::table('users')
->order_by('email', 'desc')
->order_by('name', 'asc')
->get();
Limit and Offset
return DB::table('users')->take(10)->get();
return DB::table('users')->skip(10)->get();
Aggregates
$min = DB::table('users')->min('age');
$max = DB::table('users')->max('weight');
$avg = DB::table('users')->avg('salary');
$sum = DB::table('users')->sum('votes');
$count = DB::table('users')->count();
$count = DB::table('users')->where('id', '>', 10)->count();
Insert - Update - Delete
DB::table('users')->insert(array('email' => 'example@gmail.com'));
$affected = DB::table('users')->update(array('email' => 'new_email@gmail.com'));
$affected = DB::table('users')->where('id', '=', 1)->delete();
Eloquent is an ORM (Object-relational mapper) very easy to use
Define a simple model
class User extends Eloquent {}
Conventions
But you can change it...
class User extends Eloquent {
protected $table = 'my_users';
protected $key = 'id_user';
}
Retrieving Models
Of course every method that is available through the Fluent Query Builder is available in Eloquent
$user = User::where('email', '=', $email)->first();
$user = User::where_email($email)->first();
$users = User::where_in('id', array(1, 2, 3))->or_where('email', '=', $email)->get();
$users = User::order_by('votes', 'desc')->take(10)->get();
Aggregates
Of course every method that is available through the Fluent Query Builder is available in Eloquent
$min = User::min('id');
$max = User::max('id');
$avg = User::avg('id');
$sum = User::sum('id');
$count = User::count();
$count = User::where('id', '>', 10)->count();
Inserting and Updating Models
Of course every method that is available through the Fluent Query Builder is available in Eloquent
$user = new User; //Insert
$user = User::find(1); // Or getting first for Update
$user->email = 'example@gmail.com';
$user->password = 'secret';
$user->save();
Another way to insert a new record
$user = User::create(array('email' => 'example@gmail.com'));
created_at and updated_at
Whenver you save the model, the creation an update timestamps will be set automatically
class User extends Eloquent {
public $timestamps = true;
}
You can update the update_at without saving the model
$comment = Comment::find(1);
$comment->touch();
Or
$comment = Comment::find(1);
$comment->timestamp();
//do something else here, but not modifying the $comment model data
$comment->save();
Relationships
Relation One-To-One
class User extends Eloquent {
public function phone()
{
return $this->has_one('Phone');
}
}
Now execute
$phone = User::find(1)->phone()->first();
Two queries will be performed
SELECT * FROM "users" WHERE "id" = 1
SELECT * FROM "phones" WHERE "user_id" = 1
Relation One-To-Many
class Post extends Eloquent {
public function comments()
{
return $this->has_many('Comment');
}
}
Now execute
$comments = Post::find(1)->comments()->get();
$comments = Post::find(1)->comments;
Two queries will be performed
SELECT * FROM "posts" WHERE "id" = 1
SELECT * FROM "comments" WHERE "post_id" = 1
Relation Many-To-Many
This is the most complicated, for the example create 3 tables
usersid - INTEGER
email - VARCHAR
roles
id - INTEGER
name - VARCHAR
role_user
id - INTEGER
user_id - INTEGER
role_id - INTEGER
Relation Many-To-Many
class User extends Eloquent {
public function roles()
{
return $this->has_many_and_belongs_to('Role');
}
}
Now execute
$roles = User::find(1)->roles()->get();
Or
$roles = User::find(1)->roles;
Twig is the flexible, fast and secure template language for PHP
Created by Fabien Potencier (Symfony)
Example .html using Twig
<!DOCTYPE html>
<html>
<head>
<title>My Webpage</title>
</head>
<body>
<ul id="navigation">
{% for item in navigation %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
<h1>My Webpage</h1>
{{ a_variable }}
</body>
</html>
Variables
{{ foo.bar }}
{{ foo['bar'] }}
setting variables
{% set foo = 'foo' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}
Filters
The following example removes all HTML tags{{ name|striptags|title }}
Example joining a list by commas
{{ list|join(', ') }}
Applying a list on a section of code
{% filter upper %}
This text becomes uppercase
{% endfilter %}
Functions and Control structure
{% for i in range(low=1, high=10, step=2) %}
{{ i }},
{% endfor %}
To display a list
<h1>Members</h1>
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
If structure control
{% if users|length > 0 %}
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
{% endif %}
Comments
{# note: disabled template because we no longer use this
{% for user in users %}
...
{% endfor %}
#}
Encoding and working with Dates
Encoding{{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
{# versus #}
{{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }}
Formating Dates with Timezones
{# both work #}
{{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}
{{ "now"|date(timezone="Europe/Paris", 'd/m/Y H:i') }}
Template Inheritance
We can create a base "skeleton" template with all common elements<!DOCTYPE html>
<html>
<head>
{% block head %}
<link rel="stylesheet" href="style.css" />
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2011 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
</html>
Template Inheritance
We can create a base "skeleton" template with all common elements{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ parent() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome to my awesome homepage.
</p>
{% endblock %}
Macros
Useful to reuse often used HTML fragments to not repeat yourself{% macro input(name, value = "", type = "text", size = 20) %}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" />
{% endmacro %}
Import the macro
{% import "forms.html" as forms %}
<p>{{ forms.input('username') }}</p>
Program to see the score of Bootsoft teams
Two tables in MySQL
usersid - INTEGER
name - VARCHAR
avatar - VARCHAR
team - VARCHAR
scores
id - INTEGER
round - INTEGER
points - INTEGER
user_id - INTEGER
We create the composer file in the root
{
"name": "Bowling",
"require": {
"php": ">=5.3.0",
"slim/slim": "2.*",
"slim/extras": "2.*",
"twig/twig": "1.*",
"dhorrigan/capsule": "*"
}
}
In the console execute:
composer install
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
index.php
require 'vendor/autoload.php';
$app = new \Slim\Slim();
$app->get('/', function () {
echo "Hello Bowling!!";
});
$app->run();
class User extends Illuminate\Database\Eloquent\Model {
protected $table = "Users";
public $timestamps = false;
public function scores() {
return $this->hasMany('Score');
}
}
models/Score.php
class Score extends Illuminate\Database\Eloquent\Model {
protected $table = "Scores";
public $timestamps = false;
}
To autoload the models we have to add it to composer.json
{
"name": "Bowling",
"require": {
"php": ">=5.3.0",
"slim/slim": "2.*",
"slim/extras": "2.*",
"twig/twig": "1.*",
"dhorrigan/capsule": "*"
},
"autoload": {
"classmap": [
"models"
]
}
}
In the console execute:
composer update
In the index.php add this code
// Make a new connection
$app->db = Capsule\Database\Connection::make('default', array(
'driver' => 'mysql',
'host' => 'localhost',
'port' => 3306,
'database' => 'bowling',
'username' => 'root',
'password' => '',
'prefix' => '',
'charset' => "utf8",
'collation' => 'utf8_general_ci'
), true);
Off the record: I generate the Score rows randomly with this code
$app->get('/generate', function () {
$users = User::all();
foreach ($users as $user) {
for ($i = 1; $i<=10; $i++) {
$oScore = new Score();
$oScore->round = $i;
$oScore->points = rand(0,10);
$oScore->user_id = $user->id;
$oScore->save();
}
}
echo "generated";
});
$app->get('/users', function () {
$users = User::all();
echo $users->toJson();
});
/team/:team
$app->get('/team/:team', function ($team) {
$users = User::where('team', '=', $team)->get();
echo $users->toJson();
});
/user/:id
$app->get('/user/:id', function ($id) use ($app) {
$user = User::with('scores')->where('id', '=', $id)->get();
echo $user->toJson();
echo Score::where('user_id', '=', $id)->sum('points');
});
Now lets setup Twig in Slim
In the index change$app = new \Slim\Slim();
By
// Setup custom Twig view
$twigView = new \Slim\Extras\Views\Twig();
$app = new \Slim\Slim(array(
'debug' => true,
'view' => $twigView,
'templates.path' => 'templates/',
));
We are going to get Zurb foundation (CSS Framework) using compass
Execute in the consolecompass create public -r zurb-foundation --using foundation
create base.html in templates
<!-- Nav Bar -->
<div class="row">
<div class="large-12 columns">
<div class="nav-bar right">
<ul class="button-group">
<li><a href="/team/TEAM_1" class="button">Team 1</a></li>
<li><a href="/team/TEAM_2" class="button">Team 2</a></li>
<li><a href="/team/TEAM_3" class="button">Team 3</a></li>
<li><a href="/team/TEAM_4" class="button">Team 4</a></li>
</ul>
</div>
<h1><a href="/">Bootsoft Bowling</a></h1>
<hr />
</div>
</div>
<!-- End Nav -->
{% block content %}{% endblock %}
create players.html in templates
{% extends "base.html" %}
{% block content %}
{% for user in users %}
<div class="row">
<div class="small-4 large-2 columns">
<img src="http://s3.amazonaws.com/37assets/svn/765-default-avatar.png" width="60"/>
</div>
<div class="small-4 large-6 columns">
<h2>{{ user.name|e }}</h2>
</div>
<div class="small-4 large-2 columns">
<h3>{{ user.score }}</h3>
</div>
</div>
{% endfor %}
{% endblock %}
Now at index.php change the code to
$app->get('/', function () use ($app) {
$users = User::all();
foreach ($users as $user) {
$user->score = Score::where('user_id', '=', $user->id)->sum('points');
}
$app->render('players.html', array('users' => $users));
});
Get the Bootsoft Bowling example
Official Website
PHP the Rigth Way
http://www.phptherightway.com/
Keeping it Small (Jeremy Kendall)
Slim + Composer + Eloquent ORM (Phil Sturgeon)
Official Website
Laravel Framework
Laravel Eloquent ORM
Official Website