PHP + Symfony

saucecopywriterInternet και Εφαρμογές Web

2 Φεβ 2013 (πριν από 4 χρόνια και 9 μήνες)

166 εμφανίσεις

PHP + Symfony

Rapid application development


Jonathan Bell

Nov 18, 2010

A Developer

s User Story


It

s 5:00pm on Sunday


Need to have a web app together for Monday


Want to sleep tonight


Want to have a

complete app


(validation,
security, etc)


Don

t have time machine


EJB? No…


.Net? No…

Enter Symfony

Symfony is a code generator/MVC
framework for PHP. Sounds a lot like
ruby on rails. Why PHP?

PHP is super C
-
like, might be easier to
pick up


ORB mapping
(pluggable)


CRUD generation


Validation


Routing


Templating


Plugins


Unit Testing

Object Brokering (Model layer)


Automatically generates fully
documented PHP classes from
config

file


Removes need for repeated DB calls,
provides abstraction

schema.yml

propel:


weblog_post:


_attributes: { phpName: Post }


id:


title: varchar(255)


excerpt: longvarchar


body: longvarchar


created_at:

PHP Code

$p = new Post();

$p
-
>setTitle(

Test Post

);

$p
-
>setBody(

the body

);

$p
-
>save();


$posts = PostPeer::doSelect(new
Criteria());

foreach($posts as $post)

{

print

Post:

.$post
-
>getTitle();

}

CRUD Generation + Validation (Controller +
View)


Web programmer

s worst nightmare:
writing huge forms with dozens of
inputs, associated form processors
and validators


Symfony to the rescue: generates
template Create/Read/Update/Delete


Very, very easy to customize once
generated

symfony propel:generate
-
module admin findable FindableItem

indexSuccess.php:

<
h1
>
Findable List
</
h1
>


<
table
>


<
thead
>


<
tr
>


<
th
>
Id
</
th
>


<
th
>
Name
</
th
>


<
th
>
Cardinality
</
th
>


<
th
>
Points
</
th
>


<
th
>
Description
</
th
>


<
th
>
S findable category
</
th
>


</
tr
>


</
thead
>


<
tbody
>


<?php

foreach
($findable_item_list
as
$findable_item):
?>


<
tr
>


<
td
><
a

href
="
<?php

echo
url_for('findable/edit?id='.
$findable_item
-
>getId())
?>
"
>
<?php

echo
$findable_item
-
>getId()
?>
</
a
></
td
>


<
td
>
<?php

echo
$findable_item
-
>getName()
?>
</
td
>


<
td
>
<?php

echo
$findable_item
-
>getCardinality()
?>
</
td
>


<
td
>
<?php

echo
$findable_item
-
>getPoints()
?>
</
td
>


<
td
>
<?php

echo
$findable_item
-
>getDescription()
?>
</
td
>


<
td
>
<?php

echo
$findable_item
-
>getSFindableCategoryId()
?>
</
td
>


</
tr
>


<?php

endforeach;
?>


</
tbody
>

</
table
>



<
a

href
="
<?php

echo
url_for('findable/new')
?>
"
>
New
</
a
>

actions.class.php:


public function
executeIndex(sfWebRequest
$request
)


{


$this
-
>findable_item_list = FindableItemPeer::doSelect(
new
Criteria());


}

Validation


Free with form generation!


We already defined the form

widgets


in
the original .yml file, including basic data
ranges

BaseFindableItemForm

$this
-
>setValidators(
array
(


'id' =>
new
sfValidatorPropelChoice(
array
('model' => 'FindableItem', 'column' => 'id', 'required' =>
false
)),


'name' =>
new
sfValidatorString(
array
('max_length' =>
255
, 'required' =>
false
)),


'cardinality' =>
new
sfValidatorInteger(
array
('required' =>
false
)),


'points' =>
new
sfValidatorInteger(
array
('required' =>
false
)),


'description' =>
new
sfValidatorString(
array
('required' =>
false
)),


's_findable_category_id' =>
new
sfValidatorPropelChoice(
array
('model' => 'FindableCategory', 'column' => 'id')),


));

Can easily override this in the implementation for
FindableItemForm with new validators. Or, don

t
bother and leave it at default!

Aspect Oriented Development?


Symfony supports

behaviors



Automatically creates many hook
-
spots


Classic example:

paranoid


behavior


Replace deletes with setting a flag


Augment selects to avoid records with that flag

Routing


Problem: We all love having simple
looking URLs:


http://cusearch09.com/user/image/5/320


Instead of
http://cusearch09.com/user/upload/imageT
humb.php?id=5&width=320


Solution:


Apache
mod_rewrite


No... too complicated and hard to change on the
fly. Who wants to deal with
RegExp
?


Symfony
:


routing.yml

resized_image:


url:

image/:id/:width


param: {module: upload, action: imageThumb}

Templating


Generic template setup


Allows for

partial


templates


Inheritance!


Helpers


link_to()


img_tag()

Plugins


Easy to extend Symfony with plugins


Follow observer pattern


static public function
listenToSomeSortOfEvent(sfEvent $event)


Hooks your plugin to any part of Symfony


Uses: objects, aspects


Security? AJAX?

Free Lime Tests!

(note: not Lime

s Disease tests)

Unit test the model


Functional test the controllers (WOW!)

$t = new lime_test(1, new lime_output_color());

$t
-
>diag('
-
>retrieveByUsername()');

$user = UserPeer::retrieveByUsername('jbell');

$t
-
>is($user
-
>getLastName(), 'Bell', '
-
>retrieveByUsername() returns the User for the given username');

$b = new sfTestBrowser();

$b
-
>get('/foobar/edit/id/1');

$request = $b
-
>getRequest();

$context = $b
-
>getContext();

$response = $b
-
>getResponse(); // Get access to the lime_test methods via the test() method

$b
-
>test()
-
>is($request
-
>getParameter('id'), 1);

$b
-
>test()
-
>is($response
-
>getStatuscode(), 200);

$b
-
>test()
-
>is($response
-
>getHttpHeader('content
-
type'), 'text/html;charset=utf
-
8');

$b
-
>test()
-
>like($response
-
>getContent(), '/edit/');

But wait, there

s more!


Who would want to run each test
manually, or write a script even (bah!)


Put all tests in the

unit


folder


then...


$ symfony test:all

A code review: Rentpost


Managing landlord/tenant relations


PHP, Symfony, AJAX