Light weight and Easy Use PHP MVC framework
we support
- REST API
- ActiveRecord like ORM
- Protect from forgery
- Auth
- I18n
- helper
- Pure PHP Template engine
require
- php > 5.1
- ruby > 1.9 ( for sass, coffeescript)
- Getting Started
- Model
- Routing
- Controller
- Protect from forgery
- Auth
- View
- Pure PHP Template Engine
- Helper
- I18n
create blog application
create 'blog' Database.
create 'posts' table.
column name | type | --- | --- | --- id | integer | auto increment name | string | body | text |
Humper Model is ActiveRecord like object-relational-mapper(ORM).
create post model.
class Post extends HumperModel {
protected $model_name = 'Post';
protected $schema_name = 'blog';
protected $attributes = array(
'name',
'body',
);
/**
* always add these method
*
* - find: record find by id
* - findAll: select all record
* - findAll: select record query with where with limit = 1
* - where: select record query with where
*/
public static function where($args, $values = array(), $select = array()) {
$obj = new self; return $obj->insWhere($args, $values, $select);
}
public static function findBy($args, $select = array()){
$obj = new self; return $obj->insFindBy($args, $select);
}
public static function find($id){
$obj = new self; return $obj->insFindBy(array(':id' => $id));
}
public static function findAll(){
$obj = new self; return $obj->insFindAll();
}
}
if your created table name is not based on ActiveRecord name rule.
(e.g. PostModel has Posts table)
set $table_name
class Post extends HumperModel {
protected $table_name = 'country';
...
}
select a record by id
$post = Post::find('1');
select all record
$post = Post::findAll();
select a record by name
$post = Post::findBy(array('name' => 'foo'));
# with columns
$post = Post::findBy(array('name' => 'foo'), array('id, name as title'));
select any record by name
# by array
$posts = Post::where(array('name' => 'foo'));
# by array with columns
$posts = Post::where(array('name' => 'foo'), array(), array('id, name as title'));
# by string array
$posts = Post::where('name like ?', array('%foo%'));
# with select column
$posts = Post::where('name like ?', array('%foo%'), array('id, name as title'));
insert
$post = new Post;
$post->name = 'foo';
$post->body = 'bar';
$post->save();
update
$post = Post::findBy(array(':name' => 'foo'));
$post->body = 'barbar';
$post->save();
delete
$post = Post::findBy(array(':name' => 'foo'));
$post->destroy();
we support REST API.
- HTTP Get, Post, Put , Delete method
- Unique URL Routing
class BlogApplication extends HumperApplication {
...
protected function registerRoutes() {
return array(
# show post list
'GET;/posts'
=> array('controller' => 'posts', 'action' => 'index'),
# show add post form
'GET;/posts/add'
=> array('controller' => 'posts', 'action' => 'add'),
# show post target id
'GET;/posts/:id'
=> array('controller' => 'posts', 'action' => 'show'),
# edit already post form
'GET;/posts/:id/edit'
=> array('controller' => 'posts', 'action' => 'edit'),
# create new post via 'GET;/posts/add'
'POST;/posts/:id'
=> array('controller' => 'posts', 'action' => 'create'),
# update post via 'GET;/posts/:id/edit'
'PUT;/posts/:id'
=> array('controller' => 'posts', 'action' => 'update'),
# delete post
'DELETE;/posts/:id'
=> array('controller' => 'posts', 'action' => 'delete'),
);
}
...
}
create post controller in 'controllers' directory.
class PostsController extends ApplicationController {
protected $auth_actions = array('');
protected $protect_from_forgery_actions = array('');
/**
* index
*/
function index() {
$posts = Post::findAll();
return $this->render(array(
'posts' => $posts,
));
}
/**
* show
*/
function show() {
$post = Post::find($this->params['id']);
return $this->render(array(
'post' => $post,
));
}
/**
* add
*/
function add() {
return $this->render();
}
/**
* edit
*/
function edit() {
$post = Post::find($this->params['id']);
return $this->render(array(
'post' => $post,
));
}
/**
* create
*/
function create() {
$post = new Post();
$post->name = $this->request->getPost('name', null);
$post->post = $this->request->getPost('body', null);
if( $post->create() ) {
return $this->redirect('/posts/'.$post->id);
} else {
return $this->redirect('/posts/'.$post->id);
}
}
/**
* update
*/
function update() {
$post = Post::find($this->params['id']);
$post->member_id = $this->request->getPost('member_id', null);
$post->post = $this->request->getPost('post', null);
if( $post->update() ) {
return $this->redirect('/posts/'.$post->id);
} else {
# get PDO exception
return $this->redirect('/posts/'.$post->id);
}
}
/**
* delete
*/
function delete() {
$post = Post::find($this->params['id']);
if( $post->destroy() ) {
return $this->redirect('/posts');
} else {
# get PDO exception
return $this->redirect('/posts');
}
}
}
and you can set beforeFilter/afterFilter.
these method call target method before/after.
class PostsController extends ApplicationController {
function beforeFilter() {
parent::beforeFilter();
}
function afterFilter() {
parent::beforeFilter();
}
}
get url parameter
# access via /posts/5 as /posts/:id
$this->params['id']; // = 5
get $_GET, $_POST, $_SERVER paramter
# $_GET
$this->request->getGet('key', default);
# $_POST
$this->request->getPost('key', default);
# $_SERVER
$this->request->getServer('key', default);
render template
# default
# * temaplte_name: method name
# * layout_name: layout
$this->render(variables_array, template_name, layout_name);
redirect
$this->redirect('url');
set key for generate CSRF token
class BlogApplication extends HumperApplication {
protected function configure() {
...
$this->security_component->setSecretKeyBase('xxxxxxxxxxxxxxxxxxxx....');
...
}
}
set action to controller's $protect_from_forgery_actions
// set selected action
class PostsController extends ApplicationController {
protected $protect_from_forgery_actions = array('create', 'delete', 'update');
}
// if you want set all action
class PostsController extends ApplicationController {
protected $protect_from_forgery_actions = true;
}
set auth back
class BlogApplication extends HumperApplication {
protected function configure() {
...
$this->auth_component->setRootDir('/');
...
}
}
set action to controller's $protect_from_forgery_actions
// set selected action
class PostsController extends ApplicationController {
protected $auth_actions = array('add', 'edit', 'create', 'delete', 'update');
}
// if you want set all action
class PostsController extends ApplicationController {
protected $protect_from_forgery_actions = true;
}
# authed flag
$this->setAuthenticated(true);
# get auth
$this->isAuthenticated();
if you want i18n and translate by your dictionary
set default language
class BlogApplication extends HumperApplication {
protected function configure() {
...
$this->i18n_component->setDefaultLanguage('ja');
...
}
}
create disctionay file config/locale/ja.yml
ja:
models:
post: ポスト
posts:
name: 名前
body: 内容
add: 追加
show: 表示
update: 更新
edit: 編集
delete: 削除
change language use before filter
class ApplicationController extends HumperController {
function beforeFilter() {
parent::beforeFilter();
if (isset($this->params['lang'])) {
$this->i18n_component->setLanguage($this->params['lang']);
}
}
}
view helper method use in templates. and you can difine any helpers
e.g.
/helpers/posts_helper.php
link/form generate
# get post link
link_to($post->name, '/posts/'$post->id)
# post delete link
link_to($this->t('delete'), '/posts/'.$post->id, 'delete', $_token)
html escape
h() or $this->h()
translate (i18n)
$this->t($key);
default layout is views/layouts/layout.php
<html>
<head>
<title><?php if (isset($title)): echo h($title) . ' - '; endif; ?>Blog</title>
</head>
<body>
<?php echo $_content; ?>
</body>
</html>
$_content
is any template generated html include.
views/posts/index.php
<?php $this->setLayoutVar(array('title', $this->t('models.post'))) ?>
<h1>posts</h1>
<table>
<tr>
<th>id</th>
<th><?= $this->t('id') ?></th>
<th><?= $this->t('models.posts.name') ?></th>
<th><?= $this->t('models.posts.body') ?></th>
<th></th>
<th></th>
<th></th>
</tr>
<?php foreach( $posts as $key => $post ) { ?>
<tr>
<td><?= h($post->id) ?></td>
<td><?= h($post->name) ?></td>
<td><?= h($post->body) ?></td>
<td><?= link_to($this->t('show'), '/posts/$post->id') ?></td>
<td><?= link_to($this->t('edit'), '/posts/$post->id/edit') ?></td>
<td><?= link_to($this->t('delete'), '/posts/$post->id',
array( 'method' => 'delete', 'token' => $_token)) ?></td>
</tr>
<?php } ?>
</table>
<?= link_to($this->t('add'), '/posts/add') ?>
<?php $this->setLayoutVar(array('title' => $this->t('edit'))) ?>
<h1>posts/edit</h1>
<form action='/posts/<?= $post->id ?>' method='post'>
<input type='hidden' name='_token' value="<?= $_token ?>">
<input type='hidden' name='_method' value="put">
<?= $this->t('models.posts.name') ?>:
<input type='text' name='name' value="<?= $post->name ?>">
<?= $this->t('models.posts.body') ?>:
<input type='text' name='body' value="<?= $post->body ?>">
<input type='submit' value='<?= $this->t('update') ?> '>
</form>
<?= link_to($this->t('back'), '/posts') ?>
set layout use variables
$this->setLayoutVar(array('title' => 'list'))
csrf token
$_token
- implement Haml Tempalte Engine
- PHPUnit of controller