26. Applications developed
with Symfony.
http://trac.symfony-project.org/wiki/
ApplicationsDevelopedWithSymfony
1000+ websites listed.
Monday, January 14, 13
53. 現代 PHP 解決⽅方案
The Modern PHP Solution
Monday, January 14, 13
54. Modern Tools
• PSR
• Composer / Onion / PEAR / Pyrus
• phpbrew / phpenv / phpbuild
• ClassLoader via spl_autoload_* functions
• New language features (traits, spl,
generator...)
Monday, January 14, 13
127. Each component should
have a package state
- API stability
-Package stability
Monday, January 14, 13
128. Component A
The core is pretty small,
we don’t need to change Framework Component B
core API frequently
Component C
Monday, January 14, 13
129. Component A 2.0
API Lock
Stable
Framework Component B
API Lock
Stable
API Lock
Beta Stability
Component C
API Beta
Beta Stability
Monday, January 14, 13
130. We can build another new
framework very easily.
Component A 2.0
API Lock
Stable
Framework B
New Concept
Framework Component B
API Lock
Stable
API Lock
Beta Stability
Component C
API Beta
Beta Stability
Monday, January 14, 13
131. How do we build CLI
applications?
Monday, January 14, 13
132. CLIFramework
https://github.com/c9s/CLIFramework
Monday, January 14, 13
134. CLIFramework
⽀支持⼦子命令及⼦子命令選項
Monday, January 14, 13
135. CLIFramework
<?php
namespace TestAppCommand;
use CLIFrameworkCommand;
class ListCommand extends Command
{
function execute($arg1,$arg2)
{
// .. do something here...
}
}
Monday, January 14, 13
136. CLIFramework
<?php
namespace YourApp;
use CLIFrameworkApplication;
class CLIApplication extends Application
{
/* init your application options here */
function options($opts)
{
$opts->add('v|verbose', 'verbose message');
$opts->add('path:', 'required option with a value.');
$opts->add('path?', 'optional option with a value');
$opts->add('path+', 'multiple value option.');
}
/* register your command here */
function init()
{
$this->registerCommand( 'list', 'YourAppCommandListCommand' );
$this->registerCommand( 'foo', 'YourAppCommandFooCommand' );
}
}
Monday, January 14, 13
137. CLIFramework
<?php
$app = new TestAppApplication;
$app->run($argv);
Monday, January 14, 13
138. CLIFramework
⾃自動產⽣生的 Command-line help
Monday, January 14, 13
139. How do we generate
forms?
Monday, January 14, 13
140. FormKit
https://github.com/c9s/FormKit
Monday, January 14, 13
141. FormKit
• A powerful form widget generator.
• Simple API for defining widgets and layout.
• Customizable layout engine.
Monday, January 14, 13
142. FormKit: TextInput
<?php
$text = new FormKitWidgetTextInput('username', array(
'label' => 'Username',
'placeholder' => 'Your name please',
'hint' => 'Please enter 6 characters for your username',
));
$text->value( 'default' )
->size(20);
echo $text; // render
Monday, January 14, 13
147. For more details
http://github.com/c9s/FormKit
Monday, January 14, 13
148. How do we define
logics for forms?
Monday, January 14, 13
149. ActionKit
https://github.com/c9s/ActionKit
Monday, January 14, 13
150. ActionKit
• Let you define logics and form field
definitions.
• Use FormKit to render form fields
automatically.
Monday, January 14, 13
151. If I have a login form
and login logics
Monday, January 14, 13
152. <?php
namespace UserAction;
use ActionKit;
class Login extends ActionKitAction
{
public function scheme()
{
$this->param("account")
->renderAs("TextInput");
$this->param("password") Define your form fields.
->renderAs("PasswordInput");
$this->param("remember_me");
}
}
Monday, January 14, 13
153. <?php
namespace UserAction;
use ActionKit;
class Login extends ActionKitAction
{
public function scheme()
{
$this->param("account")
->renderAs("TextInput");
$this->param("password")
->renderAs("PasswordInput");
$this->param("remember_me");
}
public function run()
{
$account = $this->arg('account');
$password = $this->arg('password'); Define your logics here.
/* your login logics here */
return $this->success('Login successfully');
}
}
Monday, January 14, 13
154. ActionKit: The API
<?php
$action = new UserActionLogin;
echo $action->createView()->render();
// customized action layout.
echo $action->createView("CustomziedLayoutClass")->render();
Render the form.
Monday, January 14, 13
155. ActionKit: The API
<?php
$runner = ActionKitActionRunner::getInstance();
$runner->registerAutoloader();
$result = $runner->run("UserActionLogin");
if( $result && $runner->isAjax() ) {
// JSON
header('Content-Type: application/json; Charset=utf-8');
echo $result->__toString();
exit(0);
}
Handle the logics and return the result.
Monday, January 14, 13
156. How do we dispatch
URL?
Monday, January 14, 13
157. Roller Router
https://github.com/c9s/Roller
Monday, January 14, 13
158. Roller Router
• A fast router for PHP.
Monday, January 14, 13
159. Roller Router
• A fast router for PHP.
• Designed for performance.
Monday, January 14, 13
160. Roller Router
• A fast router for PHP.
• Designed for performance.
• Let you define plugins, routes easily.
Monday, January 14, 13
161. Roller Router
• A fast router for PHP.
• Designed for performance.
• Let you define plugins, routes easily.
• APC / File Cache.
Monday, January 14, 13
162. Roller Router
• A fast router for PHP.
• Designed for performance.
• Let you define plugins, routes easily.
• APC / File Cache.
• Annotation Reader support.
Monday, January 14, 13
163. Roller Router
• A fast router for PHP.
• Designed for performance.
• Let you define plugins, routes easily.
• APC / File Cache.
• Annotation Reader support.
• RESTful plugin
Monday, January 14, 13
164. Roller Router
• A fast router for PHP.
• Designed for performance.
• Let you define plugins, routes easily.
• APC / File Cache.
• Annotation Reader support.
• RESTful plugin
• With C Extension support.
Monday, January 14, 13
165. Roller Router
<?php
$router = new RollerRouter( null, array(
'cache_id' => 'router_demo'
));
Monday, January 14, 13
176. <?php
Roller + RESTful
class MyGenericHandler extends RollerPluginRESTfulGenericHandler
{
public function create($resource) {
return array( 'id' => 99 );
}
public function load($resource,$id) {
return array( 'id' => $id );
}
public function update($resource,$id) {
$put = $this->parseInput();
return $put;
}
public function delete($resource,$id) {
$args = $this->parseInput();
// print_r($args);
return array( 'id' => $id );
}
public function find($resource) {
return range(1,10);
}
}
Monday, January 14, 13
177. Mount your RESTful
handler
$restful = new RollerPluginRESTful(array( 'prefix' => '/=' ));
$restful->setGenericHandler( 'MyGenericHandler' );
$router->addPlugin($restful);
GET http://localhost:8888/=/book/1
POST http://localhost:8888/=/book
Monday, January 14, 13
178. For more details
http://github.com/c9s/Roller
Monday, January 14, 13
179. LazyRecord
https://github.com/c9s/Roller
Monday, January 14, 13
202. LazyRecord
• Filter / Canonicalizer support.
• CRUD support via ActionKit.
Monday, January 14, 13
203. LazyRecord
• Filter / Canonicalizer support.
• CRUD support via ActionKit.
• Form generation via ActionKit.
Monday, January 14, 13
204. LazyRecord
• Filter / Canonicalizer support.
• CRUD support via ActionKit.
• Form generation via ActionKit.
• Migration support.
Monday, January 14, 13
205. LazyRecord: Schema
<?php
namespace TodosModel;
use LazyRecordBaseModel;
class Todo extends BaseModel
{
function schema($schema)
{
$schema->column('title')
->varchar(128)
->required()
;
$schema->column('description')
->text();
$schema->column('created_on')
->timestamp()
->default(function() {
return date('c');
});
$schema->seeds('TodosSeed');
}
}
Monday, January 14, 13
206. LazyRecord: Model
<?php
$author = new Author;
$ret = $author->create([
'name' => "Deflator Test $i",
'country' => 'Tokyo',
'confirmed' => true,
'date' => new DateTime('2011-01-01 00:00:00'),
]);
if( $ret->success ) {
echo "Created!";
} ActiveRecord Pattern
Monday, January 14, 13
207. LazyRecord: Collection
<?php
$authors = new AuthorCollection;
foreach( $authors as $author ) {
echo $author->name , "n"
}
Collection Iterating
Monday, January 14, 13
208. LazyRecord: Collection
$authors = new AuthorCollection;
$authors->where()
->equal('name','Foo')
->groupBy('name','address');
SQL Conditions via
SQLBuilder
Monday, January 14, 13
209. LazyRecord: Collection
$newAuthors = $authors->filter(function($item) {
// do something else
})->filter(function($item) {
return $item->confirmed;
});
Monday, January 14, 13
220. LazyRecord
App::Model::Phone
App::Model::PhoneCollection
App::Action::CreatePhone
App::Action::UpdatePhone
App::Action::DeletePhone
... or any other actions predefined.
Monday, January 14, 13
221. LazyRecord
App::Model::Phone
App::Model::PhoneCollection
App::Action::CreatePhone
App::Action::UpdatePhone
App::Action::DeletePhone
... or any other actions predefined.
$phone->asCreateAction()->render();
Monday, January 14, 13