You are on page 1of 32

Published by S&S Media Group

October 2013
Issue 19

Advanced MySQL Query Tuning

by Alexander Rubin
Security holes? Who cares?
by Arne Blankerts
Percona Live London
Conference preview
Open Source Spotlight
Debugging tool Kint

The Symfony2 CMF


Solving the framework or CMS dilemma

Selling stuff with Sylius

Get stuck into the next big thing in ecommerce

Branching out with Twig


www.webandphp.com

A guide to Symfony2s favorite templating engine

Image licensed by Ingram Image

Also in this issue

In the key
of Symfony2

Letter from the Editor Contents

Music to my ears

Contents
This months top events 
Open source spotlight: Kint
Interview with Rokas leinius

As I looked over this issues contents, I noticed


a theme running through
several articles: Symfony2.
Everyone has their favourite PHP web framework,
but in the two short years
since its release, Symfony2 appears to have struck
a chord among the community, forming the basis of a range of exciting open
source projects.
For example, Sylius is a promising new ecommerce
system that has generated a considerable buzz, even
though its far from finished. Like Symfony2, its also
composed of bundles where you take only the bits you
need, and leave the bits you dont. You can find out
more about using Sylius (and opportunities to get involved in its development) in the feature on page 9.
Another young Symfony2-based project is the Content Management Framework, which aims to solve
the framework or CMS dilemma once and for all
just in time for its stable 1.0 release One of the
projects developers, David Buchmann, has written
an introduction to the CMF, which you can find on
page 5.
Its not just hip, new projects that are making use of
it, either. Even dinosaurs like PHPBB and Drupal are
integrating Symfony components into their low-level
architecture, thanks to its practical modular architecture.

www.webandphp.com

Plus, instead of keeping their best innovations


locked within the framework, SensioLabs have been
generous in spinning off Symfonys best components
into separate projects like SwiftMailer and Twig (the
latter of which you can find a tutorial for on page 14).
Its a framework for a distributed age: instead of a
monolithic PHP script on a single LAMP stack, todays
applications are assembled from the best OSS has to
offer, split between remote servers and delivered to
an exploding variety of devices. Even if youre not using any of Symfony2s code base, theres plenty to be
learnt from the project.
The funny thing is that weve accidentally ended up
with an issue packed full of Symfony2-powered goodness and yet, not a single article on the core framework itself! Luckily, for those looking for something
on Symfony2 itself, well be taking an early look at the
frameworks upcoming release, Symfony 2.4, in next
months issue.

3
4

Tutorial

Introducing the Symfony2 Content 


Management Framework

by David Buchmann
Feature

Selling stuff Symfony-style with Sylius 


by Antonio Peri -Maar

Tutorial

Branching out with Twig 


by Aurelio De Rosa

14

Tutorial

Advanced MySQL Query Tuning 


by Alexander Rubin

18

Column

Creating business tools in cyberspace? 


Think Different!

25

Ben Greenaway

Column

Elliot Bentley, Editor

Security holes? Who cares?

by Arne Blankerts, thePHP.cc, Germany

28

Column

Conference preview: 
Percona Live London

30

by Terry Erisman, Chief Marketing Officer, Percona

Web&PHP Magazine 10.13 | 2

Calendar

Community Corner

This months top events


October 1 November 4 //

A handpicked selection of some of the most


exciting PHP events from around the world

October 3 // Bellingham, WA, US // Free

October 8 // Zrich // Free

October 23 // Bogot, Colombia // Free

AWS SDK for PHP

Making News with PHP

HipHop VM for PHP

http://www.meetup.com/BellinghamDevelopers/events/133264492/
Following a bite to eat at Westside Pizza, AWS
evangelist Jeremy Lindblom will be giving a
talk on getting your app to run in the cloud.

http://webtuesday.ch/meetings/20131008/
Hear from Benjamin Regg, a developer for Swiss
newspaper Blick, on how he applies open source
tools to high-speed, large-scale environments. Talk
is in German.

http://www.meetup.com/PHPColMeetup/
events/129463532/
Learn about Facebooks custom replacement
to the Zend Engine, which can (apparently)
increase performance by 5x.

October 45 // Cape Town, South Africa //


R800 (10 in USD)

October 17 // San Antonio, TX, USA // Free

October 2730 // Munich, Germany //


1,069.81 for three days

PHP South Africa


http://www.phpsouthafrica.com/
South Africas first ever conference sees
speakers both international and local travel to
Cape Town for two days of talks.

NoSQL Bakeoff
http://www.meetup.com/sawebdev/
events/135588782/
This months event is (at time of writing) still looking for volunteers to do a 1015 minute talk on
MongoDB, Neo4J, Redis or CouchDB.

International PHP Conference 2013


http://phpconference.com/2013/
Web & PHPs German colleagues host another installment of the long-running conference, this time with a keynote from Opera
evangelist Bruce Lawson.

To suggest an event for our calendar,


email elliotb@webandphp.com.

www.webandphp.com

Web&PHP Magazine 10.13 | 3

OSS Spotlight

Community Corner

Open source spotlight: Kint


Meeting the people behind the most exciting homegrown OSS projects. This
month, we speak to Rokas leinius about Kint, a drop-in replacement for
PHPs native debugging functions.
Web & PHP Magazine: Whos behind Kint?
Rokas leinius: Kint has been a single-person project, but over the recent years Ive had
some valuable contribution (https://github.com/
raveren/kint/graphs/contributors) thanks to the
popularity of GitHub and the power of open
source in general.
WPM: Why did you decide to start it?
leinius: I am constantly looking for ways to improve my workflow and I realised this is the kind
of tool that would help out in a HUGE way. At the
time I began Kint, the only alternative was the awfully buggy and already-then-abandoned Krumo.
Please dont even link to it, Id hate to give it even
more popularity.
Kint became a huge part of my development cycle, dumping newly created variables, debugging
condition outcomes, etc, and eventually it became
too good to withhold to myself.
Kint is much more than a debugging tool. I use it
all the time and sincerely have no idea how others
can develop effectively without it.

www.webandphp.com

WPM: Whats wrong with PHPs native debugging tools?


leinius: Kint to var_dump() is what a full-fledged
IDE is to MS Notepad. Both do the job, however neither notepad nor var_dump() are tailored to do real
world tasks. They are bare, generic necessities to resort to when nothing better is available.
The problem with var_dump(), debug_backtrace()
and the like is that they are terribly awkward to use
and much more importantly the information they
generate is not easy for a human to comprehend.
WPM: How does Kint compare to Xdebug?
leinius: Xdebug adds a couple of features to vanilla
var_dump() to make it a little more bearable to use but
not more.
Kint, on the other hand, has dozens upon dozens of
essential features I cant imagine coding without. Its
a tool written from scratch by a developer for developers not a layer on top of some other sub-standard
tool. Its been in the works for over three years and has
become really functional and a pleasure to use.
You can read about (most of) the myriad of features
in the project page (http://raveren.github.io/kint/), and
the best part is, its dead-simple to begin working with
and youll discover the advanced usage gradually if
youre interested.

WPM: Is manual debugging any substitute


for unit testing?
leinius: These are two different areas and
both are critical. You definitely need test coverage for your code as much as you need a proper
toolset to fix bugs when tests dont pass.
WPM: Where do you hope to see the project
in a years time?
leinius: Kint is not the only project of mine
that I want to release. I am passively preparing to
opensource my error-handling toolset, which integrates Kint heavily and is way better than every
thing Ive tried so far. Im hoping to package and
release it in the near future, so theres that.
I am hoping that one day, Kint, plus the to-bereleased error handler will be accepted as de facto
debugging tools for PHP and be included in 3rd
party frameworks by default.

Homepage:
http://raveren.github.io/kint/
On GitHub:
https://github.com/raveren/kint/

Web&PHP Magazine 10.13 | 4

Symfony2 CMF Tutorial

Your framework or CMS dilemma solved

Introducing the Symfony2 Content


Management Framework
An official sub-project of Symfony2, the CMF isnt yet another CMS but a powerful modular collection of libraries and bundles.

by David Buchmann

When starting a new web project, you have to decide


whether it is a CMS project or an application. This
is a difficult decision. For the application approach,
you can use a solid and clean framework like Symfony2[1]. But if the project also encompasses some
content management, the efforts for that part quickly
eat up way too much of the budget.
On the other hand, you can chose a powerful CMS
like Drupal. Common CMS functionality is already
there at no cost, but custom functionality means either slapping together dozens of modules of sometimes doubtful quality, or a lot of coding without
any proper framework. Also, experience shows that
when we need to do a task differently than how
Drupal thinks, it quickly becomes very hard as you
cannot replace or extend core parts of Drupal. The
only option is to add callbacks to fix things after the
fact, at the costs of unexpected interactions with all
the other modules.

www.webandphp.com

The CMF [2] aims to provide a way out of this dilemma. It consists of a couple of Symfony2 bundles
and PHP libraries that provide the means to do content
management. You can add them to a Symfony2 application to satisfy CMS needs. Or you can use them
as a base to build a completely custom CMS without
wasting time on the basics. Use the components that
make sense for the project, extend what you need and
ignore what you dont.
The CMF follows the idea of Decoupled Content
Management [3]. The Symfony2 bundles are about
functionality only. Persistence is cleanly separated,
and while a default handling for Doctrine PHPCRODM [4] is provided others can be used just as well.
The CmfCreateBundle enables frontend editing using
the general purpose create.js [5] editing framework.
The CMF is currently in release candidate phase,
with a stable 1.0 release expected at the time this
article is published. A very active community is maintaining and improving the various components. A couple of websites are already using the CMF or parts of

it[6]. Also, both Drupal 8 [7] and ezPublish are using


the routing component of the CMF.

Listing 1
$ git clone git://github.com/symfony-cmf/cmf-sandbox.git
$ cd cmf-sandbox
$ cp app/config/parameters.yml.dist app/config/parameters.yml
$ cp app/config/phpcr_doctrine_dbal.yml.dist app/config/phpcr.yml
$ curl -s http://getcomposer.org/installer | php -$ ./composer.phar install

Listing 2
$ app/console doctrine:database:create
$ app/console doctrine:phpcr:init:dbal
$ app/console doctrine:phpcr:repository:init
$ app/console doctrine:phpcr:fixtures:load

Web&PHP Magazine 10.13 | 5

Symfony2 CMF Tutorial

Listing 3
<?php
namespace Sandbox\MainBundle\Document;
use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCRODM;
use Symfony\Cmf\Bundle\ContentBundle\Doctrine\Phpcr\StaticContent
class IntroContent extends StaticContent
{
/**
* @PHPCRODM\String(translated=true)
*/
private $intro;
// getter and setter for intro...
}
Figure 1: The CMF start page

Figure 2: CMF routing process

Basic Usage
The best starting point to explore the CMF is the Sandbox [8]. You can click around in http://cmf.liip.ch , but
best is to install it locally to be able to change code.
You should now have a Symfony2 project with the
CMF set up. The storage engine we chose in Listing1
is Doctrine PHPCR-ODM with the SQLite database
driver. Next we need to initialize the database and the
repository. The last line of Listing 2 loads some fixtures so that we actually have something to look at.
Now you need to point a web server to the web/
directory of the project. When you point your browser
to http://cmf.lo/app_dev.php you will be greeted by the
default home page. Figure1 explains what CMF component handles which part of the page.
The CmfContentBundle handles simple static content. It provides a model class for the content and a
Symfony2 controller that uses either the specified or a
default twig template to render the content. The Cmf
MenuBundle extends the KnpMenuBundle, adding the

ability to load menus from Doctrine and having menu


items point to content documents so that menu entry
URLs do not need to be hardcoded. The CmfBlock
Bundle builds upon SonataBlockBundle to provide reusable pieces of content. This can be used for layout
purposes (put content into a sidebar or have pages that
consist of many blocks instead of a mixed WYSIWYG
content), to display the same content on several pages
and also to allow the page editor to control where application output should appear.
Image and also file handling is encapsulated into
the CmfMediaBundle. All other bundles that provide
file related services use this bundle rather than re-implementing things. This makes sure that the various
components are able to share media files. The Cmf
MediaBundle provides basic models and optionally integrates with LiipImagineBundle for rendering images,
as well as with the WYSIWYG editor image handling
plugin elFinder. Integration with the SonataMediaBun
dle is planned.

www.webandphp.com

Routing
When a request is received, the first thing Symfony2
has to do is to decide what code will handle this request. The main information used to make this decision is the requested URL, but other information such
as the host name used or accept headers can play a
role as well. This process is called Routing in Symfony2 and the result of the routing is information about
which Controller to call. In core Symfony2, routing is
configured using configuration files that define URL
patterns and corresponding controllers.
The CmfRoutingBundle extends Symfony2 core
routing to load routes from a database so that they can
be edited by the user. A CMF route can simply specify
a controller name. More interesting is the option to
reference a content object. An additional step called
Enhancer inside the routing processes the matched
route to infer additional information like the controller
and the template to use for the referenced content.
The aim of this design is to not duplicate configuration

Web&PHP Magazine 10.13 | 6

Symfony2 CMF Tutorial

Figure 3: The CMF start page

Listing 4
# app/config/config.yml
cmf_routing:
dynamic:
# ...
templates_by_class:
Sandbox\Document\IntroContent: SandboxMainBundle:IntroContent:
index.html.twig
# ...

information in the database so that refactorings of the


application logic do not need data changes. The logic
can also be used to transform URL parts into domain
objects to keep the controller lean. Drupal has been
using this idea for quite some time, calling it Upcast.
Figure2 illustrates the routing process. The additional
steps provided by CMF are colored in green.
An interesting side effect of linking routes with content is that the CMF routing can also generate a URL
from the content object. This is for example used in

www.webandphp.com

the menu system, to get the URLs for menu items that
link to content.
To seamlessly integrate the CMF into standard
Symfony2 applications, the CmfRoutingBundle also
provides a ChainRouter which replaces the core Symfony2 router. The ChainRouter calls the core router,
the CMF router and any other routers that where registered to it, in a configurable order. That way, normal
Symfony2 routes are still possible and do not need to
be transferred into the database.

a separate Intro field that will be used in a list view


of the content. For the model, we simply extend the
StaticContent from the CmfContentBundle in Listing3.
The generic controller will do just fine for this content. But we need a different template to render the
intro field. We configure the routing to know that it
should specify our new template for the new content
class in Listing4.
In the template, simply add {{ cmfMainContent.intro}}
where you want to output the introduction text field.

Editing
When the user is allowed to edit content, the CmfCre
ateBundle shows the Create.js toolbar at the top of the
page. By clicking on the Symfony2 logo, the editing bar
is minimized and expanded. Clicking the Edit field en
ables Frontend Editing. The content is edited right in the
location where it is shown. Create.js provides real WYSIWYG editing instead of changing the HTML structure by
adding an iframe around the editable content. That way,
the CSS does not need to be adapted and editing does
not diverge from display. Upon clicking Save, all edited content is stored over AJAX and the page is updated
without reloading. Figure3 shows the editing in action.
The CmfCreateBundle integrates create.js into Symfony2 with the help of the CreatePHP library [9]. Create.js uses RDFa attributes on content to know what
content is editable and how to communicate with
backend to save changes. CreatePHP implements the
backend handling for storing changes and also provides helpers so that template writers do not need to
manually handle the RDFa attributes. Sounds confusing? Lets add a new type of content to the sandbox to
see how this is all done.

Make the content editable with create.js


If you want the field to be editable with create.js, a bit
more work is required. You need to provide the mapping between the model and RDFa as shown in Listing5.
In the detail template, we adjust the rendering to
output the intro field with the CreatePHP twig extension. The individual articles can now even be edited on
the overview page if we render them with a template
like shown in Listing6.
To create content of our new type, the easiest is to
create it programmatically in a command. The sandbox
provides sonata admin classes for the default documents. You can extend the StaticContentAdmin to add
the intro field.

Adding a new type of content


To see a bit more, lets add a new type of content in the
sandbox. For the sake of the example, lets simply add

Storage Layers
Though designed to be storage agnostic, there is a
preferred storage layer for the CMF: Doctrine PHPCRODM. This object-document mapper stores model
classes into the PHP content repository [10]. The reason for this is simply ease of use. PHPCR is tree-oriented, but inside the tree you can mix different kinds
of content. For a CMS, this means that content can
be structured according to its logic hierarchy rather
than by type. A CMS easily has a dozen or more types
of content that differ only on details. The other cru-

Web&PHP Magazine 10.13 | 7

Symfony2 CMF Tutorial

Listing 5
<!-- src/Sandbox/MainBundle/Resources/rdf-mappings/Sandbox.MainBundle.
Document.IntroContent.xml
xmlns:sioc="http://rdfs.org/sioc/ns#"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:skos="http://www.w3.org/2004/02/skos/core#"
xmlns:sandbox="http://cmf.symfony.com"
typeof="sioc:Post"
>
<children>
<property property="dcterms:title" identifier="title" tag-name="h1"/>
<property property="sandbox:intro" identifier="intro" />
<property property="sioc:content" identifier="body" />
</children>
</type>

Listing 6
{% foreach pages as teaser %}
{% createphp teaser as rdf %}
<h1 class="my-title" {{ createphp_attributes( rdf.title ) }}>
{{ createphp_content( rdf.title ) }}
</h1>
<div class="intro" {{ createphp_attributes( rdf.intro ) }}>
{{ createphp_content( rdf.intro ) }}
</div>
{{ rdf.content|raw }}
{% endcreatephp %}
{% endfor %}

cial thing is that links between objects in PHPCR do


not need to know the target class as relational databases typically do. Thus the CmfRoutingBundle can
provide a route class that can point to any object in
PHPCR-ODM without knowing what kind of content
that could be.

www.webandphp.com

Contrary to NoSQL databases like MongoDB or


CouchDB, PHPCR is built on the concept of tree
structures. It provides efficient and powerful tree
handling out of the box, where you can directly access and modify any node of the tree. On top of
this, PHPCR makes binary data a primary citizen and
defines fine grained access control, versioning and
a bunch of other advanced content management
functionality that otherwise has to be re-invented
for each application. PHPCR-ODM natively supports
multilanguage in such a way that the application
most of the time does not even need to care about
multilanguage.
To use PHPCR-ODM in Symfony2, you need a PHPCR implementation like Jackalope, the Doctrine PHPCR-ODM library and its PHPCR bundle for Symfony2.
There is also a PHPCR Sonata Admin bundle to provide
backend editing of all PHPCR-ODM documents.
Some CMF bundles also provide mappings for Doctrine ORM. For small and/or simple projects, the ORM
is a viable option. On larger projects, the added flexibility of PHPCR-ODM will become more important.

David Buchmann is a core developer of the Symfony Content Management Framework and of the PHPCR and the Jackalope tool suite.
He works as software architect and PHP developer at the swiss
company Liip AG.

References
[1] www.symfony.com
[2] cmf.symfony.com
[3] http://decoupledcms.org/
[4] http://docs.doctrine-project.org/projects/doctrine-phpcr-odm/en/latest/
index.html
[5] http://createjs.org/
[6] http://cmf.symfony.com/references
[7] https://drupal.org/node/1874500
[8] https://github.com/symfony-cmf/cmf-sandbox
[9] http://createphp.org
[10] PHPCR was covered in a previous issue of Web & PHP: http://webandphp.
com/ThePHPContentRepository

Should I use the CMF?


Today, the CMF can handle routing, plain content
and structured content, media files, menu systems
and has means for editing both in the frontend and in
backend editors. Granted, there are still issues to be
solved, and advanced features to be added. But rather
than starting from scratch, why not contribute to an
existing project to make it even more awesome?
The CMF is very close to a stable release. If there
are any backwards compatibility breaks needed at all,
information is provided what needs to be done to upgrade your application. There is a thriving community
pushing the CMF forward and building up a comprehensive documentation, available at symfony.com.
The time is right to give the CMF a try!

Web&PHP Magazine 10.13 | 8

Sylius

Feature

iStockphoto.com/cultury

by Antonio Peri -Maar

The next big thing in ecommerce

Selling stuff Symfony-style


with Sylius
Though only seven months old, this new ecommerce framework has gathered
a massive following already thanks to its modular architecture and modern
development processes and its use of Symfony2.

www.webandphp.com

Soon after the Internet became a mass medium, many


systems developed in order to seize new opportunities. E-commerce grew rapidly and many realized that
there are business opportunities related to selling and
buying online. Web shop systems followed that lead.
Today there are numerous systems for web shop development as well as many companies that have decided to implement webshops.
In this article I will talk about Sylius, which is becoming more and more popular. It is based on the Symfony2 [1] framework, which is one of the most popular
PHP frameworks and each day more and more developers use it to develop both large and small web applications. Certainly, the migration of eZ Publish [2] and
Drupal [3] to Symfony2 framework has contributed to
this trend and the quality of Symfony2 framework.

What is Sylius?
Sylius is a modern e-commerce platform based on
Symfony2 framework, and as an open source project,
announced under MIT license, it is therefore completely free for downloading and implementing any
changes. It is developed using BDD [4] and TDD methodology the only ecommerce solution implemented
using this methodology at the moment. It is characterized by a simple and clear architecture as well as
maximal flexibility. Even though it has not reached its
beta phase yet, developers are already using it for implementing complex and custom webshops.
Sylius is a new player among existing open source
ecommerce systems, such as Magento, osCommerce
and PrestaShop. Sylius is still not in beta release and
yet is already well-known within the Symfony2 community. Developers are using it for producing ecommerce solutions with high levels of customization.
What is very exciting is that you can participate in mak-

Web&PHP Magazine 10.13 | 9

Sylius

Feature

and it has been downloaded 172 795 times so far.


In total, there are 4 235 contributions, 890 GitHub
Watchers and 501 GitHub forks. Sylius is supported
in several languages: English, Spanish, Croatian, Italian, Japanese, German, Polish, Dutch, Serbian, Russian and more. There are more than 3000 commits and
new features are constantly added.

ing such a great software as Sylius since the whole


project is produced by community. The community
decides and discusses about every major decision and
everybody can participate if they want. How do you
participate? It is very easy you just need to have a
GitHub account and a little bit of time and knowledge
about Symfony2 framework and you can start. You can
participate with adding translations or just with reporting bugs, or you can just spread the word about Sylius.

Community
As mentioned earlier, Sylius is an open source project,
started by Pawe J drzejewski [5] in 2011. The idea of
commercializing the product existed at one point (KNP
Labs company), but Pawe gave up on the idea because

www.webandphp.com

he thought that the community deserves transparency


regarding the project that they are contributing to. Also,
he said he feels that toxicity and politics can not contribute to the project in a positive way. His final decision
was to keep developing Sylius in the community that
created it, maintaining the complete transparency.
Pawe J drzejewski started the Sylius standalone application seven months ago, embracing StoryBDD with
Behat [6]. Since then the community has managed to
develop a relatively big set of features and achieve a
very extensible architecture. Currently, after finalizing
the repositories organization on GitHub, the priority is
to fill the feature holes in the checkout and API.
At the moment, 85 developers from all over the
world are contributing to the development of Sylius,

Features:
yy Product Management: unlimited products, complex products with options and attributes, product
variations
yy Inventory tracking: real time tracking, products
available on demand, tracking of individual units
yy Complete taxation support: works with simple
and complex tax rules, rates for different tax categories and zones, tax included in price support,
customizable tax calculators
yy Product categories: tree structure, complex taxonomies, list your products by category, brand,
producer (and so on), create featured product
easily
yy Shipping engine: organize and track your shipments, unlimited number of shipping methods and
individual shipment units, track shipments, statuses, and individual shipment units, multiple flexible
shipping charge calculators
yy Easy to host: Syliys requirements are identical to
Symfony2 requirements, small setups run on cheap
hosting, easy to deploy with capifony (capifony
setup file comes with Sylius standard installation)
yy Free now and always: fully open source, business
friendly licence MIT; no paid edition with more
features
Architecture
Sylius was recently upgraded to the LTS Symfony version 2.3. (LTS = long term support for three

Web&PHP Magazine 10.13 | 10

Sylius

years for any bugs and four years for any security issue)[7]. Sylius architecture is based on several decoupled components. At this moment, the standard
version is made of 19 different bundles [8]: AddressingBundle, CartBundle, CoreBundle, FlowBundle,
InstallerBundle, MoneyBundle, OmnipayBundle,
PaymentsBundle, ProductBundle, PromotionsBundle, ResourcesBundle, SalesBundle, ShippingBundle,
TaxationBundle, TaxonomiesBundle, VariableProductBundle, and WebBundle. Symfony also uses
some well known Symfony2 bundles as: FOSUserBundle, FOSRestBundle, KnpMenuBundle and
PagerFantaBundle.
The idea behind Sylius is to construct your own solution using the components, the same philosophy as
Symfony2. All features are also available as standalone
bundles.
Sylius is completely component-based, so shop
tasks such as payment, shipping, taxation, taxonomy
(and so on) are non-mandatory installs and not have to
necessarily have to come from Sylius itself. You can
write custom bundles, or you can use any other existing bundle. Thus, it introduces the idea of the Symfony2 framework early on, which has been integrated,
in this case, as a full stack.
After you have installed Sylius on your server, you
can do the complete customization through override
and customize your own interface. It is easy to customize core models and adapt the logic inside any service.
Also, it is possible to use any of the 1900 Symfony2
bundles in your Sylius project.
A part of the customization process is overriding the Twig templates in order to customize your
shop. Twig is a modern template engine for the
PHP programming language. It compiles templates
to optimized PHP code and the overhead compared
to regular PHP code was reduced to the minimum.
Also, Twig has a sandbox mode to evaluate untrust-

www.webandphp.com

ed template code, which


allows Twig to be used as
a template language for
applications where users
may modify the template
design. Twig is powered by
a flexible lexer and parser.
This allows the developer
to define its own custom
tags and filters, and create its own DSL. You can
find out more about Twig
on the official page [8] [Editors note: Theres also a
tutorial on Twig elsewhere
in this issue].
Despite this separation
of concerns, functionality like model persistence or
CRUD actions is common for all bundles. Initially,
every model had its own controller, or even 2 controllers, one for backend and another for frontend. Additionally, there was 1 manager and 1 manipulator class
per entity, which resulted in a tremendous amount of
duplicated code in every bundle. To reduce tons of
duplicated code in controllers for basic CRUD actions,
Sylius uses SyliusResourceBundle [9], and it is the
most important bundle in the entire application. SyliusResourceBundle has allowed for removing manager and manipulator classes, frontend and backend
controllers for every entity, getting rid of very simple actions just to modify the sorting or filtering and
making controllers format agnostic (API). You can use
SyliusResourceBundle as standalone component for
any Symfony2 project.
When using Sylius, Behaviour Driven Development
(BDD) via Behat is already provided. Also, there is a
demo [10] that shows you the basic functions of Sylius.

Feature

The projects current version is 0.1.0. Anyone who


is interested in undertaking the project, can install it via
Composer quite simply (Listing 1). Issues that may occur when using Sylius are brought together on GitHub.
Also, you might want to follow Sylius on Twitter [12].
During installation you can chose to load fixtures
that insert some dummy data into your database so
you can test Sylius basic functions. The demo application includes features like registration, profile
administration, product listing, product listing by taxonomy and taxon, shopping cart, checkout process
without payment integration and full backend administration to work with your Sylius store.

Listing 1
curl -sS https://getcomposer.org/installer | php
composer create-project-s sylius dev / sylius
cd sylius
php app/console sylius:install

Web&PHP Magazine 10.13 | 11

Sylius

Future plans
The major challenge is implementing/integrating a
payment system, since the main application does not
have any payment integration available out of the box.
The idea is to have a payment system as flexible as
other Sylius engines.
Pawe J drzejewski, who started Sylius, has started implementing a gateway-agnostic solution and
will share a POC soon. This should allow to integrate
any payment API library into Sylius and hopefully
there will be many integrations in the core. While
this feature is not implemented there is options for
using some of existing Symfony2 bundles like JMS
PaymentCoreBundle [13] (Apache 2.0 licensed, this
bundle is not maintained very actively, and it also requires using concrete data models but it is an an
interesting option anyway) or Omnipay [14]. An integration bundle for the Omnipay library has already
been created and it seems to work well with Sylius.
However, the library itself has some architectural issues and involves a lot of BC breaks. Therefore, one
must be careful when evaluating this option, but it
seems promising. Payum[15] at first glance looks like
the most complex option. It seems to be regularly
updated and the author has already approached the
community on GitHub. It certainly seems like a promising option.
In the latest major Sylius update, Cart and Order models have been merged. By doing this, the checkout-related logic has been dramatically simplified. It is important
to make sure that templates are displaying the data properly in the cart summary and the calculation logic and
events are already in place. If a user has selected the
shipping method, it should be displayed or it should even
be possible to allow it to be changed in the cart form.
Tax is recalculated on every cart change. However,
there is a case when the cart has changed and the user
has already picked the payment/shipping options, and

www.webandphp.com

the system must be able to handle it. At the moment


this is done by event or hand calling the method for
recalculating taxes. Also there is no option for adding
and calculating taxes for delivery costs.
Sylius does not have proper notification/confirmation
e-mails integrated out of the box. At this moment, people have to listen to events and use their own mailers.
An e-mail notification system is definitely a must-have
thing for any ecommerce solution.
All Sylius controllers work on top of the FOSRest
Bundle [16] and those who need the API can access
it relatively easily. Some work was started on routing
configuration (in a separate branch), but configuration
of serialization mappings and using one of HATEOAS
bundles in needed.

Feature

Currently the FSCHateoasBundle [17] is used to handle the serialization of Pagerfanta (the paginator) instances. This bundle is more powerful and a more complete
integration and usage ought to be considered. Another
option is the BazingaHateoasBundle [18], a much younger solution which integrates a standalone library into
Symfony2. It seems to have all the features we need,
but both solutions should be considered in order to pick
the best one.

Redesign, documentation and translations


Sylius founder, Pawel J drzejewski, stated that he
is planning on redesigning the Sylius default theme
with the same person who was in charge of creating the new look of the Sylius website. A discussion

Web&PHP Magazine 10.13 | 12

Sylius

on the look is leading among the community in RFC


on GitHub about redesigning [19] that Pawel started
few weeks ago. The starting idea is responsive Bootstrap3[20] with a nice look. Sometimes in the future,
redesigning the administration panel might be in the
spotlight, depending on time and resources. In one of
the RFCs AngularJS was proposed as a possible solution for the backend and there were some talks about
one page web app for backend with a great UX. We
will see what community decide in future.
It is very important to focus on the documentation,
and as mentioned earlier it is not very friendly for
beginners. Also, though the bundles docs are looking rather good, the main application has almost no
guides at all. Good documentation is very important
for a stable release. A few documentation hackdays
are also considered.
Sylius has already been translated into numerous
languages, but most of the translations are incomplete. The process used for translating right now is
not the best possible, and I am already exploring different approaches. An optimal way for resolving this
issue should be found.

Feature freeze and beta


After the above points are finalized, a feature freeze
will happen. This depends on the contributions of the
community. After the feature freeze, the plan is to
focus on stabilization and fixing bugs. A beta release
will ideally happen in December 2013, before the
first SymfonyCon in Warsaw. It is hard to tell how
long it will take to move from the beta to the version
1.0.0. but hopefully not too long.
Conclusion
Sylius is built on solid foundations (Symfony2 as the
enterprise-class PHP framework). It is 100% open
source project, with a high quality and component-

www.webandphp.com

based approach. It is agile and developer-friendly,


and the best thing is that you can override every single part of Syilus in accordance with your projects
requirements. Sylius has a promising future with
great community behind the project and importantly
is continuously developed and improved.
However, at the moment, Sylius is not an ideal solution. It has lack of sophisticated user managament
(CRM) [21] and it is not an out-of-the box solution.
There are numerous bugs and there is no notification
system. Also, lack of documentation is an issue, Sylius does not support signing in with social networks
and payment integration as well as templating solution and promotions with coupons are not yet implemented. Furthermore, it is not for non-developers
and does not have a simple GUI installation. Simply
put, Sylius is still an ecommerce framework, not yet
software like Magento.
Sylius popularity as well as quality is undoubtedly
growing, which comes as no surprise if we consider
its advantages. As with any other project that is still
in its early stages, Sylius has some disadvantages
and flaws, but I am sure that they will be eliminated
sometimes in the near future. Certainly, developers
will continue to develop web shops for their clients
using this particular platform, especially Symfony2
developers.

Feature

[3] http://symfony.com/blog/symfony2-meets-drupal-8
[4] http://en.wikipedia.org/wiki/Behavior-driven_development
[5] https://github.com/pjedrzejewski
[6] http://behat.org/
[7] http://sylius.org/blog/welcome-to-the-new-sylius-org
[8] http://twig.sensiolabs.org/
[9] http://sylius.org/blog/simpler-crud-for-symfony2
[10] https://github.com/Sylius/Sylius/tree/master/src/Sylius/Bundle
[11] https://demo.sylius.org
[12] http://www.twitter.com/Sylius
[13] https://github.com/schmittjoh/JMSPaymentCoreBundle
[14] https://github.com/adrianmacneil/omnipay
[15] https://github.com/payum
[16] https://github.com/FriendsOfSymfony/FOSRestBundle
[17] https://github.com/TheFootballSocialClub/FSCHateoasBundle
[18] https://github.com/willdurand/BazingaHateoasBundle
[19] https://github.com/Sylius/Sylius/issues/287
[20] http://getbootstrap.com/
[21] http://www.ymc.ch/en/sylius-a-great-piece-of-symfony2-for-ecommerce-but-is-it-ready-to-use

Antonio Peri -Maar is CEO at locastic, agency specialized in web


and mobile development and UI/UX. He has more then 6 years of
experience with developing custom web applications and last few
years he is using Symfony2 as everyday tool. At locastic he is responsible for the web applications development, business development and relationships with customers. In his spare time, he is trying to finish
his PhD in Computer Science.

References
[1] www.symfony.com
[2] http://symfony.com/blog/symfony2-meets-ez-publish-5

Web&PHP Magazine 10.13 | 13

Twig Tutorial

Branching out with Twig


Separate your applications logic from its views with the flexible template engine
from the creator of Symfony

Image licensed by Ingram Image

by Aurelio De Rosa

www.webandphp.com

Stand up if youve never used the amazing PHP construct include and/or require to assemble the layout
of a website ... I bet youre all still sat down. Me too.
Using PHP as a template engine is fine and works
well while youre building very small websites with
very few requirements. But what if you need more
flexibility? What about replacing parts of your layout
on demand? What if you want to dynamically include
other parts into the layout? Yes, all of this stuff is
possible with raw PHP too, but why reinvent the
wheel when you can rely on a fast, secure and flexible product?
I am, of course, referring to Twig. In this article Ill
show you what it is and how to use it to simplify your
work.

What is Twig?
Twig [1] is a template engine for PHP that has all the
major features you may need in your projects. It was
created by Fabien Potencier, the developer behind

the Symfony framework and its released under the


new BSD license, so its completely free to use. That
considered, you should not be surprised by the fact
that Twig is the Symfony frameworks template engine of choice. Its requirements are so basic that you
may think it can run everywhere. In fact, Twig only
needs a version of PHP greater than or equal to 5.2.4.
If youve ever used Smarty [2], youll see a lot of similarities and will be able to start using it very quickly.
The library has been built with several optimizations
in mind, specifically performance. When a template is
required, Twig parses it and then outputs the result.
However, you can speed up the whole process by
caching the compiled version in the form of plan PHP
files to reduce the overhead (compared to raw PHP)
to a minimum. In addition, the framework is extensible, meaning that in case something you need is missing, you can create your own language constructs. In
summary, Twig is a reliable, well documented, completely unit tested and mature enough framework
to be safely used in your next project. Now that you
know what Twig is, lets see how you can install it.

Web&PHP Magazine 10.13 | 14

Twig Tutorial

Installing Twig
One of the thing I appreciate is the wide range of possibilities to install Twig. The most common and recommended way is via Composer. The first step is to add it
to your projects dependencies as shown below:
...
require: {
...
twig/twig: 1.*
}
...

and then run the update command:


php composer.phar update

or run this:
php composer.phar install

An alternative method to obtain Twig is via PEAR, typing the following commands:
pear channel-discover pear.twig-project.org
pear install twig/Twig

You can obtain Twig in many other ways but Ill present just another one, the simplest one: downloading
the files from the download page of the project on
GitHub [3]. Grab the last release (1.13.2 at the time
of writing), extract the files from the archive and put
them into your projects folder.

How to create a Twig template


Before delving into the PHP code needed to load and
pass data to your Twig templates, its important to understand how a template is built. The first fact you need

www.webandphp.com

to know is that while Twig templates do not require a


specific file extension, youll usually see the use of .twig.
Many IDEs that have support for Twig will correctly
highlight the syntax of your template (for example PHPStorm) if you use the .twig extension, though. To keep
it as simple as possible, Ill show an example of a HTML
page, but remember that you can use this framework to
output XML as well as other text-based formats.
A template in Twig is composed of variables, expressions and tags. The former are evaluated at the
same time as the template, while the latter give you
tools to control the template (for example using if
and for). The presented components can be used
with two types of delimiters: {% %}, used to execute
statements, and {{ }}, used to print the variable or the
expression contained. Just like every real HTML or
XML page, Twig templates can contain comments
that are written in this way: {# This is your comment
#}. Before we go any further, lets see some examples in Listing1.
The value of the variables were ideally sent by the
PHP page that required the template. In certain situations, you may need to set the value of a variable inside the template itself. To perform this task you can
use the set tag like shown below:
{# Set the value of the variable name #}
{% set name = Aurelio De Rosa %}
{# Print the value #}
{{ name }}

Please note that mixing business logic and views isnt


a good practice. Therefore, you should limit the use
of set to those cases where its strictly required by
a view-only scope. For example, this may be useful
if youre using the I18N internationalisation extension
and want to apply a filter (more on this in a next section) to the string you want to translate.

Listing 1
{# Im a comment and these are some examples #}
{# Evaluates the variable bookTitle and print the result inside an h1 #}
<h1>{{ bookTitle }}</h1>
{# Evaluates the expression composed of the authorName variable and the string

"De Rosa", concatenated by the "~" character #}
<h2>{{ authorName ~ "De Rosa" }}</h2>
{# Evaluates the variable count and change the resulting template accordingly #}
{% if count < 1000 %}
<p>This is a good book</p>
{% else %}
<p>This is a best seller</p>
{% endif %}

In the code above I showed the use of simple variables which can store numbers, strings and similar. In
Twig, as you might expect, you can also deal with array
and objects. To use their values, youve to use a Java
Script-like syntax, therefore you can access a property
using the dot operator (for example obj.prop) or using
the square brackets (for example obj['prop']). Keep in
mind that the previous methods can be used when an
attribute contains a Twigs special characters like the
hyphen, that is interpreted as the minus operator. In
these cases, you have to use the attribute() function
like this: attribute(obj, 'prop')

Tags
So far, youve seen how to use variables and expressions, so its time to delve into the second concept of
Twig templates: tags. As said, they give you control
over the template and how it acts. In the previous examples youve already seen a couple of tags, that is

Web&PHP Magazine 10.13 | 15

Twig Tutorial

set and if. Now, what if you want to print a list of items,
for example a list of ingredients of a recipe? This is
exactly where the for tag comes into play. To perform
this task, you can do something like:
<h1>Ingredients</h1>
<ul>
{% for ingredient in ingredients %}
<li>{{ ingredient }}</li>
{% endfor %}
</ul>

Another key tag is block, which allows you to declare


a named section of your code that can be overridden by a child template in the future. Before showing you an example, its important to introduce the
last two tags Ill explain in this article: include and
extend.
The include tag is used to include a template into
another one just like the PHP include construct. For
example, you can put some meta tags into a file called
meta.twig and then have a larger template called lay
out.twig that includes it. So, in this example the meta.
twig file might look like this:
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" href="/images/favicon.ico" />

This is then included in the layout template shown in


Listing2.
The extend tag is used to inherit from a parent template and, eventually, overrides some blocks. To see it
in action, the best example is to think to a general layout declaration overridden by the template of a specific page. So, lets say you have a layout.twig template
that has the general structure of your website and an
about.twig file that has the code and text of your page.

www.webandphp.com

This is the typical situation where youll use the extend


tag. Lets see an example.
A simple layout file is shown in Listing3. Then you
can have the about page extending the previous code
and injecting the actual content inside the content and
the pageTitle blocks:
{% extend "layout.twig" %}
{% block pageTitle %}About{% endblock %}
{% block content %}
<p>Aurelio De Rosa is an Italian web developer who loves new technologies.</p>
{% endblock %}

The framework has other tags that can help you in


building your templates, but presenting them all is outside the scope of this article. However, you can find
them all in the Twig tags page [4].

Filters
You probably find yourself often modifying variables
in a PHP page using functions for example, escaping HTML characters or converting a sentence to title case. Doing it in the controllers (or in the page
if you arent adopting an MVC pattern) isnt a really
good practice, because if the same controller is used
for other purposes you may need not to apply those
functions. The best place to apply those filters is
in the view and luckily Twig knows this, providing you with a bunch of them. Filters are separated
from the variable by a pipe symbol (|) and may have
optional arguments closed between two brackets.
In addition, you can apply multiple filters by chaining
them. Recalling the example I outlined, this is a snippet that takes a variable called bookTitle, escapes
HTML characters and capitalizes the first letter of
each word:

An example of filter that accepts a parameter is date,


to format a date into a given format. It accepts a
strings that is compliant with the format supported

Listing 2
<!DOCTYPE html>
<html>
<head>
{% include "meta.twig" %}
<!-- asserts here... -->
</head>
<body>
<!-- layout here... -->
</body>
</html>

Listing 3
<!DOCTYPE html>
<html>
<head>
<title>{% block pageTitle %}{% endblock %}</title>
<!-- asserts here... -->
</head>
<body>
<head>
<img src="site-logo.jpg" alt="" />
<h1>Aurelio De Rosas website</h1>
</head>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>

{{ bookTitle|escape|title }}

Web&PHP Magazine 10.13 | 16

Twig Tutorial

by the strtotime() function, a DateTime instance, or


a DateInterval instance. For instance, to display the
current year into a copyright notice you can use the
code shown by the example below:
<p>Copyright Aurelio De Rosa 2010 - {{ "now"|date("Y") }}</p>

Please, note the use of the string "now" to evaluate


the current date and time and the "Y" parameter to
print only the year.
These are just few examples of what you can do. A
list of all the filters available can be found in the Twig
filters page [5].

How to load and show a template


So far, youve seen how to build a layout, but youre
not yet able to use it to show to the user of your website. Before showing you the code, its important to
know a little more about the classes included in the
library. Twig uses a central class called Twig_Envi
ronment where youll set the configuration and add
the extensions of your project. This is also the object youll use to load the templates from the filesystem (or other locations) using the appropriate loader
called Twig_Loader_Filesystem. The Twig_Environ
ment constructor accepts two arguments: the first
is the loader (for example an instance of Twig_Load
er_Filesystem), and the second is an array of options
to configure Twig. Some of the options you can set
are: cache, to set the path where the compiled PHP
files will be stored, auto_reload, a boolean to recompile the template whenever the source code changes,
and strict_variables, a boolean to ignore invalid or not
existent variables, attributes, and methods, replacing
them with a null value.
Now that you have an idea of how you can initialize
Twig, lets see some code. The first thing to do to use
its classes, is to load the library. If you installed Twig

www.webandphp.com

via Composer as suggested in the introduction, this is


done using this simple line of code:
require_once '/vendor/autoload.php';
$twig = new Twig_Environment(
new Twig_Loader_Filesystem('templates/'), array(
'cache' => 'cache/twig/',
'auto_reload' => true,
'strict_variables' => true
)
);

The last step is to load the template and then render


it, passing in the required variables. To load a template you have to call the loadTemplate() method and
pass the path of the template as a parameter. This
method returns a Twig_Template instance that you
can use to call the render() method, which accepts as
a parameter an array containing a set of key-values.
In this array, the keys have the same names as those
used in your template and the values, are, well ... the
values to display. Heres an example of those classes
in action:
$template = $twig->loadTemplate('about.twig');
echo $template->render(array('bookTitle' => 'Instant jQuery Selectors', 'bookAuthor'

=> 'Aurelio De Rosa'));

You can also pass two parameters to the render()


method to load the template and pass the variables in
one line of code, as shown below:
echo $twig->render('about.twig', array('bookTitle' => 'Instant jQuery Selectors',

'bookAuthor' => 'Aurelio De Rosa'));

$twig->display('about.twig', array('bookTitle' => 'Instant jQuery Selectors',



'bookAuthor' => 'Aurelio De Rosa'));

The framework has a lot of other classes and methods


not covered here which you can study in the official documentation [6]. However, with the examples described
in this section youre able to start using it right now.

Conclusions
In this article we discovered what Twig is and its basic components. Throughout it, we uncovered the key
features of the framework, like variables, tags, and
filters, and also studied several examples that should
help using it easily in your next projects. Keep in mind
that the library has also some important extensions not
described here, like the I18N and Intl, which are very
useful if youre developing a multilingual project. With
this last hint, the article is over. I hope you enjoyed it
and that thanks to it youll consider using Twig or another of the available template frameworks.
Aurelio De Rosa is an Italian web and app developer with more than
5 years experience programming for the web using HTML5, CSS3,
JavaScript and PHP. He mainly uses the LAMP stack and frameworks
like jQuery, jQuery Mobile, and Cordova (PhoneGap) but his interests
also include web security, web accessibility, SEO, WordPress and
everything he can put his hands on. In the little spare time left, he contributes
to the open source community writing libraries for PHP as well as jQuery plug
ins. Currently hes self-employed working with the cited technologies. Hes also
a regular blogger for several networks (SitePoint, Tuts+, FlippinAwesome) where
he writes articles about the topics he usually works with and more.

References
[1] http://twig.sensiolabs.org/
[2] http://www.smarty.net/
[3] https://github.com/fabpot/Twig/tags

Alternatively, you can also use the display() method,


that acts as a shortcut for echo $twig->render(...);, to
output the template directly, like so:

[4] http://twig.sensiolabs.org/doc/tags/index.html
[5] http://twig.sensiolabs.org/doc/filters/index.html
[6] http://twig.sensiolabs.org/documentation

Web&PHP Magazine 10.13 | 17

MySQL Query Tuning Tutorial

Every second counts

Advanced MySQL Query Tuning


A closer look at query optimization with a focus on queries with GROUP BY and ORDER BY

Table for the tests


I will use a couple of tables for the tests. The first table
we will use to illustrate is explained in Listing1. This
table is the part of MySQL world test db and can be
downloaded from [2].

Indexes
In this article we will focus on the b-tree indexes only
(InnoDB and MyISAM only support B-tree indexes). Figure1 illustrates a basic b-tree index [1] implementation.

B-tree supports both equality (where id = 1) and


range (where date > 2013-01-01 and date < 2013-0701) search. Figures2 and 3 show examples of these,
illustrated.
Figure 2 is of an equality search with primary or
unique key: select select * from table where id = 12.
In this scenario MySQL will be able to scan through
the tree and go directly to 1 leaf and then stop. That is
usually the fastest index scan operation.
In InnoDB primary key searches is even faster as InnoDB clusters records around primary key. Range:
select * from table where id in (6, 12, 18).
In this scenario MySQL will need to scan thru the
tree and visit many leafs/nodes

Figure 1: A basic B-tree index

Figure 2: An equality search with primary or unique key

Figure 3: An equality search with multiple keys

by Alexander Rubin

In this article we will talk about query optimization


with the focus on the queries with GROUP BY and
ORDER BY. We will start with the basic concepts (Indexes, Explain plan in MySQL etc) and then will talk
about the advanced query optimization techniques.
We will cover loose index scan and tight index
scan optimizations and show the benchmark results.

www.webandphp.com

Explain plan
The main way to profile a query with MySQL is to
use explain [3]. Listing2 shows an example. As we
can see from the explain, MySQL does not use any
indexes (key: NULL) and will have to perform a full
table scan.
In this case we can add an index to restrict the number of rows:

Web&PHP Magazine 10.13 | 18

MySQL Query Tuning Tutorial

mysql> alter table City add key (Name);


Query OK, 4079 rows affected (0.02 sec)
Records: 4079 Duplicates: 0 Warnings: 0

The new explain in Listing3 shows that MySQL will use


an index.

Index usages
MySQL will choose only 1 index per query (and per
table if the query joins multiple tables). In some cases

Listing 1
CREATE TABLE City (
ID int(11) NOT NULL AUTO_INCREMENT,
Name char(35) NOT NULL DEFAULT '',
CountryCode char(3) NOT NULL DEFAULT '',
District char(20) NOT NULL DEFAULT'',
Population int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (ID),
KEY CountryCode (CountryCode)
) Engine=InnoDB;

Listing 2
mysql> EXPLAIN select * from City where Name = 'London'\G
*************************** 1. row
id: 1
select_type: SIMPLE
table: City
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4079
Extra: Using where

www.webandphp.com

MySQL can also intersect indexes, however we will


not cover it in this article. MySQL uses index statistics
to make a decision about the best possible index.

Combined Indexes
Combined indexes are very important for MySQL query
optimizations. MySQL can use leftmost part of any index.
For example, if we have this index: Comb(CountryCode,
District, Population). Then MySQL can use:
CountryCode only part
CountryCode + District
CountryCode + District + Population
From the explain plan in Listing 4 we can understand
which part(s) will be used. Note the key_len part
it shows: 3. This is the number of bytes used from
our index. As the CountryCode field is declared as
char(3), that means that MySQL will use the first
field from our combined index.
Similarly, MySQL can use 2 leftmost fields or all 3
fields from the index. In Listing5, the 2 leftmost fields

Listing 3
mysql> explain select * from City where Name = 'London'\G
*********************** 1. row ***************************
id: 1
select_type: SIMPLE
table: City
type: ref
possible_keys: Name
key: Name
key_len: 35
ref: const
rows: 1
Extra: Using where

are used, so MySQL will use 2 first fields from the


comb key:
CountryCode = 3 chars
District = 20 chars
Total = 23
In Listing6, all 3 fields from the index:
CountryCode = 3 chars/bytes
District = 20 chars/bytes
Population = 4 bytes (INT)
Total = 27
However, if the query does not have the first leftmost
part of an index, MySQL will not be able to use it (Listing7). As we do not have the CountryCode in the where
clause, MySQL will not be able to use our comb index.

Covered index
The covered index is an index that covers all fields in
the query. For example, for this query:

Listing 4
mysql> explain select * from City
where CountryCode = 'USA'\G
********************** 1. row ******************
table: City
type: ref
possible_keys: comb
key: comb
key_len: 3
ref: const
rows: 273

Web&PHP Magazine 10.13 | 19

MySQL Query Tuning Tutorial

select name from City where CountryCode = 'USA' and District = 'Alaska' and

population > 10000

the following index will be a covered index:


cov1(CountryCode, District, population, name)

The above index uses all fields in the query in particular


order:

Figure 4: (district, population) index scan

Listing 5
mysql> explain select * from City
where CountryCode = 'USA' and District = 'California'\G
********************** 1. row ******************
table: City
type: ref
possible_keys: comb
key: comb
key_len: 23
ref: const,const
rows: 68

Listing 6
mysql> explain select * from City
where CountryCode = 'USA' and District = 'California'
and population > 10000\G
********************** 1. row ******************
table: City
type: range
possible_keys: comb
key: comb
key_len: 27
ref: NULL
rows: 68

www.webandphp.com

Figure 5: (population, district) index scan

Listing 7
mysql> explain select * from City where
District = 'California' and population > 10000\G
********************** 1. row ******************
table: City
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 3868

Listing 8
mysql> explain select name from City where CountryCode = 'USA' and District =

'Alaska' and population > 10000\G
*************************** 1. row ***********
table: City
type: range
possible_keys: cov1
key: cov1
key_len: 27
ref: NULL
rows: 1
Extra: Using where; Using index

1. Where part
2. Group By/Order (not used now)
3. Select part (here: name)
You can see an example of this in Listing8. Using index in the extra field of the explain output means that
MySQL will use our covered index. That also means
that MySQL will use an index only to satisfy the query:
all the information that MySQL needs is in the index.
That is usually much faster, especially if we have a
large text or blob fields in the table.

Order of the fields in index


The order of the fields in the index is very important.
The way b-tree works, it is more beneficial to have a
field which will be used for equality comparison first
and the fields with range (more than and less than comparison) second. For example, take the following query:
select * from City where district = 'California' and population > 30000

The best Index will be on (district, population), in this


particular order:
1. (district, population) index (Figure4): In this
case MySQL will be able to go directly (via index scan) to the correct district (CA) and do a
range scan by population. All other nodes for the

Web&PHP Magazine 10.13 | 20

MySQL Query Tuning Tutorial

Listing 9
mysql> explain select name from City where CountryCode = 'USA' and District =

'Alaska' and population > 10000\G
*************************** 1. row ***********
table: City
type: range
possible_keys: cov1
key: cov1
key_len: 27
ref: NULL
rows: 1
Extra: Using where; Using index

Listing 10
...
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4833086
Extra: Using where; Using temporary; Using filesort

Listing 11
mysql> explain select name from City where CountryCode = 'USA' and District =

'Alaska' and population > 10000\G
*************************** 1. row ***********
table: City
type: range
possible_keys: cov1
key: cov1
key_len: 27
ref: NULL
rows: 1
Extra: Using where; Using index

www.webandphp.com

district field (other US states in this example)


will not be scanned.
2. (population, district) index (Figure5): In this
example, MySQL will have to do a range scan for
the population and for each index record it will
have to check for the correct district, which will
be slower.

Complex Slow Queries


In this article we will be concentrating on 2 major
query types:
Queries with group by
Queries with order by
Those queries are usually the slowest ones. We will
show how to optimize those queries and decrease the
query response time as well as the application performance in general.

Group by example
Lets look at this simple example, a query of how
many cities there are in each country. As we can see
from Listing9, MySQL does not use any indexes (no
proper indexes are available), but it also shows Using temporary; Using filesort. MySQL will need to
create a temporary table to satisfy the Group by
clause if there is no appropriate index (You can find
more information about the temporary tables at [4]).
However, MySQL can use a combined index to satisfy the group by clause and avoid creating temporary table.
Group by and covered index
To illustrate the group by queries I will use the following table:

CREATE TABLE ontime_2012 (


YearD int(11) DEFAULT NULL,
MonthD tinyint(4) DEFAULT NULL,
DayofMonth tinyint(4) DEFAULT NULL,
DayOfWeek tinyint(4) DEFAULT NULL,
Carrier char(2) DEFAULT NULL,
Origin char(5) DEFAULT NULL,
DepDelayMinutes int(11) DEFAULT NULL,
...
) ENGINE=InnoDB DEFAULT CHARSET=latin1

The table contains freely available airline performance


statistics [5]. The table is 6 million rows and approximately 2GB in size. From this data we want to:
Find maximum delay for flights on Sunday
Group by airline
Our example query is:
select max(DepDelayMinutes),
carrier, dayofweek

Listing 12
mysql> alter table ontime_2012
add key covered(dayofweek, Carrier, DepDelayMinutes);
explain select max(DepDelayMinutes), Carrier, dayofweek from ontime_2012 where

dayofweek =7 group by Carrier\G
...
possible_keys: DayOfWeek,covered
key: covered
key_len: 2
ref: const
rows: 905138
Extra: Using where; Using index

Web&PHP Magazine 10.13 | 21

MySQL Query Tuning Tutorial

Listing 13
mysql> explain select max(DepDelayMinutes), Carrier, dayofweek from ontime_2012
where dayofweek > 5 group by Carrier, dayofweek\G
...
type: range
possible_keys: covered
key: covered
key_len: 2
ref: NULL
rows: 2441781
Extra: Using where; Using index; Using temporary; Using filesort

Listing 14
(select max(DepDelayMinutes), Carrier, dayofweek
from ontime_2012
where dayofweek = 6
group by Carrier, dayofweek)
union
(select max(DepDelayMinutes), Carrier, dayofweek
from ontime_2012
where dayofweek = 7
group by Carrier, dayofweek)

from ontime_2012
where dayofweek = 7
group by Carrier

The explain plan is in Listing 10. As we can see,


MySQL does not use any index and have to scan
~4M rows. In addition, it will have to create a large
temporary table.
If we will create an index on dayofweek it will
only filter out some rows and MySQL will still need
to create a temporary table (Listing11).
However, we can create a covered index on (dayofweek, Carrier, DepDelayMinutes) in this particular
order. In this case MySQL will be able to use this index and avoid creating a temporary table (Listing12).
As we can see from the explain, MySQL will use our
index and will avoid creating a temporary table. This is
the fastest possible solution.
Note that MySQL will also be able to use noncovered index on (dayofweek, Carrier) and avoid
creating a temporary table. However, covered index
will be faster as MySQL will be able to satisfy the
whole query by just reading the index.

Listing 15
*************************** 1. row ***************************
table: ontime_2012
key: covered
...
Extra: Using where; Using index
*************************** 2. row ***************************
table: ontime_2012
key: covered
...
Extra: Using where; Using index
*************************** 3. row ***************************

www.webandphp.com

Group by and a range scan


The covered index works well if we have a const
(where dayofweek=N). However, MySQL will not be
able to use an index and avoid a filesort if we have a
range scan in the where clause. Listing13 shows
an example.
MySQL will still have to create a temporary table.
To fix that we can use a simple trick and rewrite the
query into 2 parts with UNION (Listing14). For each
of the 2 queries in the union MySQL will be able to
use an index instead of creating a temporary table, as
shown in the explain plan in Listing15.
As we can see, MySQL uses our covered index for
each of the 2 queries. It will still have to create a temporary table to merge the results, however, it will probably be much smaller temporary table as it will only
need to store the resultsets of 2 queries.
Group by and a loose index scan
Loose index scan is another MySQL algorithm to optimise Group By queries. Loose index scan considers
only a fraction of the keys in an index and is very fast.
The following limitations apply:

Listing 16
id: NULL
select_type: UNION RESULT
table: <union1,2>
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: Using temporary

mysql> explain select max(DepDelayMinutes) as ddm, Carrier, dayofweek from



ontime_2012 where dayofweek = 5 group by Carrier, dayofweek
table: ontime_2012
type: range
possible_keys: covered
key: loose_index_scan
key_len: 5
ref: NULL
rows: 201
Extra: Using where; Using index for group-by

Web&PHP Magazine 10.13 | 22

MySQL Query Tuning Tutorial

Note that loose_index_scan is only a name of the index,


it can be any name. You can see an example in Listing16. Using index for group-by in the where clause
means that MySQL will use the loose index scan. Loose
index scan is very fast as it only scans a fraction of the
key. It will also work with the range scan (Listing17).

Figure 6: Speed of queries with temporary table, tight index scan (covered index)
and loose index scan

The query is over a single table.


The GROUP BY names only columns that form a
leftmost prefix of the index and no other columns.
The only aggregate functions used in the select list
(if any) are MIN() and MAX(), same column
More information can be found in MySQL documentation on Loose Index Scan [6]. For loose index scan
to work we will need to create an additional index
and start with columns in the Group by clause and
then all fields in the where clause (order of the
fields in the index matters!). For example, for our
query:
select max(DepDelayMinutes) as ddm, Carrier, dayofweek from ontime_2012 where

dayofweek = 5 group by Carrier, dayofweek

we will need to create this index:


KEY loose_index_scan (Carrier,DayOfWeek,DepDelayMinutes)

www.webandphp.com

Benchmark
We have performed a benchmark to compare query
speed with a temporary table, a tight index scan (covered index) and a loose index scan. The table is 6 million rows and approximately 2GB in size.
The results are shown in Figure6. As we can see,
loose index scan index shows the best performance.
Unfortunately, loose index scan only works with 2 aggregate functions, min and max for the group by. AVG
+ group by does not work with loose index scan. As we
can see in Listing16, MySQL will use a covered index
(not loose_index_scan index) and, because we have a
range in the where clause (dayofweek > 5), it will have
to create a temporary table.
ORDER BY and filesort
MySQL may have to perform a filesort operation when
a query uses the order by clause. You can find more
information about filesort at [7].
The filesort operation in Listing19 is usually pretty
slow operation (even if it does not involve creating a
file on disk), especially if MySQL will have to sort a lots
of rows.
To optimize this query we can use a combined index
(Listing 20). MySQL was able to use our combined
index to avoid sorting: as the index is sorted, MySQL
was able to read the index leafs in the correct order.
Sorting and limit
If we have a LIMIT clause in our query (and the
limit is relatively small (i. e. LIMIT 10 or LIMIT 100)

compared to the amount of rows in the table), MySQL


can avoid using a filesort and can utilize index instead.
Heres an example:
mysql> alter table ontime_2012 add key (DepDelayMinutes);

We can create an index on DepDelayMinutes fields


only and run the explain in Listing21 (note the query
with LIMIT 10). As we can see, MySQL uses index on

Listing 17
mysql> explain select max(DepDelayMinutes) as ddm, Carrier, dayofweek from
ontime_2012
where dayofweek > 5 group by Carrier, dayofweek;
table: ontime_2012
type: range
possible_keys: covered
key: loose_index_scan
key_len: 5
ref: NULL
rows: 213
Extra: Using where; Using index for group-by;

Listing 18
mysql> explain select avg(DepDelayMinutes) as ddm, Carrier, dayofweek from

ontime_2012 where dayofweek >5 group by Carrier, dayofweek \G
table: ontime_2012
type: range
key: covered
key_len: 2
ref: NULL
rows: 2961617
Extra: Using where; Using index; Using temporary; Using filesort

Web&PHP Magazine 10.13 | 23

MySQL Query Tuning Tutorial

DepDelayMinutes only. Here is how it works. As Index


is sorted, MySQL can:
1. Scan the whole table in the order of the index
2. Filter results (using the where clause condition, but
not using the index)
3. Stop after finding 10 rows matching the where
condition

Listing 19
table: City
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4079
Extra: Using where; Using filesort

Listing 20
mysql> alter table City
add key my_sort2 (CountryCode, population);
mysql> explain select district, name, population from City where CountryCode =

USA order by population desc limit 10\G
table: City
type: ref
key: my_sort2
key_len: 3
ref: const
rows: 207
Extra: Using where

This can be very fast if MySQL finds the rows right


away. For example, if there are a lots of rows matching
our condition (dayofweek in (6,7)), MySQL will find 10
rows fast. However, if there are no rows matching our
condition (i.e. empty result set, all rows filtered out),
MySQL will have to scan the whole table using an index scan. If we have 2 indexes, a covered index and an
index on the ORDER BY field only, MySQL usually is
able to figure out the best possible index to use. Using
ORDER BY + limit optimization can help optimize
your queries.

Conclusion
We have discussed different indexing strategies to optimize your slow queries:

Order by optimizations can be done with covered


index and with the order by+limit index technique, described above.
Now you can look again into your MySQL slow query
log and optimize more slow queries.

Alexander Rubin is a Principal Consultant for Percona, a provider of


enterprise-grade MySQL Support, Consulting, Training, Remote DBA,
and Server Development services. Alexander helps organizations of
all sizes design large, scalable and highly available MySQL systems
and optimize MySQL performance as well as Big Data solutions.

Covered index is a great MySQL feature and, in


most cases, can increase MySQL performance
significantly.
Some queries may also be optimized with a separate
index which will enable loose index scan algorithm.

Listing 21
mysql> explain select * from ontime_2012
where dayofweek in (6,7) order by DepDelayMinutes desc
limit 10\G
type: index
possible_keys: DayOfWeek,covered
key: DepDelayMinutes
key_len: 5
ref: NULL
rows: 24
Extra: Using where

References
[1] http://en.wikipedia.org/wiki/B-tree
[2] http://dev.mysql.com/doc/index-other.html
[3] http://dev.mysql.com/doc/refman/5.5/en/explain.html
[4] http://dev.mysql.com/doc/refman/5.5/en/internal-temporary-tables.html
[5] http://www.transtats.bts.gov/DL_SelectFields.asp?Table_ID=236&DB_
Short_Name=On-Time
[6] http://dev.mysql.com/doc/refman/5.5/en/loose-index-scan.html
[7] http://dev.mysql.com/doc/refman/5.5/en/order-by-optimization.html

www.webandphp.com

Web&PHP Magazine 10.13 | 24

OSS Column

Creating business
tools in cyberspace?
Think Different!
by Ben Greenaway

Ben Greenaway discusses the open


source software and sustainable business
movements and argues that an overly simplified
cloud on-ramp would be a mistake.
Over the past few weeks I have been giving a series of
workshops and talks for Impact Hub, Kings Cross. This
collaborative, shared workspace is a member of the
international Impact Hub Association and populated by
smart and sustainable social businesses. Their members are entrepreneurs and freelancers who make regular use of in-the-cloud Software as a Service tools like
SurveyMonkey, MailChimp and others. The workshop
I gave focused on WordPress and HTML skills training, yet a discussion of Software as a Service tools
developed and brought with it a renewal of some most
deeply treasured ideals.

www.webandphp.com

It may not be obvious why, but I consider WordPress as belonging to these Software as a Service
offerings. Im sure you are familiar with it as a free
and open source blogging tool, and to many small
business owners it is also an essential piece of
their communications and relationship management
strategy. Modern business requires good customer
service, sales require brand awareness and marketing campaigns need mass distribution all of which
have significant social networking components
these days. Its hard to look like a modern business
without one.

If you look to see how it is deployed you can see a


blurring of WordPresss open source project status
with that of a commercial business concern, in line
with the way SaaS offerings are delivered. WordPress and similarly Drupal offer themselves as hosted service options on Wordpress.com and Acquia.
com. Each routinely restrict their functionality and
the extensibility of their parent open source projects,
but each too offer the low-overhead and savings of
an in-the-cloud IT solution. Then, as centrally hosted
business applications, they rightly deserve to be considered Software as a Service and often become the
starting point of a small businesss online migration.
Business tools delivered through the World Wide
Web are nothing new. Where there is a market for
these services, a business case for them can be made.
The SaaS case can be made quite strongly it opens up
IT to many companies who otherwise may not afford

Bio
Ben Greenaway has been a software developer
for 18 years. After pioneering internet narrowcasting in the 90s in collaboration with Virtual
Futures he has led development on A/V installation projects for Pixar and Sony Entertainment
and web applications for SMEs in Southern
California before moving to the San Francisco
Bay in 2010 and developing performance solutions for Dyn DNS and e-commerce APIs for
Tzolkin TZO. He now lives in South London
where he balances time writing and developing
with the demands of an ever growing collection
of retro computers.

Web&PHP Magazine 10.13 | 25

OSS Column

it. The additional benefit of being a commute-killing,


low carbon-footprint option for the sustainable-minded
start-ups makes such technologies appear harbingers
of a new age of business. And it would be foolish to
think that companies will go out and learn to develop
code in addition to a customer base, advertising channels and working processes so we can be sure that
use of these tools will grow.
The story of the Internets arrival is also the story of
the open source software movements greatest success. As you probably know, the movements aim has
been to offer universal access to softwares source
code without prejudice to its use, modification or redistribution. It has proven that the development of new
software can be a collaborative and distributed process, saving time, money, and the duplication of effort,
all the while educating and informing a broader public
of the technologys mechanisms. Treating users as codevelopers has worked, and still works brilliantly. In
the webs case, it has been the single most important
way for all the innovation to get in, as innovation does,
through edge-cases and by riding on the backs of Black
Swans. And it is that self same flexibility and capacity
to concurrently include multiple agendas which has allowed our open source projects to grow.
We could not have possibly done it without them.
Just to download open source software is to receive
some practical training in the way your computer or
server works. A simplified and passive education it
may be, many games developers have nonetheless
emerged from the modding scene to create studios
and their own titles and many more HTML developers have emerged from personal page creation to become the heads of development organizations all in
the short space of a decade.
So if throwing away the more defensive and protective ideologies in our own industry has been for the
best from the draining of the Waterfall to sharing the

secrets of our sauce would it not do some good in


others? True, there are many challenges beyond the
coordination and control of corporate infrastructure,
and open source has become a moniker of social
movement and change akin to transparency there.
But in the practical software application space, open
sources home turf, it is disseminating itself in the form
of SaaS offerings to eager, needy alternative minded
startups missing its most vital of components. To me,
this appears to abuse the success of our flexibility
and growth, short-changing a customer we should far
more strongly support. It strikes me as perverse that
we are giving such a bad representation of ourselves.
And the sad truth is that they cant even notice it.
The open source story is somewhat counter-intuitive
and poorly communicated outside of our industry;
you wouldnt guess what I have been discussing here
and there exist few analogies to it in everyday life.
Pop quiz: which scene in The Social Network is filled
with product placement for the open source project
Mark Zuckerburg used to germinate the Facebook
mega-corp? You cant remember can you ? (spoiler:
there wasnt one!) Sustainable, social businesses and
free and open source software sectors should, in my
mind, have recognized far more common ground by
now. They should have collaborated on many great,
customized workflow products and flexible business
managers but they havent. It worries me that any further flexibility or capacity to act in the current tools will
be hard to come by.
Sustainable small business industry wants great
tools, and, I think, we all need great, sustainable small
businesses. We could be champions of their ideals
something I was astonished not to be already, and as I
finished my workshops I left with new questions: How
should we progress to re-tool an alternative to the corporate world? And what would an open sourcing of
business be like?

Available

now for

$ 3.99
Buy now at:

www.developerpress.com
Also available to buy on:

www.webandphp.com

Web&PHP Magazine 10.13 | 26

OSS Column

www.webandphp.com

Web&PHP Magazine 10.13 | 27

Security Column

Security holes?
Who cares?
by Arne Blankerts, thePHP.cc, Germany

To err is human, but to ignore the


warnings of independent security
researchers is just downright silly,
writes Arne Blankerts.

for reports of security relevant issues. But have you


ever tried reporting such a problem?
What happened to two security researchers in Germany when contacting PayPal about a problem they
discovered feels rather odd, yet typical: Thank you
for your time but no, that is not a problem, everything is fine. Quite comparable to how the security
team at Facebook replied to some other white-hat
hacker when he was pointing out a security relevant
problem. That hacker though, not willing to give in,
chose to demonstrate the problem in a drastic fashion: He wrote a post to Mark Zuckerbergs personal
wall, which should not have been possible [1]. That
at least got the attention the problem deserved and
the bug got fixed. Facebook though refused to pay
the bug bounty but instead banned the hacker for
violating the terms of service.
The two hackers talking to PayPal chose not to remain silent either, but refrained from any drastic actions. Finally, after three months of arguing, PayPal
acknowledged and fixed the problem. They also paid
the bug bounty without any complaints [2].
The experiences these hackers had when talking
to a big enterprise strongly remind my of my own

Bio
Every now and then, things go wrong. This is how
life is and there is probably nothing we can really do
about it. On the other hand, we automate more and
more things, have computers and machines take
over to reduce the potential of humans making mistakes. Happily ignoring the fact all those machines
are built and programmed by humans, we blindly
trust the device at hand. And if things go wrong anyway, its not a human mistake but a computer glitch.

www.webandphp.com

Just as if the computer has a bad day, did not sleep


well last night or is hung over.
Luckily, more and more companies seem to realize that, even given their best effort, their software
may not be as free of bugs and security issues as
they wish. And following up on that notion, they offer a dedicated email address or web form to contact
them in case of bugs or security problems. Some go
even as far as offering money called bug bounty

Arne Blankerts consults for thePHP.cc, solving IT problems long before many companies
realize that they even exist. IT security is his
passion, which he pursues with almost magical intuition, creating solutions that always
bear his hallmark. Companies around the
world rely on his concepts and Linux-based
system architectures.

Web&PHP Magazine 10.13 | 28

Security Column

attempts of reporting security relevant problems. If


I actually found a way to contact their technical staff
and not just marketing or sales people, I either got
ignored, was told that there is no problem or eventually got threatened to get sued for hacking into their
computer systems.

The technical aspects of the


problems reported to PayPal
and Facebook are hardly new.

The risk of being sued seems to grow quite a bit


when the company in question has a lot to loose or
the problem is too big (read: potentially expensive).
A team of researchers for instance found a way to
circumvent the immobilizer of Volkswagen cars and,
before they could publicly speak about it, got sued to
remain silent [3].
But of course it does not always have to be that
bad. One company I reported a security problem to
some years ago initially refused to admit the issue,
but changed their minds only a few minutes after
asking me whether I would be up to the challenge
and prove it to them. They even went the extra mile
of providing me with a test database I should run the
exploit against. Conceiving a working SQL injection
to fetch the information stored in that database took
only a few minutes given that they already provided
me with details like database and table names, it was
hardly a complicated task. So much for a challenge.
I convinced the developers and together we fixed
those pressing issues on their website.

www.webandphp.com

Looking at the issues I reported in the past, as well


as what the other researchers reported to PayPal and
Facebook, the technical aspect of the problems is
hardly new. Or complex, for that matter. They actually are quite standard and consist of common mistakes that are well documented. This makes me sad,
given that the Sans Institute released a list of the
top 25 most dangerous yet common programming
mistakes in website development [4] as early as in
January 2009: Cross site scripting, SQL injections,
mail header injections, cross site request forgery
you name it.
But of course web security does not stop at the
development level and so the recently-updated Top
Ten list provided by the OWASP (open web application security project) adds additional aspects and
common mistakes to the mix [5]. The list, available
since 2004 and updated from time to time, contains
common flaws in maintaining a safe environment,
mistakes when implementing or using cryptographic
algorithms and of course the all time favorites like
XSS and other injection bugs.

Too often, software keeps


being developed with the
happy path in mind.

while that makes perfect sense for a list sorted by


risk or potential damage, the fact that the lists sorted
by prevalence hardly change (sadly) seems to indicate that people fail to learn. Too often, software
keeps being developed with the happy path in mind,
ignoring all the potential issues and unhandled conditions which lead to random features.
So let us for the sake of a safe browsing experience hope that the white-hat hackers keep up with
their good work, despite the hard time many companies give them. After all, those hackers seem to be
the only ones who really care, and try to help companies to make their software better.

References
[1] http://venturebeat.com/2013/08/18/facebook-zuckerberg-wallvulnerability/

When comparing the various versions and iterations of said lists, one thing stands out: Even if the
order of the items changes, there seems to be hardly
any real change in terms of content. The standard
mistakes keep being ranked high in all lists. And

[2] http://www.vulnerability-lab.com/dev/index.php/2013/04/29/5000-paypalbug-bounty-auth-bypass-vulnerability/
[3] http://www.telegraph.co.uk/finance/newsbysector/industry/10211760/
Volkswagen-sues-UK-university-after-it-hacked-sports-cars.html
[4] http://www.sans.org/top25-software-errors/
[5] https://www.owasp.org/index.php/Top_10_2013-Top_10

Web&PHP Magazine 10.13 | 29

Percona Live Event

MySQL and more in the UKs capital

by

Conference preview:
Percona Live London

Book your ticket to hear from the likes of MySQL and MariaDB creator Monty
Widenius and VP MySQL Engineering Tomas Ulin on November 1112, 2013

by Terry Erisman, Chief Marketing Officer, Percona

According to one attendee [1], last years Percona Live


MySQL Conference in London [2] was even more interesting than the first edition, and I had great fun discussing all the techie stuff with the right people. The
attendees enjoyed a wide range of excellent speakers,
including keynotes from Monty Widenius from Monty
Program Ab, Robert Hodges from Continuent, Frank
Terburg from Clustrix, and Peter Zaitsev of Percona,
as well as engaging tutorials and highly rated breakout
sessions.
This years Percona Live MySQL Conference in London is shaping up to be even better. We are especially
excited by the participation of Oracle representatives

www.webandphp.com

this year providing a keynote, participating on the


Conference Committee, and delivering breakout session talks.
Conference sessions will dive into the major variants of MySQL MySQL 5.6, Percona Server 5.6,
and MariaDB 10 and MySQL-related technologies.
The keynote speakers will address the MySQL variants and related technologies during their talks, including:
Tomas Ulin, Vice President, MySQL Engineering
at Oracle, will discuss the focus, strategy, investments and innovations that are preparing MySQL
to power next-generation web, mobile, cloud and
embedded applications. He will also discuss the

f ticketsof!
o
r
i
a
p
a
air
Win
ill win a p

w
n
y reader
t. Send a
One luck
er's even
b
m
e
v
m
o
o
N
andphp.c
tickets to
tb@web
io
na Live
ll
o
e
rc
e
to
P
"
il
ema
) titled
5
1
r
e
b
to
, Oc
e to win.
(by 11pm
ur chanc
o
y
r
fo
"
tion
Competi

latest and the most significant MySQL database


release, MySQL 5.6, as well as what is ahead in
MySQL 5.7.
Monty Widenius, CTO of the MariaDB Foundation,
will provide a walkthrough of the new features in
MariaDB 5.5 and share details on things like why
the Foundation chose to create MariaDB 10.0 instead of simply taking MySQL 5.6 as a base for
creating what would have been called MariaDB 5.6.
Robert Hodges, CEO of Continuent, will deliver a
keynote in which he will make it clear that What
You Dont Know Can Hurt You as he explores the
real risks of managing data in the cloud and explains how cloud data managers using MySQL can
build more robust systems.

Web & PHP Magazine 10.13 | 30

Percona Live Event

Peter Zaitsev, CEO & co-founder of Percona, will


give a keynote on the continuing evolution of the
MySQL ecosystem in an era of increasing demands
for performance and rising reliance on the cloud.
He will also address the growing phenomenon of
organizations using MySQL with NoSQL solutions
such as Hadoop, MongoDB, and Redis to address
Big Data challenges.
This years Conference Committee [3] consists of
highly engaged and experienced professionals who
are developing an exciting agenda that will include a
focus on real-world customer stories that demonstrate
a range of problem-solving use cases for MySQL. The
committee members are:
Cedric Peintre, Conference Chairman and DBA,
Dailymotion
Todd Farmer, Director of Technical Product Management, Oracle
Ivan Zoratti, CTO, SkySQL Ab
David Busby, Remote DBA, Percona
Kenny Gryp, Principal Consultant, Percona
Ben Mildren, Remote DBA, Percona
While all the conference talks will be informative
and engaging, most attendees will find the tutorials
particularly valuable. The tutorials will present immediate and practical guidance based on an in-depth
knowledge of MySQL. Tutorials are a cross between
a training class and a conference breakout session,
which makes them highly accessible, interesting and
relevant. The conference tracks currently being developed include Developing Applications, Database
Administration, Trends in Architecture and Design,
Tools, Utilizing Hardware, New Features, Best Practices for Businesses, Replication, and High Availability Strategies.

www.webandphp.com

One of the highly anticipated events at Percona Live


London is the Community Networking Reception that
follows the conference on Tuesday, November 12.
Featuring delectable food and tantalizing drinks, the reception offers an excellent opportunity for attendees to
mingle, make new friends, and develop future plans.

The Value of Percona Live MySQL Conference, London


Attending Percona Live London provides attendees
with a unique opportunity to connect with European
MySQL users and vendors. The attendees at Percona
Live London 2012 were a diverse and very interesting
group. A little over half of them were from the United
Kingdom and about a third were from other parts of
Europe, including Finland, The Netherlands, France,
Germany, Italy, Sweden, Austria, Lebanon, Russia,
and Malta. Other nations represented included Estonia, Turkey, Lithuania, and Malaysia. And this diversity
of geography was matched by diversity in company

size. About a third of the attendees came from companies with fewer than 50 employees, and about a
fifth from companies with more than 501 employees.
The vertical focus of the represented companies also
covered a wide range, including software, telecommunications, e-commerce, media, retail, entertainment,
mobile technology, education, hospitality, social networking, biotechnology, and healthcare.
While the Percona Live MySQL Conference in London is a chance to play an active role in a growing community of professionals, it also offers specific benefits
for three groups of attendees.
For MySQL professionals in Europe, the conference
is the best opportunity to connect with customers,
partners, and other stakeholders in the MySQL ecosystem. Because most of our day-to-day contact may
be online, the conference can be a great opportunity to
meet face-to-face, nurture relationships, and explore
the possibility of future collaboration.

Web&PHP Magazine 10.13 | 31

Percona Live Event

For MySQL Community members, the conference


is a terrific way to reignite their passion for the technology. After every Percona Live conference I feel
extremely lucky to be part of such a smart, innovative Community, and it always leaves me excited
about the future. The conference is also a potential
way to be discovered by professionals and perhaps
create new career opportunities. Sharing tools and
technologies with peers is also a very practical way
to get direct feedback and learn some new tricks of
the trade.
For current and future MySQL users, the conference
is a great place to meet the people you work with and
even some of the experts whose blog posts and articles you read regularly. Its a chance to ask questions
of some of the most experienced professionals in the
industry and compare ideas. But most important, its a
chance to learn. By listening to people share their challenges and seeing how they resolved them, you can
develop new strategies for dealing with similar challenges you may even be able to get some specific
advice for resolving a particularly troubling problem!
MySQL continues to thrive because it is a cost-effective tool to scale web applications and business processes while delivering the innovations organizations need
to successfully adapt to business and technology environments that evolve with extraordinary rapidity. As the
premier conferences for the European MySQL community, Percona Live London offers MySQL users and their
organizations the ability to gain unprecedented levels of
insight from some of the most experienced MySQL users in the world. What better way to learn about the tips,
tricks, and strategies that can help you stay ahead of the
competition all while having a great time. We hope to
see you there!
If youd like more information about Percona Live
MySQL Conference 2013, London, including attending
or sponsoring the event, visit our website [4].

www.webandphp.com

Web & PHP Magazine readers get 25 off their


Percona Live London tickets, just head over to the
Percona Live London site and enter the promotional
code PHP-UK at the checkout.

References
[1] http://lists.mysql.com/mysql/228795
[2] https://www.percona.com/live/london-2013/
[3] https://www.percona.com/live/london-2013/conference-committee
[4] https://www.percona.com/live/london-2013/

About
Publisher
Software & Support Media Ltd
Editorial Office Address
86 Great Suffolk St
London SE1 0BE
www.sandsmedia.com
Editor: Elliot Bentley (elliotb@sandsmedia.com)
Authors: Arne Blankerts, David Buchmann, Aurelio De Rosa,
Terry Erisman, Ben Greenaway, Antonio Peri -Maar,
Alexander Rubin, Rokas leinius,
Creative Director: Jens Mainz
Layout: Tobias Dorn, Flora Feher, Petra Rth
Sales:
Ellen May
+44 207 199 6234
ellenm@sandsmedia.com
Contents copyright 2013 Software & Support Media Ltd.
All rights reserved. No part of this publication may be reproduced, redistributed, posted online or reused by any means in
any form, including print, electronic, photocopy, internal network,
Web or any other method, without prior written permission of
Software & Support Media Ltd.
The views expressed are solely those of the authors and do
not reflect the views or position of their firm, any of their
clients, or Publisher. Regarding the information, Publisher disclaims all warranties as to the accuracy, completeness, or adequacy of any information, and is not responsible for any errors,
omissions, inadequacies, misuse, or the consequences of using any information provided by Publisher. Rights of disposal of
rewarded articles belong to Publisher. All mentioned trademarks
and service marks are copyrighted by their respective owners.

Web&PHP Magazine 10.13 | 32

You might also like