PHP custom session handler changes in PHP7

If you are using a custom session handler probably you noticed this kind of issue when you upgraded to PHP7. Keep this information in mind since in the PHP documentation it is not really clear at the moment of writing this article.

Since PHP 5 these changes affected custom session handler implementation:

  • The read method should return an empty string if the session was not started yet
  • The write method should return either true or false

Git useful commands and tricks

  1. Delete all merged branches
    git branch --merged master | grep -v master | xargs git branch -d
    
    //Or maybe you want to keep only few branches 
    git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep1>|<Branch_You_Want_to_Keep2>/) printf "%s", $0 }'`
    
  2. Add new origin
    git remote rm origin
    git remote add origin ssh://git@git.zitec.ro:6246/george.babarus/dpd_presta.git
     

How to enable SSL certificate on Nginx

First of all, you have to check if your webserver version supports SSL. If SSL is not enabled in your server read more here

If the SSL module is installed in your Nginx instance then you have a few simple steps to follow.

  1. Generate Certificate Signing Request (CSR)
    • Generate private key
    • Login into the server by ssh
      
      openssl genrsa -out www.domain.com.key 2048
    • Generate the CSR
    • openssl req -new -key www.domain.com.key -out www.domain.com.csr
      
  2. Create a backup of the private key in a secure place it will be useful
  3. Request Certificate – with the CSR generated above you can go to a provider to sign your certificate.
  4. Install the certificate
    • You have to receive the keys from your SSL certificate provider: your primary certificate and the intermediate certificate.
    • create one file with both files
    • Upload to the server in a safe place with read access for the root user
    • Edit your host configuration on Nginx
    • server {
      
              listen 443 default ssl;
              server_name .domain.com;
              ssl_certificate      /etc/ssl/www.domain.com.crt;
              ssl_certificate_key  /etc/ssl/www.domain.com.key;
       keepalive_timeout    70;
              # other configuration
       ...
      }
    • Test your Nginx configuration and restart the service if everything is fine.
  5. Done

Recompile Nginx

  1. Create backups for all Nginx files.
  2. "cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_old"
    "cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.old"
  3. Download all sources and dependencies for Nginx
  4. #You can check previous configuration parameters by 
    nginx -V
    
    #Download all needed sources
    wget http://nginx.org/download/nginx-1.6.3.tar.gz
    wget https://github.com/pagespeed/ngx_pagespeed/archive/v1.9.32.10-beta.tar.gz
    wget https://github.com/openresty/headers-more-nginx-module/archive/v0.28.tar.gz nginx-headers.tar.gz
    wget https://dl.google.com/dl/page-speed/psol/1.9.32.10.tar.gz
    
    #Extract them 
    tar -zxvf file.tar.gz
    
  5. Configure the compilation with custom parameters. You can even specify another binary location for the newly compiled software. In this way, all the installed software will sill exist in the original location. In my case, I decided to overwrite the existing binary of Nginx.
    “/usr/local/nginx/sbin/nginx -V”
  6. ./configure  --add-module=/home/ec2-user/headers-more-nginx-module-0.28 --add-module=/home/ec2-user/ngx_pagespeed-1.9.32.10-beta --with-http_ssl_module
  7. Compile and install
  8. sudo make
    sudo make test
    #run: "make install clean" This will install the new binary in place of the old one and  makes a backup of the old one.
    sudo make install
  9. Sometimes this step is a little bit risky because some files may be opened and could not be overwritten. In my case, everything worked fine.  Even if the service was running in this time, the binary was already replaced.
  10. If you decided to go on a safer way and installed the binary in another place, now all you have to change is defining your daemon to use this binary instead of the old one, test the Nginx configuration and restart the service.

A much more complex approach may be found here

Upgrade MySql 5.5 to 5.6 on Ubuntu 14.04

If you are already using MySql 5.5 and some new applications is requiring a newer version you can proceed a upgrade with the following steps

  1. Check if there is available a binary version for your operating system
  2. If you are using Ubuntu14.04 there is available a Mysql 5.6 version. If not, you have to register other repository
  3. Create a backup just in case somethings will go wrong
    mysqldump --lock-all-tables -u root -p --all-databases > dump.sql
  4. Upgrade
  5. sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install mysql-server-5.6
  6. If something was wrong until now you can remove previous version and separately install the new one.
  7. You can restore the information by
    mysql -u root -p < dump.sql

Install PHP 7 and xdebug for development environment

PHP 7 was released

Compile PHP 7 from source for development environment

git clone git@github.com:php/php-src.git && cd php-src

./buildconf

./configure \
--with-freetype=/usr/local \
--with-config-file-path=/opt/php7/config.d \
--with-config-file-scan-dir=/opt/php7/conf.d \
--prefix=/opt/php7 \
--with-zlib-dir \
--with-freetype-dir \
--enable-mbstring \
--with-libxml-dir=/usr \
--enable-soap \
--enable-calendar \
--with-curl \
--with-mcrypt \
--with-zlib \
--with-gd \
--disable-rpath \
--enable-inline-optimization \
--with-bz2 \
--with-zlib \
--enable-sockets \
--enable-sysvsem \
--enable-sysvshm \
--enable-pcntl \
--enable-mbregex \
--with-mhash \
--enable-zip \
--with-pcre-regex \
--with-mysql \
--with-pdo-mysql \
--with-mysqli \
--with-png-dir=/usr \
--enable-gd-native-ttf \
--with-openssl \
--with-fpm-user=nginx \
--with-fpm-group=nginx \
--with-libdir=lib \
--enable-ftp \
--with-imap \
--with-imap-ssl \
--with-kerberos \
--with-gettext \
--with-gd \
--with-xpm-dir=/usr \
--with-ldap=/usr \
--with-jpeg-dir=/usr/lib/ \
--enable-fpm \
--with-fpm-user=www-data \
--with-fpm-group=www-data \


make
make test
make install

Install xdebug from sources, since there are no available binaries compatible with PHP7

  1. Download xdebug source archive
  2. Unzip the source code
  3. Check the PHP version /opt/php7/bin/phpize
  4. configure the compile process with this php version ./configure –with-php-config=/opt/php7/bin/php-config
  5. make
  6. make install
  7. Add the extension to ini file
  8. Configure xdebug
  9. xdebug.remote_enable=true
    xdebug.remote_port="<the port for XDebug to listen to>" (the default port is 9000)
    xdebug.remote_host=<the host where PhpStorm is running (e.g. localhost)>
    xdebug.remote_handler=dbgp 
    xdebug.remote_mode=req
    xdebug.idekey=PHPSTORM
    xdebug.profiler_enable=1
    xdebug.profiler_output_dir="<AMP home\tmp>"

Cloud-based Infrastructure for Black Friday

Earn more money during sales campaigns using a cloud-based infrastructure

During the largest online sales events of the year, all retailers are very excited to sell as much as they can sell. But what if the online platform is not able to support such amount of traffic. Is your website ready for Black Friday?

Few advantages of using cloud platforms for this purpose:

    • you have as many resources as you may want
    • you don’t need to be afraid of hardware issues
    • up-time is guaranteed for some services
    • you pay as you use
    • you can easily build a very stable/professional application
    • overall cost

Compile Nginx from source

Probably you are setting a virtual host on one of the cloud providers. Read here  few references on cloud computing provides

Configure Nginx with extra modules

The first step is to figure out which modules of Nginx you will be using. Read Nginx documentation and download all dependencies.

For example, I will download ngx_cache_purge from git and some few other Nginx modules

git clone https://github.com/phusion/passenger_apt_automation.git
git clone https://github.com/FRiCKLE/ngx_cache_purge.git
git clone https://github.com/openssl/openssl.git

Depending on which modules you will use probably you will need to install some libraries (depending on your operating system) as shown below.

 apt-get install libxml2-dev
 apt-get install libxslt-dev
 apt-get install libgd2-xpm libgd2-xpm-dev
./configure --sbin-path=/usr/sbin/nginx --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_spdy_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-openssl=/usr/local/src/openssl-1.0.1j --add-module=/usr/local/src/passenger_apt_automation/debian_specs/nginx/modules/nginx-auth-pam --add-module=/usr/local/src/passenger_apt_automation/debian_specs/nginx/modules/nginx-echo --add-module=/usr/local/src/passenger_apt_automation/debian_specs/nginx/modules/nginx-upstream-fair --add-module=/usr/local/src/passenger_apt_automation/debian_specs/nginx/modules/nginx-dav-ext-module --add-module=/usr/local/src/ngx_cache_purge

Configure

The output of this command may be similar to:

 Configuration summary
 + using system PCRE library
 + using OpenSSL library: /usr/local/src/openssl-1.0.1j
 + md5: using OpenSSL library
 + sha1: using OpenSSL library
 + using system zlib library
 nginx http scgi temporary files: "/var/lib/nginx/scgi"

Build Nginx and install

If the configure step was successfully finished, then you can try to build and install Nginx by following commands.

 make
 make install

Cloud computing providers overview and nice cloud features

When it comes to scaling your application (PHP or no matter what languages or technologies) of course you are looking to optimize the software part, but of course, the hardware is important too.

Even if you are a start-up or a big business  you can optimize your monthly cost or performance using the right solution.

Features

  • Digital ocean is a nice service but there are a few week points:
    1. you can not attach additional storage for virtual machines
    2. there are no other services you can use, the virtual machine will be everything you have
  • Amazon AWS
    1. there are a lot of interesting features you can use and managed services, this will be a big plus
    2. all services I used until now worked perfectly
    3. flexible management tools
  • Azure
    1. a lot of features and services
    2. managed services
    3. personally, I encountered a lot of problems with virtual machines performances on Azure
    4. few of the problems were resolved

Pricing

  • Digital ocean it is cheaper and offers a very good performance
  • AWS I think it has the best features/price score I tested until now
  • Azure – I think I need to test it more until I will show my opinion.

In conclusion, I will recommend the next cloud computing providers in a few use cases:

  • Digital Ocean, if you are developing a small project and you are not needing advanced cloud computing features. It is not flexible on storage service
  • Amazon AWS, best for ambitious projects, full feature cloud computing service

Performance benchmark PHP 5 , PHP 5 + Opcache, PHP 5 + APC, HHVM

Is PHP good for any application?

PHP is the most popular language on web-based applications with a huge amount of opensource components/reusable code and powered by a big community. I think it is important to understand it’s architecture first and then talk about scaling the application. And this may be a good reason to consider PHP as one of the best languages for a start-up or low budget project. Maybe I can add more reasons here as deployment flow or development efficiency or others.

What if the business grows very fast?

So, what? There are a lot of tricks you can use.

PHP vs HHVM

Since PHP is an interpreted language some use-cases can prove PHP lazy.

HHVM is an opensource project powered by Facebook to add more power to PHP projects. In this way, there are few improvements to the interpreter. HHVM is a just-in-time compiler for PHP, meaning, that the code is not interpreted every time but the generated byte code is saved and reused. HHVM tries to resolve a few week points as variable type missing, functions – variables – constants lookup time, and others.

The result of my benchmark could surprise you.

The benchmark is made on Magento 1.9, the most popular e-commerce platform in the PHP ecosystem.

Compare PHP with HHVM

I used the default configuration for all scenarios and, as you can see in the table above, just using HHVM you can obtain a 3.5X performance gain over PHP 5.6X. But the difference is not so big if on the standard PHP interpreter you are using APC cache or OPCACHE.

grafic-tranzactiii-php-vs-hhvm

Requests/min / Concurrent users

See the performance gain in the following graph

performance-gain-PHP-HHVM

The average response time is much more stable using hhvm due to all optimizations made, as you can see below.

response-time-hhvm-php

In my test, I used 15 concurrent users up to 250 concurrent users and below we can see the availability state of the service during the test.

availability

Configure Zend Opcache extension for PHP

Zend Opcache extension installation

If you want to speed up your PHP application maybe you are looking for a PHP accelerator such APC cache.

Since PHP 5.5 there is another option for caching Opcodes (details): Zend OpCache extension

If you are using PHP 5.5.0 and later Zend Opcache extension may be compiled with PHP, you have only to configure it.

If you are using an older version of PHP you can compile the extension following a few simple steps:

  • Download the latest version here https://github.com/zendtech/ZendOptimizerPlus
  • Configure the compilation with your PHP config
  • ./configure \
          --with-php-config=$PHP_DIR/bin/php-config
  • Build the package
    make
    
  • The install command will copy the binary file to your extension directory (or you can copy by your own)
     make install

After the compilation was successfully finished you can declare your new extension into php.ini file

 zend_extension=/...full path.../opcache.so

 Zend Opcache configuration

The full parameters list are listed on Zend Opcache documentation

I will just mention a few parameters you have to consider in your configuration

opcache.revalidate_freq=0
opcache.validate_timestamps=0
opcache.max_accelerated_files=7963
opcache.memory_consumption=192
opcache.interned_strings_buffer=16
opcache.fast_shutdown=1
  •  revalidate_freq – configure how often the file timestamp is checked to detect file changes. 0 – means check every time. You have to configure revalidate_freq 0 on your development machine. On production, I am using a large number such as 3600
  • validate_timestamps – When disabled, you must reset the OPcache manually or restart the webserver for changes to the filesystem to take effect. I advise you to use it on the production server and create a hook to clear Opcache after release
  • max_accelerated_files  – the maximum number of scripts stored in opcached memory. you can count your code-base using find . -type f -print | grep php | wc -l
  • memory_consumption – the amount of memory to store pre-compiled PHP files

You can read here a performance benchmark report here on the same subject.

Install APC extension for PHP from sources

How to compile the PHP APC extension for your PHP version

Used operating system: Ubuntu 14.04

There are few steps to follow until you will have your APC extension up and running for your particular PHP version:

  • Download the latest version of APC
  • wget http://pecl.php.net/get/APC
  • Extract files and identify the default values for the following parameters PHP Extension,
    Zend Extension using “phpize”
  • tar -xvf APC
    cd APC-X.X.X (replace with your downloaded version)
    phpize
  • If you are running more then one version on the same machine you will need to configure the compilation with the target version of PHP
  • In my case, I used this command to configure the compilation
  • ./configure --with-php-config=/opt/php-5.3/bin/php-config --enable-apc --enable-apc-debug
  • if everything worked ok, then you can compile your extension using make && make install
  • The last step is to enable and configure your extension in the php.ini file (echo “extension=apc.so” > /etc/php.d/apc.ini)
  • Restart PHP service

You can read here a performance benchmark report here on the same subject.

Find in files – translations texts

Use case

Follow this article if you want to locate multiple occurrences of a string in a folder using a regular expression pattern.

 Find all occurrence of pattern

Using the following code in the Linux command line you will copy all occurrence of the given pattern in a temporary file

 find ./ -name '*.*' -exec grep -o -E "language->get(.*?)" {} > output.txt  \;


OR you can use this 

find ./ -name '*.*' -exec grep -o -E -Hn "language->get(.*?)" {} > output.txt2  \;

Process found parts

Using a simple text editor compatible with the regular expression you will be able to process the temporary file to the wanted format.

See the attached screenshot.

notepad-search-and-replace

In my case I had to find all $this->get(‘Any text here’) in my PHP files and create a translation file for the Opencart platform in the following format:

$_['Any text here'] = 'Any text here';
$_['Any text here'] = 'Any text here';

Manage RDS instances with AWS CLI

Introduction

Why do you need to use RDS CLI?

There are some actions that you may want to execute on your instance but you are not allowed to make from the web interface:

  • change the parameters group

Install RDS CLI tools

To be able to use RDS CLI tool you have to install Java, download RDS CLI tool and configure few environment variables.

All configuration steps are listed here:

As shown in the related article if the command

rds --help

is working then the CLI tools was successfully installed.

RDS CLI usage

As you already completed the configuration steps (very important: don’t forget to set the path to your credentials to be able to use any further commands).

rds-modify-db-instance

Read more

 rds-modify-db-instance DBInstanceIdentifier --db-parameter-group-name fp-param-group --region eu-west-1

DBInstanceIdentifier – This is the unique key that identifies a DB instance. Stored as a lowercase string. This is provided at instance creation time, or modified later, and can be found at the beginning of instance Endpoint.

Very important:  If you are not providing the –region parameter the CLI will use the default region, and can return the wrong results.

Use more than one PHP version in Nginx

In some cases probably you need to have different PHP versions on the same machine and using it on different domains.

Install PHP

You can install PHP versions by downloading already compiled packages or you can compile your own (with personalized configuration – quick PHP compile & install guide).

Personally, I prefer for development machines to compile PHP by myself.  You can read how I prefer to install PHP in the linked article.

PHP FPM

In your “php-fpm” configuration file there is an option to specify the port used to listen:

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses on a
;                            specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = 127.0.0.1:9562

Nginx

The next step is to define the upstream in Nginx configuration, to be able to pass the requests to PHP.  Next, you will have a few examples:

# This will define upstream to local PHP-FPM server; for tools like 
upstream local-phpfpm {
	server   127.0.0.1:9053;
}
upstream phpfpm {
	#server unix:/var/run/php5-fpm.sock;
	server   127.0.0.1:9053;
}
upstream php53fpm {
	server   127.0.0.1:9053;
}
upstream php56fpm {
	server  127.0.0.1:9562;
}

Next time when you will configure a virtual host on your machine you will be able to use different PHP version on the same machine:

    location ~ .php$ { ## Execute PHP scripts
        fastcgi_pass    php53fpm;
        include        fastcgi_params; ## See /etc/nginx/fastcgi_params
    }


OR


    location ~ .php$ { ## Execute PHP scripts
        fastcgi_pass    php56fpm;
        include        fastcgi_params; ## See /etc/nginx/fastcgi_params
    }

Install PHP 5.x from repository on Ubuntu

Install build tool

Here are detailed steps for installing the compile tool for ubuntu.

Install dependencies

In most cases, quite a lot of dependencies will be missing. You can install most of them using the next command

sudo apt-get install libxml2-dev libpcre3-dev libbz2-dev libcurl4-openssl-dev libdb4.8-dev libjpeg-dev libpng12-dev libxpm-dev libfreetype6-dev libmysqlclient-dev postgresql-server-dev-9.1 libt1-dev libgd2-xpm-dev libgmp-dev libsasl2-dev libmhash-dev unixodbc-dev freetds-dev libpspell-dev libsnmp-dev libtidy-dev libxslt1-dev libmcrypt-dev

Compile and install PHP

Clone the PHP repository

sudo mkdir /opt/source && cd /opt/source
git clone git@github.com:php/php-src.git && cd php-src

Choose the version of PHP you want to compile and install

  PHP 5.3:  git checkout PHP-5.3
  PHP 5.4:  git checkout PHP-5.4
  PHP 5.6:  git checkout PHP-5.6
  PHP HEAD: git checkout master

To building PHP from a git repository, first, you have to run sudo ./buildconf .

./buildconf generates the configuration script. This may take several minutes.

 Create the folder where you want to install the PHP:

Suggestion:

sudo mkdir -p /opt/php-5.6
sudo mkdir -p /opt/php-5.5

 Configure build

Once the ./configure script is generated via the step above, you can use it to customize your PHP build. You can list all supported options using –help:

 ./configure \
--with-freetype=/usr/local \
--with-config-file-path=/opt/php-5.6/config.d \
--with-config-file-scan-dir=/opt/php-5.6/conf.d \
--prefix=/opt/php-5.6 \
--with-zlib-dir \
--with-freetype-dir \
--enable-mbstring \
--with-libxml-dir=/usr \
--enable-soap \
--enable-calendar \
--with-curl \
--with-mcrypt \
--with-zlib \
--with-gd \
--disable-rpath \
--enable-inline-optimization \
--with-bz2 \
--with-zlib \
--enable-sockets \
--enable-sysvsem \
--enable-sysvshm \
--enable-pcntl \
--enable-mbregex \
--with-mhash \
--enable-zip \
--with-pcre-regex \
--with-mysql \
--with-pdo-mysql \
--with-mysqli \
--with-png-dir=/usr \
--enable-gd-native-ttf \
--with-openssl \
--with-fpm-user=nginx \
--with-fpm-group=nginx \
--with-libdir=lib \
--enable-ftp \
--with-imap \
--with-imap-ssl \
--with-kerberos \
--with-gettext \
--with-gd \
--with-xpm-dir=/usr \
--with-ldap=/usr \
--with-jpeg-dir=/usr/lib/ \
--enable-fpm \
--with-fpm-user=www-data \
--with-fpm-group=www-data \


Compile PHP

Now, you can use make to perform the actual compilation:

make

 Install PHP

Now you can run “make install” to install PHP into “/usr/local” (default) or another directory by using the --prefixconfiguration. In this case, it’s /opt/php-5.6

sudo make install

Please note that make install will not create an ini file.

/opt/php-5.6/bin/php --ini
Configuration File (php.ini) Path: /opt/php-5.6/lib
Loaded Configuration File:         (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

Copy config files

sudo cp /opt/source/php-src/php-fpm.conf.default /opt/php-5.6/etc/php-fpm.conf
sudo cp /opt/source/php-src/php.ini-production /opt/php-5.6/lib/php.ini

Open /opt/php-5.6/etc/php-fpm.conf and adjust the value in the listen line. You must change to an unused port (e.g. 9001)

Init script setup

You will probably want to create an init script for your new “php-fpm”. Luckily, PHP 5.3+ already provides it for you, simply copy the init script to your directory and change permissions:

1
2
sudo cp /opt/source/php-src/sapi/fpm/init.d.php-fpm /etc/init.d/php5.6-fpm
sudo chmod 755 /etc/init.d/php5.6-fpm

Your init script is ready. Now, you are able to start, stop, and reload php-fpm:

1
2
3
sudo /etc/init.d/php5.6-fpm start
sudo /etc/init.d/php5.6-fpm stop
sudo /etc/init.d/php5.6-fpm reload

Create an alias for every command:

alias p56start='sudo /etc/init.d/php5.6-fpm start'
alias p56stop='sudo /etc/init.d/php5.6-fpm stop'
alias p56r='sudo /etc/init.d/php5.6-fpm restart'

alias p53start='sudo /etc/init.d/php5.3-fpm start'
alias p53stop='sudo /etc/init.d/php5.3-fpm stop'
alias p53r='sudo /etc/init.d/php5.3-fpm restart'

alias nginxr='sudo service nginx restart'

Magento – BNR currency import module for RON

Automatically currency rate import for RON currency in your Magento e-commerce

You can download here: https://github.com/georgebabarus/mage-bnr-currency-import

Or you can create your own currency import module following the next instructions, it is very simple:

Build your own Magento e-commerce – currency rate import extension

  1. declare your currency import model in etc/config.xml file
        <global>
            <currency>
                <import>
                    <services>
                        <bnr>
                            <name>BNR RON</name>
                            <model>bb_bnr/currency_import_bnr</model>
                        </bnr>
                    </services>
                </import>
            </currency>
    
            <models>
                <bb_bnr>
                    <class>Bb_Bnr_Model</class>
                </bb_bnr>
            </models>
        </global>
  2. Next, in the Bb_Bnr_Model_Currency_Import_Bnr class definition extend the class  Mage_Directory_Model_Currency_Import_Abstract 
  3. This class have to implement the function  protected function _convert($currencyFrom, $currencyTo, $retry=0). This function has to return the currency rate between “currencyFrom” and “currencyTo” as float.