Bookmark and Share
Check Google Page Rank Locations of visitors to this page
Click to get Free offers

Tuesday, May 27, 2014

What is PHPNG and how it will help to speed up PHP 6

What is PHPNG?

PHPNG is a new branch of development that aims to bring a whole new level of performance and memory usage efficiency to PHP.
This branch was added somewhat secretly by Zend developers to the PHP development repository in April 16 but it was openly described only in May 5 when Sebastian Bergmann of the PHPUnit fame asked in the PHP internals about it.
Dmitry Stogov of Zend presented a more or less detailed description of the PHPNG branch. He explained that he has been experimenting using a JIT engine (Just In Time compilation to native machine code) using LLVM.
Using LLVM as a JIT for the Zend Engine was already proposed by Nuno Lopes in 2008. Some work was done with a student that was directed by Nuno Lopes as a Google Summer of Code project that resulted in the PECL LLVM extension. I have covered all possible PHP JIT solutions in an article about this topic in 2011.
The PHPNG branch also features improvements in the PHP memory management. According to Dmitry Stogov, the PHP execution takes a big part of the time dealing with memory allocations, and so that is an aspect that affects significantly PHP performance.
According to his tests the speed improvements of typical PHP applications are significant. For instance, he measured it and noticed that it can server 20% more requests per second when testing a Wordpress installation.
You cannot expect that all PHP applications will benefit from similar performance improvements because most of the time PHP is waiting for database or cache access operations to complete. Those operations will not benefit much from speed improvements in the execution of PHP, as PHP will be idle most of the time.

When PHPNG will be available?

These developments are mostly experimental. There is plenty of work to do to make them ready to be used in a stable PHP enviroment.
The expectation is that the PHPNG branch will be merged into PHP 6 or PHP 7 depending on what is supposed to be called the next PHP major release.

Backwards Incompatible Changes

The idea behind the PHPNG branch is to run existing PHP code without any changes. So PHP users will not be required to change their code to benefit from these improvements.
However, since PHPNG requires changes in the PHP internals, existing PHP extensions need to be adapted to work with the changes done in the Zend Engine. It seems to not require much work but those changes need to be done in the code of all PHP extensions.

The Plot to Kill Apache mod_php SAPI

During the debate about the work to be done to adapt extensions for these Zend Engine changes it was discussed which server APIs (SAPIs) should be worth supporting in future PHP versions. PHP supports many SAPIs. Some of them are probably not being used by many PHP users.
One of the SAPIs that was considered to not be supported in the future is the mod_php SAPI. The reason is not whether it is used by PHP users or not. mod_php is very popular, probably the most popular SAPI.
The reason for a possible deprecation and future discontinuation is the claim that using Apache or some other Web server with FastCGI or similar SAPI would be more efficient than using mod_php SAPI.
While that may be true in certain circumstances, many PHP applications rely on features only available when PHP is being used with Apache mod_php. For instance mod_php can read PHP options from .htaccess files. While there is the htscanner extension that can be used with other SAPIs to read configuration from .htaccess files, it is not exactly a perfect solution.
This is just to say that once mod_php is discontinued, upgrading to the PHP version that no longer supports it, will cause eventual grief and discourage PHP users and hosting companies to upgrade PHP.
This is a deja vu situation. In 2011 PHP core developers started discussing the discontinuation of the original MySQL extension. This was announced in another article of this blog. It was probably the article here that got most reactions because the change would affect probably millions of PHP users.
By then some core developers blamed this blog for announcing something that was not yet decided. Actually the article was just telling that there was intention to kill the mysql extension. Blaming this blog for exposing PHP core developers intentions was like shooting the postman for delivering letters with bad news.
The fact is that mysql extension ended up being deprecated in PHP 5.5 and is scheduled to be removed in PHP 5.7 or PHP 6, regardless of how many PHP users opposed to the decision. So the chances that Apache mod_php SAPI will be removed in future PHP versions are not negligible. Anyway, no decision was made about this yet, so not panic (yet).

PHPNG versus Facebook Hack

It seems it is not a coincidence that this great plan to finally bring a JIT compiler to PHP is something that happened just a few weeks after Facebook announced the Hack language.
The Hack language provides many features that PHP users want but were never implemented often with the justification that it takes a lot of time and effort to implement them.
One of the requested features is that it is built on top of the HHVM (HipHop Virtual Machine) engine. Among other features, HHVM implements JIT dynamic compilation of PHP code to native machine, just like PHPNG implements now to achieve speed improvements. So apparently the release of the Hack language rushed the development of PHPNG.
Facebook is a social network site. Their focus is not to develop new programming languages. If they created a new language, it is because they needed features that PHP did not provide. They just could not wait forever until the PHP core developers to give those features enough priority to implement them.
At the same time I think Facebook would rather rely on the official PHP core developments if it had the features they needed. So, if Facebook goal was to rush the development of such new PHP features, congratulations it seems they already succeeded to a certain extent.
Still the current PHP official implementation is far behind Hack in terms of features. Here are some of the features that the official PHP needs to catch up to at least match Hack features:

1. Type Hinting

Hack provides support for type hinting on everything: function arguments, function return values, and variables. Type hinting is useful for enforcing type checks and detecting bugs in PHP code.
However, type hinting is also useful to help the HHVM engine to generate optimized native machine code. Once the engine is aware of the types of variables and function return values, it no longer has to generate machine code to check and convert those values types at execution time. The resulting machine code can be smaller and faster when compared to when there is no type hinting.

2. Asynchronous Programming

Asynchronous programming is a way to execute multiple tasks in parallel while waiting for asynchronous tasks that depend on I/O operations like accessing files, network, databases, etc..
Hack introduced the await keyword. That allows your code to call some other code that is running in parallel while the calling script flow will only resume when the asynchronous operations inside the await code are finished.
This means that you can have multiple parallel activities running without having to use callback functions to handle their results. This is the most elegant asynchronous programming solution I have seen so far in any language. It is certainly better than the way it is done in JavaScript with Node.js for instance.

3. Production Ready Standalone Web server

Hack code runs inside HHVM. HHVM may run either as a single command line script, as a Web server, or as a FastCGI server. As a Web server, HHVM can run PHP Web applications without needing a separate Web server.
Nowadays, PHP can also run as a standalone Web server. The problem is that it is not yet considered robust enough to run as a Web server in a production environment.

4. Multithread safe

HHVM can run as a multithreaded Web server. This means that it can accept simultaneous connections in separate threads.
In theory PHP can also run with multithreaded Web servers. However when it uses extensions and libraries that are not thread safe, it may crash due to memory corruption caused by multiple threads attempting to access the same data in the same memory space.
To avoid this problem, it is recommended that PHP runs with a multi-process environment. The difference between processes and threads is that each process has its own memory space. So there is no way one process may cause another process to crash due to memory corruption.
On the other hand, in a multithreaded server all threads share the same memory space. This allows to make a more efficient use of memory. When a thread ends handling a HTTP request, it frees memory for handling other simultaneous requests.
This would not be possible in a multi-process environment like with Apache mod_php (pre-fork) or with PHP handling requests as FastCGI.
This way HHVM can provide a more scalable solution that can handle more simultaneous requests within the same server machine, as the limit of simultaneous requests that a single machine can handle, is directly tied to the amount of RAM that all requests are using at a given moment.
This is a matter that I have talked about in 2008 when I was invited to attend a PHP event organized by Microsoft along with many other PHP developers.
The effort to make the Zend Engine based PHP fully thread safe was always considered too complicated by the PHP core developers, so it was never done. However it was not too complicated for Facebook, so they made its HHVM based implementation as thread safe as it should be.

Conclusions

The PHPNG branch is certainly good news for the PHP community. Congratulations to Dmitry Stogov, Nikita, Xinchen and everybody else at Zend for finally have taken this step to move on with the PHP evolution.
After the release of Facebook Hack, maybe they finally realized that moving on to a JIT compiler based Zend Engine was a necessary step to keep Zend relevant in the PHP future.
PHP still has a lot to catch up to match Hack language features and HHVM benefits. Still this is good start.
Personally I would rather see Facebook join forces with Zend and other core PHP developers because that would make the PHP community stronger and the PHP future brighter, but there must be good will on each side to cooperate.
Still I think the Hack language development will continue independently at least for a while even if Zend wants to colaborate because Facebook needs Hack features to reduce their costs of deployment of the Facebook site.
View blog reactions

Sunday, August 4, 2013

Creating A Magento Module

A lot of community extensions (or modules) are available for the feature-rich open-source e-commerce solution Magento, but what if they don’t quite work as you want them to? What if you could understand the structure of a Magento module a little better, to the point that you could modify it to suit your needs or, better yet, write your own module from scratch?
In this tutorial, we will introduce the coding of Magento in the form of a “Hello World”-style module. The goal of the module will be simply to write some information to a log file every time a product is saved. This very basic module will allow us to cover a number of interesting topics, including:
  • The app/code directories,
  • The structure and creation of a Magento module,
  • Event observers,
  • Logging.

Before We Begin

This tutorial assumes that you already have an installation of Magento up and running, either locally or on a development server, that you can add new files to. The version of Magento that you use doesn’t really matter, because we will be covering fundamental aspects that exist across all versions and editions: Community, Professional and Enterprise.

DISABLE THE CACHE

This is one of the first lessons a Magento developer should learn: disable the cache! You can do this by going to Admin Panel > System > Cache Management > Select All > Actions: Disable > Submit.
While very good at boosting performance in a production environment, the cache is a developer’s enemy. Leave it enabled at your peril! Every Magento developer I have met has on more than one occasion spent an hour or so wondering why their latest update is not showing up, only to find that Magento is still displaying the version of the website that it conveniently cached earlier that day.

The app/code Directory

The brains of Magento can be found in individual modules inside the app/code directory, which is split in to three areas: core, community and local.

CORE

The app/code/core directory contains all of the functionality for products, categories, customers, payments, etc. Until you know what you are doing (and even afterwards), keep app/code/core off limits because these files should not be modified.
Magento is structured in such a way that you can alter the functionality of any of these core files without modifying them directly, which ensures that your application remains upgrade-proof. By all means, look in order to better understand how Magento works, but do not touch.

COMMUNITY

As the name suggests, app/code/community is where you will find modules that have been provided by third parties (i.e. not Magento’s core team). Hundreds of modules are available through Magento Connect, and when you install them through the built-in “Package Manager,” this is where they end up.

LOCAL

Magento ships with an empty app/code/local directory, ready for you to add bespoke modules for your own Magento installation. This is where we will be working for the duration of this tutorial.

Structuring Our Directory

Open your favorite editor, and navigate to app/code/local to add some new directories and files.

MODULE NAMESPACE

The first directory we will create is a “namespace.” This can be called anything you like, but the convention is some form of the name of the company or module’s author. Magento uses “Mage” as its namespace. Here at Ampersand Commerce, we use “Ampersand.” For this tutorial, we will use “SmashingMagazine” as our namespace. So, create the directory app/code/local/SmashingMagazine.

MODULE NAME

For the next directory, we will give our module a descriptive name. The module we are creating will write log entries each time a product is saved, so a logical name would be LogProductUpdate. Create the directory app/code/local/SmashingMagazine/LogProductUpdate.
We should now have the following directory structure for our module. These directory and file names are case-sensitive, so capitalize where appropriate.
app
  - code
      - local
          - SmashingMagazine
              - LogProductUpdate

Configuring Our Module

Next, we will begin to configure our module. The configuration files belong inside our module in a directory named etc, so let’s create that along with a new XML file:app/code/local/SmashingMagazine/LogProductUpdate/etc/config.xml. This XML file will inform Magento of the location of the files in our module, as well as many other things, such as version number and events to observe. For now, we will create a simple config.xml file, which contains comments that explain the meaning of each section.



<config> 

    
    <modules>

        
        <SmashingMagazine_LogProductUpdate>

            
            <version>0.0.1</version>

        </SmashingMagazine_LogProductUpdate>

    </modules>

</config>

Activating Our Module

The next step is to inform our Magento installation that our module exists, which we do by creating a new XML file in app/etc/modules. The name of this XML file can be anything you like, since Magento will read all XML files in this directory and will be interested only in the content. However, by convention we should give the file and module the same name. Let’s createapp/etc/modules/SmashingMagazine_LogProductUpdate.xml with the following content:

<config>
    <modules>
        <SmashingMagazine_LogProductUpdate>

            
            <active>true</active>

            
            <codePool>local</codePool>

        </SmashingMagazine_LogProductUpdate>
    </modules>
</config>

Sanity Check: Is The Module Enabled?

We now have a fully functional module that is enabled in Magento. It doesn’t do anything, but it is a valid module. This is our first opportunity to see whether we have correctly configured everything so far. If we log into the Magento admin panel and navigate to System > Configuration > Advanced > Advanced and view the “Disable Modules Output” listing, we should see ourSmashingMagazine_LogProductUpdate module listed as enabled. If it is not listed, then something has gone wrong, so carefully run through the steps up to this point again. This is usually when new Magento developers discover the cache!
Our module’s structure now looks like this:
app
  - code
      - local
          - SmashingMagazine
              - LogProductUpdate
                  - etc
                      - config.xml

  - etc
      - modules
          - SmashingMagazine_LogProductUpdate.xml

Defining An Event Observer

Event observers are extremely powerful and are one of the cleanest ways to extend Magento’s functionality without having to rewrite or override any core methods or classes. We want to observe the event that Magento dispatches just after a product is saved, so the code for the event we are interested in is catalog_product_save_after. Determining which event code to use when defining a new observer requires a basic understanding of Magento’s model layer, which is beyond the scope of this tutorial. Don’t worry, though: we’ll cover it another time!
We now need to modify our config.xml to include the event observer definition:

<config>
    <modules>
        <SmashingMagazine_LogProductUpdate>
            <version>0.0.1</version>
        </SmashingMagazine_LogProductUpdate>
    </modules>

    
    <global>

        
        <events>

            
            <catalog_product_save_after>

                
                <observers>

                    
                    <smashingmagazine_logproductupdate>

                        
                        <class>smashingmagazine_logproductupdate/observer</class>

                        
                        <method>logUpdate</method>

                        
                        <type>singleton</type>

                    </smashingmagazine_logproductupdate >

                </observers>

            </catalog_product_save_after>

        </events>

    </global>

</config>

Configuring Our Model’s Directory

In the event observer defined above, we made reference to a model that we have not yet created. We need to inform Magento where to find models in our module by updating config.xml with the following:

<config>
    <modules>
        <SmashingMagazine_LogProductUpdate>
            <version>0.0.1</version>
        </SmashingMagazine_LogProductUpdate>
    </modules>

    
    <global>

        
        <models>

            
            <smashingmagazine_logproductupdate>

                
                <class>SmashingMagazine_LogProductUpdate_Model</class>

            </smashingmagazine_logproductupdate>

        </models>

        <events>
            <catalog_product_save_after>
                <observers>
                    <smashingmagazine_logproductupdate>
                        <class>smashingmagazine_logproductupdate/observer</class>
                        <method>logUpdate</method>
                        <type>singleton</type>
                    </smashingmagazine_logproductupdate >
                </observers>
            </catalog_product_save_after>
        </events>

    </global>

</config>

Creating An Observer Model

We will now create the model to be instantiated when the event is dispatched. Create a new PHP file in app/code/local/SmashingMagazine/LogProductUpdate/Model/Observer.php with the following content:

/**
 * Our class name should follow the directory structure of
 * our Observer.php model, starting from the namespace,
 * replacing directory separators with underscores.
 * i.e. app/code/local/SmashingMagazine/
 *                     LogProductUpdate/Model/Observer.php
 */
class SmashingMagazine_LogProductUpdate_Model_Observer
{
    /**
     * Magento passes a Varien_Event_Observer object as
     * the first parameter of dispatched events.
     */
    public function logUpdate(Varien_Event_Observer $observer)
    {
        // Retrieve the product being updated from the event observer
        $product = $observer->getEvent()->getProduct();

        // Write a new line to var/log/product-updates.log
        $name = $product->getName();
        $sku = $product->getSku();
        Mage::log(
            "{$name} ({$sku}) updated",
            null, 
            'product-updates.log'
        );
    }
}

We’re done! Try it out.

The directory structure for our completed module should now look like this:
app
  - code
      - local
          - SmashingMagazine
              - LogProductUpdate
                  - Model
                      - Observer.php

                  - etc
                      - config.xml

  - etc
      - modules
          - SmashingMagazine_LogProductUpdate.xml
Now that our module is complete, it’s time to try it out! Log into the Magento admin panel, create or update a product in your catalog, and then check the var/log folder to see your product-updates.log file populated.
If nothing appears or the directory does not exist, ensure that the correct permissions are set to allow Magento to write to this directory, and that logging is enabled in Admin Panel > System > Configuration > Developer > Log Settings > Enabled.
This basic tutorial is meant to give you an overall understanding of how Magento modules work. After completing this tutorial, spend some time exploring the Magento modules in app/code/core and see if you now have a better idea of how it all works.

curtsy: Joseph McDermott

View blog reactions