symfony on action - webtech 207
DESCRIPTION
TRANSCRIPT
symfony in action.
WebTech 2007
symfony ?
• PHP 5 Web Framework
• Based on well-known projets (Mojavi, Propel, Prado …)
• Open-Source (MIT licence)
• Sponsored by Sensio ( http://www.sensio.com/ )
cite from symfony book
If you have been looking for a Rails/Django-like framework for PHP projects with features such as:
· simple templating and helpers· cache management· multiple environments support· deployment management· scaffolding· smart URLs· multilingual and I18N support· object model and MVC separation· Ajax support
...where all elements work seamlessly together, then symfony is made for you
don’t reinvent the wheel
• Follow best practices
• MVC Pattern : Model / View / Controller
• Unit and functional test framework
• Environment and deployment support
• Security (XSS protection)
• Extensible (plugin system)
a professional web framework
• Built from experience• 1.0 stable, maintained with commercial
support• Growing community
– Developpers in more than 80 countries– 100 000 visitors per month on symfony-project.com
• Open-Source Documentation– The book (450 pages - GFDL)– Askeet Tutorial (250 pages)
Sounds good ?Let’s try it !
requirements
• PHP5
• Web server (Apache)
• RDBMS (MySQL)
installation
• Sandbox> wget http://www.symfony-project.com/get/sf_sandbox.tgz
• PEAR> pear channel-discover pear.symfony-project.com > pear install symfony/symfony
• Subversion> svn checkout http://svn.symfony-project.com/branches/1.0/
.
init new symfony project
> mkdir WebTechComments> cd WebTechComments
> symfony init-project WebTechComments> symfony init-app frontend
Project
Application(s)
Module(s)
Actions(s)
Composant(s)
Template
web server configuration
<VirtualHost *:80>
ServerName WebTechComments DocumentRoot "/path/to/project/web" DirectoryIndex index.php
Alias /sf /path/to/symfony/data/symfony/web/sf
<Directory "/path/to/project/web"> AllowOverride All </Directory>
</VirtualHost>
demo
Congratulations!
You have successfully created your symfony project.
object-relational mapping
• Tables as classes and records as objects
public function getName() {
return $this->getFirstName.' '.$this->getLastName();}
public function getTotal() {
$total = 0;
foreach ($this->getItems() as $item) { $total += $item->getPrice() * $item->getQuantity(); } return $total;
}
• Object and Peer classes$article = new Article(); ... $title = $article->getTitle();
$articles = ArticlePeer::retrieveByPks(array(123, 124, 125));
PropertyField, column
ObjectRow, record
ClassTable
Object-OrientedRelational
create database schema
#/config/schema.yml propel: sessions: _attributes: { phpName: Session } id: date: timestamp speaker: varchar(255) topic: varchar(255) description: longvarchar comments: _attributes: { phpName: Comment } id: sessions_id: type: integer foreignTable: sessions foreignReference: id onDelete: cascade phpName: SessionId peerName: SESSION_ID author: varchar(255) content: longvarchar created_at:
build model and database
• Configuration– database access– Propel properties
• Build model > symfony propel-build-model
• Build SQL > symfony propel-build-sql
• Create database > symfony propel-insert-sql
• Do them all > symfony propel-build-all
define some test data
• Test data# data/fixtures/data.ymlSession: s1: date: 06/29/2007 speaker: Test Speaker topic: Test Topic description: Just for testingComment: c1: sessions_id: s1 author: Teo Tester content: It’s better when other do the tests
> symfony propel-load-data frontend
scafolding
• Create / Retrieval / Update / Delete (CRUD)
• Initiating or Generating Code
> symfony <TASK_NAME> <APP_NAME> <MODULE_NAME> <CLASS_NAME> tasks: propel-init-crud, propel-generate-crud, and propel-init-admin
> symfony propel-generate-crud frontend session Session
> symfony propel-init-crud frontend comment Comment
routing
homepage: url: / param: { module: session, action: list }
<?php echo url_for(‘@homepage’) ?> => /
session_view: url: /session/:id.html param: { module: session, action: view } requirements: id: \d+
<?php echo link_to(‘@sesion_view?id=’.$session->getId()) ?> => /session/12.html
default: url: /:module/:action/*
<?php echo url_for(‘session/view?id=’.$session->getId()) ?> => /session/view/id/12
Internal URI<module>/<action>[?param1=value1][¶m2=value2]
External URLhttp://www.example.com/module/action/[param1/value1]
view
• Templates
• Helpers
• Page layout
• Code fragments– Partials– Components– Slots
view
• Templates
• Helpers
• Page layout
• Code fragments– Partials– Components– Slots
<h1>Welcome</h1>
<p>Welcome back, <?php echo $name ?>!</p>
<p>What would you like to do?</p>
<ul>
<li><?php echo link_to('Read', 'article/read') ?></li>
<li><?php echo link_to(‘Write', 'article/write') ?></li>
</ul>
view
• Templates
• Helpers
• Page layout
• Code fragments– Partials– Components– Slots
<?php echo use_helper('HelperName') ?>
<?php echo use_helper('HelperName1', 'HelperName2' ) ?>
<?php echo tag('input', array('name' => 'foo', 'type' => 'text')) ?>
<?php echo tag('input', 'name=foo type=text') ?>
=> <input name="foo" type="text" />
view
• Templates
• Helpers
• Page layout
• Code fragments– Partials– Components– Slots
view
• Templates
• Helpers
• Page layout
• Code fragments– Partials– Components– Slots
view
• Templates
• Helpers
• Page layout
• Code fragments– Partials– Components– Slots
view
• Templates
• Helpers
• Page layout
• Code fragments– Partials– Components– Slots
controller
• Front controller
• Actions
• Request
• User sessions
• Validation
• Filters
controller
• Front controller
• Actions
• Request
• User sessions
• Validation
• Filters
1 Define the core constants.
2 Locate the symfony libraries.
3 Load and initiate the core framework classes.
4 Load the configuration.
5 Decode the request URL to determine the action to execute and the request parameters.
6 If the action does not exist, redirect to the 404 error action.
7 Activate filters (for instance, if the request needs authentication).
8 Execute the filters, first pass.
9 Execute the action and render the view.
10 Execute the filters, second pass.
11# Output the response
controller
• Front controller
• Actions
• Request
• User sessions
• Validation
• Filters
class mymoduleActions extends sfActions
{
public function executeIndex()
{
// Retrieving request parameters
$password = $this->getRequestParameter('password');
// Retrieving controller information
$moduleName = $this->getModuleName();
$actionName = $this->getActionName();
// Retrieving framework core objects
$request = $this->getRequest();
$userSession = $this->getUser();
$response = $this->getResponse();
// Setting action variables to pass information to the template
$this->setVar('foo', 'bar');
$this->foo = 'bar'; // Shorter version
}
}
controller
• Front controller
• Actions
• Request
• User sessions
• Validation
• Filters
$this->getRequest()->
getMethod() sfRequest::GET sfRequest::POST
getCookie('foo')
isXmlHttpRequest()
isSecure()
hasParameter('foo')
getParameter('foo')
getParameterHolder()->getAll()
getLanguages()
getAcceptableContentTypes()
getFileNames()
getFileSize($fileName)
getFileType($fileName)
setAttribute(‘foo’)
getAttribute(‘foo’)
controller
• Front controller
• Actions
• Request
• User sessions
• Validation
• Filters
$this->getUser()->
setAttribute('nickname', $nickname)
getAttribute('nickname', ‘Default')
getAttributeHolder()->remove('nickname')
getAttributeHolder()->clear()
$this->setFlash('attrib', $value)
$this->getFlash('attrib')
controller
• Front controller
• Actions
• Request
• User sessions
• Validation
• Filters
class myModuleActions extends sfActions
{
public function validateMyAction()
{
return ($this->getRequestParameter('id') > 0);
}
public function handleErrorMyAction()
{
$this->message = "Invalid parameters";
return sfView::SUCCESS;
}
public function executeMyAction()
{
$this->message = "The parameters are correct";
}
}
controller
• Front controller
• Actions
• Request
• User sessions
• Validation
• Filters
Live demo !