Codebits 2012 - Fast relational web site construction.
1. Fast relational web site
construction with PHP
Nelson Gomes (nelson.gomes@telecom.pt)
Team Leader
ZCE, ITIL Foundation V3, LPIC1-101
16th of November 2012
3. Introduction
The purpose of this talk is to help web developers to take
advantage of some known PHP frameworks to develop
complex websites rapidly;
Although we're showing some specific frameworks in this
talk, other frameworks exist that do almost the same thing
or even better;
Just google the web and try out other frameworks and use
the ones you like the most;
The benefit of using these frameworks is to be more
productive, to use best pratices and to develop faster;
4. Introduction (cont.)
Developing complex sites with complex relational databases
can be very difficult without the right tools:
Manage Database Connections;
Maintaining Relational Integrity;
Performing Transactions;
Acessing data spread over several tables;
Updating, deleting and inserting records without loosing
integrity;
5. Introduction (cont.)
Example of how some developers still program:
mysql_query(“insert into customers (name, phone) values
('$name', '$phone');
When using many tables the developers need to create
methods to insert, update, delete and query records, this can
give a lot of work;
In this presentation, I'll try to show how to do all of this
with minimum programming...
6. Introduction (cont.)
Web site security depends greatly of the awareness
developers have for security issues;
Many PHP developers do bad code because don't know the
problems that can arise from bad programming:
SQL Injection;
Cross-Site Scripting;
Cross-Site Request Forgery;
(...)
Using these frameworks correctly reduce (some) security
vulnerabilities;
8. Frameworks
Introducing some PHP frameworks:
Doctrine – is a Object relational mapper that works on
top of PDO (PHP Data Objects);
Smarty – an engine for web templating in PHP;
MVC – (could use one MVC framework, but on this talk
won't use any);
You can easily change any of these frameworks with others
of your choice;
9. Frameworks (cont.)
Doctrine
With Doctrine you can use 'Code First', 'Model First' and
'Database First' approaches, meaning you start by
creating objects, UML or a database as a start point;
All doctrine queries are made using DQL – Doctrine
Query Language;
In this talk we'll go throught 'Database First' approach,
meaning Doctrine will look into the database and generate
code for it;
In this talk I'm using Doctrine 1.2.4, why?
10. Frameworks (cont.)
Advantages of using Doctrine:
Object Oriented Approach;
No need to rewrite code when switching database;
No need to keep track of identifiers of the inserted fields;
Object are written to database by Doctrine, no need to
SQL!
Associations are managed by Doctrine;
Database can be generated by our models (yaml, xml)
11. Frameworks (cont.)
Smarty
Is a template engine for PHP;
Allows separating design from code;
Eases the maintainability of on large web sites;
Allows reuse of templates;
Makes your website go faster;
Improves security;
Easily extensible;
15. The 'Magic'
Folder models has been filled by Doctrine with code:
models/*.php (to fill with your business logic);
models/generated/*.php (object definitions);
Folder lib/templates_c/*.php has been filled by Smarty with
munged templates;
Now that the magic is working let's fill a web page with the
data we have in the tables!
16. The 'Magic'
Declaring table relations using hasMany, hasOne:
class Customers extends BaseCustomers {
public function setUp() {
$this>hasMany('CustomerUsers as relatedUsers',
array(
'local'=>'id',
'foreign'=>'fk_customer_id',
)
);
(…)
}
}
17. The 'Magic'
Avoiding XSS in Smarty:
function escFilter($content,$smarty) {
return htmlspecialchars($content,ENT_QUOTES,UTF8);
}
$smarty>registerFilter('variable','escFilter');
To show unsafe content just explicitly do:
{$variable nofilter}
Doctrine manages strings avoiding SQL Injection attempts!
(but cannot do miracles!)
18. Transactions
But a good business layer only works well if it is
transactional, to maintain relational integrity.
$conn=Doctrine_Manager::connection();
try{
$conn>beginTransaction();
$customer=new Customers();
$customer>name=$name; (...)
$customer>save();
$address=new Addresses();
$address>fk_customer_id=$customer>id; (...)
$address>save();
$conn>commit();
} catch(Exception $ex) {
$conn>rollback();
}
19. Queries
Any language or framework is secure depending on how
users use it:
static function updateCustomerName($name, $id) {
$conn=Doctrine_Manager::connection();
$conn>execute(“update customers set name='$name' where id=$id”);
}
Bad pratice to concat any user input, use instead Doctrine
methods!
The above example can also be database dependant which
isn't a good practice.
21. Conclusion
In this demo:
We accessed data scattered over 7 different tables with
(almost) zero programming;
We didn't established or managed any connection;
Our application can be now easily converted to another
database engine with minimum effort;
Each page is only a couple of lines in size, no more
HTML embedding nightmares...;
Our application has become more secure;
In a couple of minutes...