The Symfony2 CMF Selling stuff with Sylius Branching out with Twig

32
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 A guide to Symfony2‘s favorite templating engine Published by S&S Media Group www.webandphp.com ALSO IN THIS ISSUE 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 Image licensed by Ingram Image In the key of Symfony2

Transcript of The Symfony2 CMF Selling stuff with Sylius Branching out with Twig

The Symfony2 CMFSolving the “framework or CMS” dilemma

Selling stuff with SyliusGet stuck into the next big thing in ecommerce

Branching out with TwigA guide to Symfony2‘s favorite templating engine

Published by S&S Media Group

www.webandphp.com

AlSo in ThiS iSSue

october 2013 Issue 19

Advanced MySQl Query Tuningby Alexander Rubin

Security holes? Who cares?by Arne Blankerts

Percona live londonConference preview

open Source SpotlightDebugging tool Kint

Imag

e lic

ense

d b

y In

gra

m Im

age

In the key of Symfony2

Contents

ContentsLetter from the Editor

As I looked over this is-sue’s contents, I noticed a theme running through several articles: Symfony2. Everyone has their favour-ite PHP web framework, but in the two short years since its release, Symfo-ny2 appears to have struck a chord among the com-

munity, 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 it’s far from finished. Like Symfony2, it’s also composed of bundles where you take only the bits you need, and leave the bits you don’t. You can find out more about using Sylius (and opportunities to get in-volved in its development) in the feature on page 9.

Another young Symfony2-based project is the Con-tent 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 project’s developers, David Buchmann, has written an introduction to the CMF, which you can find on page 5.

It’s 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 architec-ture.

Plus, instead of keeping their best innovations locked within the framework, SensioLabs have been generous in spinning off Symfony’s best components into separate projects like SwiftMailer and Twig (the latter of which you can find a tutorial for on page 14).

It’s a framework for a distributed age: instead of a monolithic PHP script on a single LAMP stack, today’s applications are assembled from the best OSS has to offer, split between remote servers and delivered to an exploding variety of devices. Even if you’re not us-ing any of Symfony2’s code base, there’s plenty to be learnt from the project.

The funny thing is that we’ve accidentally ended up with an issue packed full of Symfony2-powered good-ness – and yet, not a single article on the core frame-work itself! Luckily, for those looking for something on Symfony2 itself, we’ll be taking an early look at the framework’s upcoming release, Symfony 2.4, in next month’s issue.

Elliot Bentley, Editor

Music to my ears This month’s top events 3open source spotlight: Kint 4Interview with Rokas Šleinius

Tutorial

introducing the Symfony2 Content 5Management Framework by David Buchmann

Feature

Selling stuff Symfony-style with Sylius 9by Antonio Peri -Mažar

Tutorial

Branching out with Twig 14by Aurelio De Rosa

Tutorial

Advanced MySQl Query Tuning 18by Alexander Rubin

Column

Creating business tools in cyberspace? 25 Think Different! Ben Greenaway Column

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

Column

Conference preview: 30 Percona live londonby Terry Erisman, Chief Marketing Officer, Percona

www.webandphp.com Web & PHP Magazine 10.13 | 2

Community CornerCalendar

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

AWS SDK for PhPhttp://www.meetup.com/Bellingham-Developers /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.

October 4–5 // Cape Town, South Africa // R800 (10¢ in USD)

PhP South Africahttp://www.phpsouthafrica.com/South Africa’s first ever conference sees speakers both international and local travel to Cape Town for two days of talks.

To suggest an event for our calendar, email [email protected].

ThiS MonTh’S ToP evenTS october 1 – november 4 // A handpicked selection of some of the most

exciting PHP events from around the world

October 8 // Zürich // Free

Making news with PhPhttp://webtuesday.ch/meetings/20131008/Hear from Benjamin Rüegg, a developer for Swiss newspaper Blick, on how he applies open source tools to high-speed, large-scale environments. Talk is in German.

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

noSQl Bakeoffhttp://www.meetup.com/sawebdev/events/135588782/This month’s event is (at time of writing) still look-ing for volunteers to do a 10–15 minute talk on MongoDB, Neo4J, Redis or CouchDB.

October 23 // Bogotá, Colombia // Free

hiphop vM for PhPhttp://www.meetup.com/PHPColMeetup/events/129463532/Learn about Facebook’s custom replacement to the Zend Engine, which can (apparently) increase performance by 5x.

October 27–30 // Munich, Germany // €1,069.81 for three days

international PhP Con-ference 2013http://phpconference.com/2013/Web & PHP’s German colleagues host an-other installment of the long-running confer-ence, this time with a keynote from Opera evangelist Bruce Lawson.

www.webandphp.com Web & PHP Magazine 10.13 | 3

Community CornerOSS Spotlight

Web & PHP Magazine: Who’s behind Kint?Rokas Šleinius: Kint has been a single-per-

son project, but over the recent years I’ve 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 im-

prove 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 aw-fully buggy and already-then-abandoned Krumo. Please don’t even link to it, I’d hate to give it even more popularity.

Kint became a huge part of my development cy-cle, 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.

WPM: What’s wrong with PHP’s native debug-ging tools?

Šleinius: Kint to var_dump() is what a full-fledged IDE is to MS Notepad. Both do the job, however nei-ther notepad nor var_dump() are tailored to do real world tasks. They are bare, generic necessities to re-sort 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 can’t imagine coding without. It’s a tool written from scratch by a developer for develop-ers – not a layer on top of some other sub-standard tool. It’s 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, it’s dead-simple to begin working with and you’ll discover the advanced usage gradually if you’re interested.

open source spotlight: Kint

WPM: Is manual debugging any substitute for unit testing?

Šleinius: These are two different areas and both are critical. You definitely need test cover-age for your code as much as you need a proper toolset to fix bugs when tests don’t pass.

WPM: Where do you hope to see the project in a year’s 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 inte-grates Kint heavily and is way better than ev ery-thing I’ve tried so far. I’m hoping to package and release it in the near future, so there’s that.

I am hoping that one day, Kint, plus the to-be-released 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/

Meeting the people behind the most exciting homegrown OSS projects. This month, we speak to Rokas Šleinius about Kint, a drop-in replacement for PHP’s native debugging functions.

www.webandphp.com Web & PHP Magazine 10.13 | 4

TutorialSymfony2 CMF

www.webandphp.com Web & PHP Magazine 10.13 | 5

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 Sym-fony2 [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 ei-ther slapping together dozens of modules of some-times 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.

The CMF [2] aims to provide a way out of this di-lemma. 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 ap-plication 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 don’t.

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 PHPCR-ODM [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 main-taining and improving the various components. A cou-ple 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

Your “framework or CMS” dilemma solved

introducing the Symfony2 Content Management Framework An official sub-project of Symfony2, the CMF isn’t “yet another CMS” but a powerful modular collection of libraries and bundles.

TutorialSymfony2 CMF

www.webandphp.com Web & PHP Magazine 10.13 | 6

Basic UsageThe best starting point to explore the CMF is the Sand-box [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 Listing 1 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 fix-tures 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. Figure 1 explains what CMF com-ponent handles which part of the page.

The CmfContentBundle handles simple static con-tent. 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 re-usable 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 ap-plication 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-im-plementing things. This makes sure that the various components are able to share media files. The Cmf­MediaBundle provides basic models and optionally in-tegrates with LiipImagineBundle for rendering images, as well as with the WYSIWYG editor image handling plugin elFinder. Integration with the SonataMediaBun­dle is planned.

RoutingWhen a request is received, the first thing Symfony2 has to do is to decide what code will handle this re-quest. The main information used to make this deci-sion 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 Symfo-ny2 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

Figure 2: CMF routing processFigure 1: The CMF start page

Listing 3<?phpnamespace Sandbox\MainBundle\Document;use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCRODM;use Symfony\Cmf\Bundle\ContentBundle\Doctrine\Phpcr\StaticContentclass IntroContent extends StaticContent{ /** * @PHPCRODM\String(translated=true) */ private $intro; // getter and setter for intro...}

TutorialSymfony2 CMF

www.webandphp.com Web & PHP Magazine 10.13 | 7

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”. Figure 2 illustrates the routing process. The additional steps provided by CMF are colored in green.

An interesting side effect of linking routes with con-tent is that the CMF routing can also generate a URL from the content object. This is for example used in

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 Sym-fony2 router. The ChainRouter calls the core router, the CMF router and any other routers that where reg-istered to it, in a configurable order. That way, normal Symfony2 routes are still possible and do not need to be transferred into the database.

EditingWhen 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 WYSI-WYG 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 ed-ited content is stored over AJAX and the page is updated without reloading. Figure 3 shows the editing in action.

The CmfCreateBundle integrates create.js into Sym-fony2 with the help of the CreatePHP library [9]. Cre-ate.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 pro-vides helpers so that template writers do not need to manually handle the RDFa attributes. Sounds confus-ing? Let’s add a new type of content to the sandbox to see how this is all done.

Adding a new type of contentTo see a bit more, let’s add a new type of content in the sandbox. For the sake of the example, let’s simply add

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 Listing 3.

The generic controller will do just fine for this con-tent. 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 Listing 4.

In the template, simply add {{ cmfMainContent.intro }} where you want to output the introduction text field.

Make the content editable with create.jsIf you want the field to be editable with create.js, a bit more work is required. You need to provide the map-ping between the model and RDFa as shown in List-ing 5.

In the detail template, we adjust the rendering to output the intro field with the CreatePHP twig exten-sion. The individual articles can now even be edited on the overview page if we render them with a template like shown in Listing 6.

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 docu-ments. You can extend the StaticContentAdmin to add the intro field.

Storage LayersThough designed to be storage agnostic, there is a preferred storage layer for the CMF: Doctrine PHPCR-ODM. This object-document mapper stores model classes into the PHP content repository [10]. The rea-son for this is simply ease of use. PHPCR is tree-ori-ented, 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-

Figure 3: The CMF start page

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

TutorialSymfony2 CMF

www.webandphp.com Web & PHP Magazine 10.13 | 8

cial thing is that links between objects in PHPCR do not need to know the target class as relational data-bases 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.

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 %}

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 ac-cess 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 PHP-CR implementation like Jackalope, the Doctrine PHP-CR-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 Doc-trine ORM. For small and/or simple projects, the ORM is a viable option. On larger projects, the added flexibil-ity of PHPCR-ODM will become more important.

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 up-grade your application. There is a thriving community pushing the CMF forward and building up a compre-hensive documentation, available at symfony.com. The time is right to give the CMF a try!

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

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

FeatureSylius

www.webandphp.com Web & PHP Magazine 10.13 | 9

by Antonio Peri -Mažar

Soon after the Internet became a mass medium, many systems developed in order to seize new opportuni-ties. 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 de-velopment as well as many companies that have de-cided to implement webshops.

In this article I will talk about Sylius, which is becom-ing more and more popular. It is based on the Sym-fony2 [1] framework, which is one of the most popular PHP frameworks and each day more and more devel-opers use it to develop both large and small web ap-plications. 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 com-pletely free for downloading and implementing any changes. It is developed using BDD [4] and TDD meth-odology – the only ecommerce solution implemented using this methodology at the moment. It is charac-terized 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 im-plementing 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 com-munity. Developers are using it for producing ecom-merce solutions with high levels of customization. What is very exciting is that you can participate in mak-

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.

©iS

tock

pho

to.c

om

/cul

tury

FeatureSylius

www.webandphp.com Web & PHP Magazine 10.13 | 10

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 report-ing bugs, or you can just spread the word about Sylius.

CommunityAs 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

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 contrib-ute 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 ap-plication 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,

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, Ital-ian, Japanese, German, Polish, Dutch, Serbian, Rus-sian and more. There are more than 3000 commits and new features are constantly added.

Features: y Product Management: unlimited products, com-plex products with options and attributes, product variations

y Inventory tracking: real time tracking, products available on demand, tracking of individual units

y Complete taxation support: works with simple and complex tax rules, rates for different tax cat-egories and zones, tax included in price support, customizable tax calculators

y Product categories: tree structure, complex tax-onomies, list your products by category, brand, producer (and so on), create featured product easily

y Shipping engine: organize and track your ship-ments, unlimited number of shipping methods and individual shipment units, track shipments, status-es, and individual shipment units, multiple flexible shipping charge calculators

y 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)

y Free now and always: fully open source, business friendly licence – MIT; no paid edition with more features

ArchitectureSylius was recently upgraded to the LTS Symfo-ny version 2.3. (LTS = long term support for three

FeatureSylius

www.webandphp.com Web & PHP Magazine 10.13 | 11

years for any bugs and four years for any security is-sue) [7]. Sylius architecture is based on several de-coupled components. At this moment, the standard version is made of 19 different bundles [8]: Address-ingBundle, CartBundle, CoreBundle, FlowBundle, InstallerBundle, MoneyBundle, OmnipayBundle, PaymentsBundle, ProductBundle, PromotionsBun-dle, ResourcesBundle, SalesBundle, ShippingBundle, TaxationBundle, TaxonomiesBundle, VariablePro-ductBundle, and WebBundle. Symfony also uses some well known Symfony2 bundles as: FOSUser-Bundle, FOSRestBundle, KnpMenuBundle and PagerFantaBundle.

The idea behind Sylius is to construct your own solu-tion 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 exist-ing bundle. Thus, it introduces the idea of the Sym-fony2 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 custom-ize core models and adapt the logic inside any service. Also, it is possible to use any of the 1 900 Symfony2 bundles in your Sylius project.

A part of the customization process is overrid-ing 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-

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 cre-ate its own DSL. You can find out more about Twig on the official page [8] [Edi-tor’s note: There’s 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 control-lers, one for backend and another for frontend. Addi-tionally, 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. Sy-liusResourceBundle has allowed for removing man-ager and manipulator classes, frontend and backend controllers for every entity, getting rid of very sim-ple 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 Sy-lius.

The project’s 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 oc-cur 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 ap-plication includes features like registration, profile administration, product listing, product listing by tax-onomy and taxon, shopping cart, checkout process without payment integration and full backend admin-istration to work with your Sylius store.

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

FeatureSylius

www.webandphp.com Web & PHP Magazine 10.13 | 12

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 start-ed 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 re-quires using concrete data models – but it is an an interesting option anyway) or Omnipay [14]. An in-tegration bundle for the Omnipay library has already been created and it seems to work well with Sylius. However, the library itself has some architectural is-sues 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 prom-ising option.

In the latest major Sylius update, Cart and Order mod-els have been merged. By doing this, the checkout-relat-ed logic has been dramatically simplified. It is important to make sure that templates are displaying the data prop-erly 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

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, peo-ple 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.

Currently the FSCHateoasBundle [17] is used to han-dle the serialization of Pagerfanta (the paginator) instanc-es. This bundle is more powerful and a more complete integration and usage ought to be considered. Another option is the BazingaHateoasBundle [18], a much young-er 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 translationsSylius’ founder, Pawel J drzejewski, stated that he is planning on redesigning the Sylius default theme with the same person who was in charge of creat-ing the new look of the Sylius website. A discussion

FeatureSylius

www.webandphp.com Web & PHP Magazine 10.13 | 13

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 Boot-strap 3 [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 solu-tion 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 look-ing 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 incom-plete. The process used for translating right now is not the best possible, and I am already exploring dif-ferent approaches. An optimal way for resolving this issue should be found.

Feature freeze and betaAfter 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.

ConclusionSylius is built on solid foundations (Symfony2 as the enterprise-class PHP framework). It is 100 % open source project, with a high quality and component-

based approach. It is agile and developer-friendly, and the best thing is that you can override every sin-gle part of Syilus in accordance with your project’s 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 so-lution. 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, Sy-lius does not support signing in with social networks and payment integration as well as templating solu-tion and promotions with coupons are not yet imple-mented. 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.

Antonio Peri -Mažar 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 re-sponsible for the web applications development, business develop-

ment 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

[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-e-commerce-but-is-it-ready-to-use

TutorialTwig

www.webandphp.com Web & PHP Magazine 10.13 | 14

by Aurelio De Rosa

Stand up if you’ve never used the amazing PHP con-struct include and/or require to assemble the layout of a website ... I bet you’re all still sat down. Me too. Using PHP as a template engine is fine and works well while you’re 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 flex-ible product?

I am, of course, referring to Twig. In this article I’ll 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 it’s released under the new BSD license, so it’s completely free to use. That considered, you should not be surprised by the fact that Twig is the Symfony framework’s template en-gine 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 you’ve ever used Smarty [2], you’ll see a lot of simi-larities 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 extensi-ble, meaning that in case something you need is miss-ing, you can create your own language constructs. In summary, Twig is a reliable, well documented, com-pletely unit tested and mature enough framework to be safely used in your next project. Now that you know what Twig is, let’s see how you can install it.

Branching out with Twig Separate your application’s logic from its views with the flexible template engine from the creator of Symfony

Imag

e lic

ense

d b

y In

gra

m Im

age

TutorialTwig

www.webandphp.com Web & PHP Magazine 10.13 | 15

Installing TwigOne of the thing I appreciate is the wide range of pos-sibilities to install Twig. The most common and recom-mended way is via Composer. The first step is to add it to your project’s 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, typ-ing the following commands:

pear channel-discover pear.twig-project.orgpear install twig/Twig

You can obtain Twig in many other ways but I’ll pre-sent 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 project’s folder.

How to create a Twig templateBefore delving into the PHP code needed to load and pass data to your Twig templates, it’s important to un-derstand how a template is built. The first fact you need

to know is that while Twig templates do not require a specific file extension, you’ll usually see the use of .twig. Many IDEs that have support for Twig will correctly highlight the syntax of your template (for example PHP-Storm) if you use the .twig extension, though. To keep it as simple as possible, I’ll 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, ex-pressions 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, let’s see some exam-ples in Listing 1.

The value of the variables were ideally sent by the PHP page that required the template. In certain situ-ations, you may need to set the value of a variable in-side 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 isn’t a good practice. Therefore, you should limit the use of set to those cases where it’s strictly required by a view-only scope. For example, this may be useful if you’re using the I18N internationalisation extension and want to apply a filter (more on this in a next sec-tion) to the string you want to translate.

In the code above I showed the use of simple vari-ables 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, you’ve 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 Twig’s 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')

TagsSo far, you’ve seen how to use variables and expres-sions, so it’s 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 ex-amples you’ve already seen a couple of tags, that is

Listing 1{# I’m 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 %}

TutorialTwig

www.webandphp.com Web & PHP Magazine 10.13 | 16

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 overrid-den by a child template in the future. Before show-ing you an example, it’s important to introduce the last two tags I’ll 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 Listing 2.

The extend tag is used to inherit from a parent tem-plate and, eventually, overrides some blocks. To see it in action, the best example is to think to a general lay-out declaration overridden by the template of a specif-ic page. So, let’s 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.

This is the typical situation where you’ll use the extend tag. Let’s see an example.

A simple layout file is shown in Listing 3. 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 out-side the scope of this article. However, you can find them all in the Twig tags page [4].

FiltersYou probably find yourself often modifying variables in a PHP page using functions – for example, escap-ing HTML characters or converting a sentence to ti-tle case. Doing it in the controllers (or in the page if you aren’t adopting an MVC pattern) isn’t 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, provid-ing 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 snip-pet that takes a variable called bookTitle, escapes HTML characters and capitalizes the first letter of each word:

{{ bookTitle|escape|title }}

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 3<!DOCTYPE html><html> <head> <title>{% block pageTitle %}{% endblock %}</title> <!-- asserts here... --> </head> <body> <head> <img src="site-logo.jpg" alt="" /> <h1>Aurelio De Rosa’s website</h1> </head> <main> {% block content %}{% endblock %} </main> </body></html>

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

TutorialTwig

www.webandphp.com Web & PHP Magazine 10.13 | 17

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 templateSo far, you’ve seen how to build a layout, but you’re not yet able to use it to show to the user of your web-site. Before showing you the code, it’s important to know a little more about the classes included in the library. Twig uses a central class called Twig_Envi­ronment where you’ll set the configuration and add the extensions of your project. This is also the ob-ject you’ll use to load the templates from the filesys-tem (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 recom-pile 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, let’s see some code. The first thing to do to use its classes, is to load the library. If you installed Twig

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 tem-plate 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. Here’s 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'));

Alternatively, you can also use the display() method, that acts as a shortcut for echo $twig­>render(...);, to output the template directly, like so:

$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 doc-umentation [6]. However, with the examples described in this section you’re able to start using it right now.

ConclusionsIn this article we discovered what Twig is and its ba-sic 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 you’re developing a multilingual project. With this last hint, the article is over. I hope you enjoyed it and that thanks to it you’ll consider using Twig or an-other 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 he’s self-employed working with the cited technologies. He’s 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

[4] http://twig.sensiolabs.org/doc/tags/index.html

[5] http://twig.sensiolabs.org/doc/filters/index.html

[6] http://twig.sensiolabs.org/documentation

TutorialMySQL Query Tuning

B-tree supports both “equality” (where id = 1) and range (where date > ‘2013-01-01’ and date < ‘2013-07-01’) search. Figures 2 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 In-noDB “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

every second counts

Advanced MySQl Query Tuning A closer look at query optimization with a focus on queries with GROUP BY and ORDER BY

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 (In-dexes, 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.

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

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

Explain planThe main way to “profile” a query with MySQL is to use “explain” [3]. Listing 2 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 num-ber of rows:

www.webandphp.com Web & PHP Magazine 10.13 | 18

TutorialMySQL Query Tuning

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 Listing 3 shows that MySQL will use an index.

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

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 IndexesCombined 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 Listing 5, the 2 leftmost fields

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

• CountryCode = 3 chars • District = 20 chars • Total = 23

In Listing 6, 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 (List-ing 7). As we do not have the CountryCode in the where clause, MySQL will not be able to use our “comb” index.

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

Listing 1CREATE 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 2mysql> EXPLAIN select * from City where Name = 'London'\G*************************** 1. row id: 1 select_type: SIMPLE table: City type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 4079 Extra: Using where

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

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

www.webandphp.com Web & PHP Magazine 10.13 | 19

TutorialMySQL Query Tuning

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:

1. Where part2. Group By/Order (not used now)3. Select part (here: name)

You can see an example of this in Listing 8. “Using in-dex” 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 indexThe 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 com-parison) 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 (Figure 4): In this case MySQL will be able to go “directly” (via in-dex scan) to the correct district (“CA”) and do a range scan by population. All other nodes for the

Figure 4: (district, population) index scan Figure 5: (population, district) index scan

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

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

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

Listing 8mysql> explain select name from City where CountryCode = 'USA' and District = 'Alaska' and population > 10000\G*************************** 1. row *********** table: City type: rangepossible_keys: cov1 key: cov1 key_len: 27 ref: NULL rows: 1 Extra: Using where; Using index

www.webandphp.com Web & PHP Magazine 10.13 | 20

TutorialMySQL Query Tuning

”district” field (other US states in this example) will not be scanned.

2. (population, district) index (Figure 5): 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 QueriesIn 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 perfor-mance in general.

Group by exampleLet’s look at this simple example, a query of how many cities there are in each country. As we can see from Listing 9, MySQL does not use any indexes (no proper indexes are available), but it also shows “Us-ing 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 sat-isfy the “group by” clause and avoid creating tempo-rary table.

Group by and covered indexTo illustrate the “group by” queries I will use the fol-lowing 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 approxi-mately 2 GB 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 10... type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 4833086 Extra: Using where; Using temporary; Using filesort

Listing 11mysql> explain select name from City where CountryCode = 'USA' and District = 'Alaska' and population > 10000\G*************************** 1. row *********** table: City type: rangepossible_keys: cov1 key: cov1 key_len: 27 ref: NULL rows: 1 Extra: Using where; Using index

Listing 12mysql> 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

Listing 9mysql> explain select name from City where CountryCode = 'USA' and District = 'Alaska' and population > 10000\G*************************** 1. row *********** table: City type: rangepossible_keys: cov1 key: cov1 key_len: 27 ref: NULL rows: 1 Extra: Using where; Using index

www.webandphp.com Web & PHP Magazine 10.13 | 21

TutorialMySQL Query Tuning

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 (Listing 11).

However, we can create a covered index on (day-ofweek, Carrier, DepDelayMinutes) in this particular order. In this case MySQL will be able to use this in-dex and avoid creating a temporary table (Listing 12). 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 non- covered 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.

Group by and a range scanThe 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. Listing 13 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 (Listing 14). 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 Listing 15.

As we can see, MySQL uses our covered index for each of the 2 queries. It will still have to create a tem-porary table to merge the results, however, it will prob-ably be much smaller temporary table as it will only need to store the resultsets of 2 queries.

Group by and a loose index scanLoose index scan is another MySQL algorithm to op-timise 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 16mysql> explain select max(DepDelayMinutes) as ddm, Carrier, dayofweek from ontime_2012 where dayofweek = 5 group by Carrier, dayofweek

table: ontime_2012 type: rangepossible_keys: covered key: loose_index_scan key_len: 5 ref: NULL rows: 201 Extra: Using where; Using index for group-by

Listing 13mysql> explain select max(DepDelayMinutes), Carrier, dayofweek from ontime_2012 where dayofweek > 5 group by Carrier, dayofweek\G...

type: rangepossible_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)

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 ***************************

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

www.webandphp.com Web & PHP Magazine 10.13 | 22

TutorialMySQL Query Tuning

• 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 documen-tation 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)

Note that loose_index_scan is only a name of the index, it can be any name. You can see an example in List-ing 16. “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 (Listing 17).

BenchmarkWe have performed a benchmark to compare query speed with a temporary table, a tight index scan (cov-ered index) and a loose index scan. The table is 6 mil-lion rows and approximately 2 GB in size.

The results are shown in Figure 6. As we can see, loose index scan index shows the best performance. Unfortunately, loose index scan only works with 2 ag-gregate functions, min and max for the group by. “AVG” + group by does not work with loose index scan. As we can see in Listing 16, 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 filesortMySQL 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 Listing 19 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 limitIf 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. Here’s an example:

mysql> alter table ontime_2012 add key (DepDelayMinutes);

We can create an index on DepDelayMinutes fields only and run the explain in Listing 21 (note the query with LIMIT 10). As we can see, MySQL uses index on

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

Listing 18mysql> 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

Listing 17mysql> explain select max(DepDelayMinutes) as ddm, Carrier, dayofweek from ontime_2012 where dayofweek > 5 group by Carrier, dayofweek;

table: ontime_2012 type: rangepossible_keys: covered key: loose_index_scan key_len: 5 ref: NULL rows: 213 Extra: Using where; Using index for group-by;

www.webandphp.com Web & PHP Magazine 10.13 | 23

TutorialMySQL Query Tuning

DepDelayMinutes only. Here is how it works. As Index is sorted, MySQL can:

1. Scan the whole table in the order of the index2. Filter results (using the where clause condition, but

not using the index)3. Stop after finding 10 rows matching the “where”

condition

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 in-dex 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.

ConclusionWe have discussed different indexing strategies to op-timize your slow queries:

• 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 21mysql> explain select * from ontime_2012 where dayofweek in (6,7) order by DepDelayMinutes desclimit 10\G

type: indexpossible_keys: DayOfWeek,covered key: DepDelayMinutes key_len: 5 ref: NULL rows: 24 Extra: Using where

Listing 20mysql> 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

• Order by optimizations can be done with covered index and with the “order by+limit” index tech-nique, described above.

Now you can look again into your MySQL slow query log and optimize more slow queries.

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

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.

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

ColumnOSS

Creating business tools in cyberspace? Think Different!

by Ben Greenaway

www.webandphp.com Web & PHP Magazine 10.13 | 25

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 mem-bers are entrepreneurs and freelancers who make reg-ular 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 train-ing, yet a discussion of Software as a Service tools developed and brought with it a renewal of some most deeply treasured ideals.

Bio

Ben Greenaway has been a software developer for 18 years. After pioneering internet narrow-casting in the 90’s in collaboration with Virtual Futures he has led development on A/V installa-tion 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 solu-tions 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.

It may not be obvious why, but I consider Word-Press as belonging to these Software as a Service offerings. I’m 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 market-ing campaigns need mass distribution – all of which have significant social networking components these days. It’s hard to look like a modern business without one.

If you look to see how it is deployed you can see a blurring of WordPress’s open source project status with that of a commercial business concern, in line with the way SaaS offerings are delivered. Word-Press and similarly Drupal offer themselves as host-ed 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 con-sidered Software as a Service and often become the starting point of a small business’s 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

ColumnOSS

www.webandphp.com Web & PHP Magazine 10.13 | 26

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 chan-nels and working processes so we can be sure that use of these tools will grow.

The story of the Internet’s arrival is also the story of the open source software movement’s greatest suc-cess. As you probably know, the movement’s aim has been to offer universal access to software’s source code without prejudice to its use, modification or redis-tribution. It has proven that the development of new software can be a collaborative and distributed pro-cess, saving time, money, and the duplication of effort, all the while educating and informing a broader public of the technology’s mechanisms. Treating users as co-developers has worked, and still works brilliantly. In the web’s 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 al-lowed 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 develop-ers have emerged from personal page creation to be-come the heads of development organizations all in the short space of a decade.

So if throwing away the more defensive and protec-tive 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 source’s 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 can’t even notice it. The open source story is somewhat counter-intuitive and poorly communicated outside of our industry; you wouldn’t 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 can’t remember can you …? (spoiler: there wasn’t 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 haven’t. It worries me that any fur-ther 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 cor-porate world? And what would an open sourcing of business be like?

Available now for $ 3.99Buy now at:

www.developerpress.com

Also available to buy on:

ColumnOSS

www.webandphp.com Web & PHP Magazine 10.13 | 27

ColumnSecurity

Security holes? Who cares?

To err is human, but to ignore the warnings of independent security researchers is just downright silly, writes Arne Blankerts.

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 real-ize 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 of-fer 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 –

for reports of security relevant issues. But have you ever tried reporting such a problem?

What happened to two security researchers in Ger-many 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, every-thing 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 fash-ion: He wrote a post to Mark Zuckerberg’s 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 re-main silent either, but refrained from any drastic ac-tions. 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

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

by Arne Blankerts, thePHP.cc, Germany

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 mis-takes. 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 any-way, it’s not a human mistake but a computer glitch.

www.webandphp.com Web & PHP Magazine 10.13 | 28

ColumnSecurity

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 eventu-ally got threatened to get sued for hacking into their computer systems.

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.

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 indi-cate that people fail to learn. Too often, software keeps being developed with the happy path in mind, ignoring all the potential issues and unhandled condi-tions which lead to “random features”.

So let us – for the sake of a safe browsing experi-ence – hope that the white-hat hackers keep up with their good work, despite the hard time many compa-nies give them. After all, those hackers seem to be the only ones who really care, and try to help compa-nies to make their software better.

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 actu-ally are quite standard and consist of common mis-takes 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 appli-cation 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.

When comparing the various versions and itera-tions 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

“The technical aspects of the problems reported to PayPal and Facebook are hardly new.”

“Too often, software keeps being developed with the

happy path in mind.” References

[1] http://venturebeat.com/2013/08/18/facebook-zuckerberg-wall-vulnerability/

[2] http://www.vulnerability-lab.com/dev/index.php/2013/04/29/5000-paypal-bug-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

www.webandphp.com Web & PHP Magazine 10.13 | 29

EventPercona Live

www.webandphp.com Web & PHP Magazine 10.13 | 30

by Terry Erisman, Chief Marketing Of� cer, Percona

According to one attendee [1], last year’s Percona Live MySQL Conference in London [2] “was even more in-teresting than the fi rst edition, and I had great fun dis-cussing 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 year’s Percona Live MySQL Conference in Lon-don is shaping up to be even better. We are especially excited by the participation of Oracle representatives

this year – providing a keynote, participating on the Conference Committee, and delivering breakout ses-sion talks.

Conference sessions will dive into the major vari-ants of MySQL – MySQL 5.6, Percona Server 5.6, and MariaDB 10 – and MySQL-related technologies. The keynote speakers will address the MySQL vari-ants and related technologies during their talks, in-cluding:

• Tomas Ulin, Vice President, MySQL Engineering at Oracle, will discuss the focus, strategy, invest-ments and innovations that are preparing MySQL to power next-generation web, mobile, cloud and embedded applications. He will also discuss the

latest and the most signifi cant 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 in-stead 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 Don’t Know Can Hurt You” as he explores the real risks of managing data in the cloud and ex-plains how cloud data managers using MySQL can build more robust systems.

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 11–12, 2013 Win a pair of tickets!

One lucky reader will win a pair of

tickets to November's event. Send an

email to [email protected]

(by 11pm, October 15) titled "Percona Live

Competition" for your chance to win.

MySQL and more in the UK’s capital

EventPercona Live

www.webandphp.com Web & PHP Magazine 10.13 | 31

• 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 year’s 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 Man-agement, 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 im-mediate 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 de-veloped include Developing Applications, Database Administration, Trends in Architecture and Design, Tools, Utilizing Hardware, New Features, Best Prac-tices for Businesses, Replication, and High Availabil-ity Strategies.

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 re-ception offers an excellent opportunity for attendees to mingle, make new friends, and develop future plans.

The Value of Percona Live MySQL Conference, LondonAttending 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 Esto-nia, Turkey, Lithuania, and Malaysia. And this diversity of geography was matched by diversity in company

size. About a third of the attendees came from com-panies 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, telecommu-nications, e-commerce, media, retail, entertainment, mobile technology, education, hospitality, social net-working, biotechnology, and healthcare.

While the Percona Live MySQL Conference in Lon-don is a chance to play an active role in a growing com-munity 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 eco-system. 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.

EventPercona Live

www.webandphp.com Web & PHP Magazine 10.13 | 32

For MySQL Community members, the conference is a terrific way to reignite their passion for the tech-nology. After every Percona Live conference I feel extremely lucky to be part of such a smart, innova-tive 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 arti-cles you read regularly. It’s a chance to ask questions of some of the most experienced professionals in the industry and compare ideas. But most important, it’s a chance to learn. By listening to people share their chal-lenges and seeing how they resolved them, you can develop new strategies for dealing with similar chal-lenges – 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-effec-tive tool to scale web applications and business process-es while delivering the innovations organizations need to successfully adapt to business and technology envi-ronments that evolve with extraordinary rapidity. As the premier conferences for the European MySQL commu-nity, Percona Live London offers MySQL users and their organizations the ability to gain unprecedented levels of insight from some of the most experienced MySQL us-ers 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 you’d like more information about Percona Live MySQL Conference 2013, London, including attending or sponsoring the event, visit our website [4].

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

PublisherSoftware & Support Media Ltd

Editorial Office Address86 Great Suffolk StLondon SE1 0BEwww.sandsmedia.com

Editor: Elliot Bentley ([email protected])Authors: Arne Blankerts, David Buchmann, Aurelio De Rosa, Terry Erisman, Ben Greenaway, Antonio Peri -Mažar, Alexander Rubin, Rokas Šleinius, Creative Director: Jens MainzLayout: Tobias Dorn, Flora Feher, Petra Rüth

Sales:Ellen May+44 207 199 [email protected]

Contents copyright © 2013 Software & Support Media Ltd. All rights reserved. No part of this publication may be repro-duced, 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 dis-claims all warranties as to the accuracy, completeness, or ade-quacy of any information, and is not responsible for any errors, omissions, in adequacies, misuse, or the consequences of us-ing any information provided by Pub lisher. Rights of disposal of rewarded articles belong to Publisher. All mentioned trademarks and service marks are copyrighted by their respective owners.