How to install Ioncube Loader PHP on Linux Ubuntu

Ioncube Loader Extenion allows to run encoded PHP scripts by Ioncube Encoder.

  • Ioncube Loader Extension – extension which starts witch PHP process that can read and run encoded files. The extension is free.
  • Ioncube Encoder – software that allows encode and obfulscate PHP scripts using license key to description.

This tutorial shows how to install Ioncube Loader Extension.

1. Download Ioncube loader extension.

Go to the http://www.ioncube.com/loaders.php url and locate your proper platofrm version.

If you are not sure what platform (x86 or 64-bit, TS or NTS ) you need, just run phpinfo() and read from “System” and “PHP Extension Build”. For example this entry looks like:

System: Linux athlan-VirtualBox 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64

PHP Extension Build: API20121212,NTS

I am using 64-bit platform, NTS (non-thread safe).

So copy proper link and call:

wget http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz

Extract the package

tar xvfz ioncube_loaders_lin_x86-64.tar.gz

athlan@athlan-VirtualBox:~/tmp/ioncube$ ls -1
ioncube_loader_lin_4.1.so
ioncube_loader_lin_4.2.so
ioncube_loader_lin_4.3.so
ioncube_loader_lin_4.3_ts.so
ioncube_loader_lin_4.4.so
ioncube_loader_lin_4.4_ts.so
ioncube_loader_lin_5.0.so
ioncube_loader_lin_5.0_ts.so
ioncube_loader_lin_5.1.so
ioncube_loader_lin_5.1_ts.so
ioncube_loader_lin_5.2.so
ioncube_loader_lin_5.2_ts.so
ioncube_loader_lin_5.3.so
ioncube_loader_lin_5.3_ts.so
ioncube_loader_lin_5.4.so
ioncube_loader_lin_5.4_ts.so
ioncube_loader_lin_5.5.so
ioncube_loader_lin_5.5_ts.so
ioncube_loader_lin_5.6.so
ioncube_loader_lin_5.6_ts.so
LICENSE.txt
loader-wizard.php
README.txt
USER-GUIDE.txt

2. Copy extension to PHP extension dir

Locate your extenion dir:

athlan@athlan-VirtualBox:~/tmp/ioncube$ php -i | grep extension_dir
extension_dir => /usr/lib/php5/20121212 => /usr/lib/php5/20121212

Copy here your proper loader, in my case:

cp ./ioncube_loader_lin_5.5.so /usr/lib/php5/20121212

3. Add extension to php.ini file

You must add Ioncube Loader to php.ini file pointing proper file:

zend_extension=ioncube_loader_lin_5.5.so

Make sure that extension is the first loaded extension for PHP, because the error will appear:

PHP Fatal error: Unable to start ionCube Loader module in Unknown on line 0

In my Ubuntu the extensions directory are under: /etc/php5/mods-available directory – one per extension. So define ioncube.ini file. In php+apache2 for ubuntu there are configuratios groupped by environment, one is apache2, so I make symbolic link to include my .ini file:

ln -s .etc/php5/mods-available/ioncube.ini /etc/php5/apache2/conf.d/01-ioncube.ini

I named my file by prefix 01- to make sure that it will be the first included extension.

4. Check configuration

Make file with phpinfo() and check if Ioncube is loaded under “Additional Modules” and “with the ionCube PHP Loader (enabled) + Intrusion Protection from ioncube24.com (unconfigured) v5.0.11, Copyright (c) 2002-2015, by ionCube Ltd.”:

ioncube-phpinfo

ioncube-phpinfo2

Done!

Known issues:

Apache hangs while start

The apache2 instance did not start within 20 seconds. Please read the log files to discover problems

Probably you have not proper version of your extension included (TS or NTS). Please verify that comparing to your phpinfo() “System” and “PHP Extension Build”.

Invalid extension definition

[Sat Jul 11 15:44:24 2015] [warn-phpd] The ionCube Loader is a Zend-Engine extension and not a module (pid 3038)
[Sat Jul 11 15:44:24 2015] [warn-phpd] Please specify the Loader using ‘zend_extension’ in php.ini (pid 3038)

You have included Ioncube by extension= while zend_extension= should be used.

Ioncube Loader is loaded after another extensions

PHP Fatal error: [ionCube Loader]
The Loader must appear as the first entry in the php.ini file in Unknown on line 0

You have to specify zend_extension directive in php.ini as a first extension loaded. To make sure, just place it as a first line.

 

Symfony2 Redis Session Handler

Context

When you scale a PHP

application you have to consider several aspects of runtime environment such us:

  • Bytecode caching (e.x. APC or Zend Optimizer Plus or eAccelerator), more;
  • Reading project files from RAM instead of HDD;
  • Caching and minify static content etc.
  • One additional aspect is storing sessions.

By default, PHP stores sessions in files. There are also several approaches to speed up saving sessions, such us memcached, mapping save_path folder as ramdisc, etc.

In scaling approaches there is important that many worker nodes (with deployed application) runs the same code, round-robin selected or load-ballanced, but have the same space to store sessions, because there is no guarantee in distributes architecture, that next user’s request will be handled by the same node. This implies, that session memory have to be shared between nodes, unfortunately storing these data in local

RAM doesn’t meet this requirement.

Redis as PHP Session Handler

One of additional approach to storing sessions in fast-memory is Redis – key-value store. This could be configured as centralized or distributed database.

There is available a Redis session_handler for PHP. To use it:

  1. install Redis first as a service [more]
  2. copy/compile redis.so PHP extension [more information]
  3. register an extension in php.ini configuration file
  4. reconfigure session.save_handler in your php.ini configuration file, or set it directly on runtime by writing for e.x.:
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://localhost:6379');
Redis Session Handler in Symfony 2

I am using Symfony 2 framework. Unfortunately, 4th step don’t affects the application. You have to register own SessionHandler in config.yml file:

framework:
 session:
 handler_id: session_handler_redis

This configuration uses new SessionHandler registered ad session_handler_redis Symfony Service (more).

We have to write own SessionHandler in Symfony. I have found the Redis SessionHandler proposed by Andrej Hudec on GitHub (original code here). I have decided to use and improve existing implementation.

Declare new SessionHandler class somewhere in your project:

<?php
 
namespace Fokus\Webapp\CommonBundle\SessionHandler;
 
use \Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
 
/**
 * NativeRedisSessionStorage.
 *
 * Driver for the redis session <div id="R77EHMs" style="position: absolute; top: -1183px; left: -1358px; width: 243px;"></div> save hadlers provided by the redis PHP extension.
 *
 * @see https://github.com/nicolasff/phpredis
 *
 * @author Andrej Hudec &lt;pulzarraider@gmail.com&gt;
 * @author Piotr Pelczar &lt;me@athlan.pl&gt;
 */
class NativeRedisSessionHandler extends NativeSessionHandler
{
 /**
 * Constructor.
 *
 * @param string $savePath Path of redis server.
 */
 public function __construct($savePath = "")
 {
 if (!extension_loaded('redis')) {
 throw new \RuntimeException('PHP does not have "redis" session module registered');
 }
 
 if ("" === $savePath) {
 $savePath = ini_get('session.save_path');
 }
 
 if ("" === $savePath) {
 $savePath = "tcp://localhost:6379"; // guess path
 }
 
 ini_set('session.save_handler', 'redis');
 ini_set('session.save_path', $savePath);
 }
}

Now, add the entry that declares

the class as a Symfony Service in services.yml file:

services:
 session_handler_redis:
 class: Fokus\Webapp\CommonBundle\SessionHandler\NativeRedisSessionHandler
 arguments: ["%session_handler_redis_save_path%"]

I have improved Andrzej’s code that you can configure the session handler calling it’s constructor and pass the Redis connection string just in services in Symfony, without touching ini_set or php.ini settings. As you see, the %session_handler_redis_save_path% parameter has been used.

Now, declare the value of parameter in parameters.yml file:

session_handler_redis_save_path: tcp://localhost:6379

That’s all!

Just refresh your page, use the session such us in after loging and check out if it works. Type in command line:

redis-cli

and show all keys stored by PHP Session Handler. Keys begins with string PHPREDIS_SESSION:.

KEYS PHPREDIS_SESSION*

Example output:

redis 127.0.0.1:6379> KEYS PHPREDIS_SESSION*
1) "PHPREDIS_SESSION:s4uvor0u5dcsq5ncgulqiuef14"
2) "PHPREDIS_SESSION:dcu54je80e6feo5rjqvqpv60h7"

Hope it helped!

 

VirtualBox Linux server on Windows

Howdy! Recently I have faced the inconvenience that I have to develop parts of application beeing friendly-configurable on Linux and at the same time installing them on Windows is a nightmare.

What to do when do you develop on Windows, but you need the production environment based on Linux and you don’t want to buy server? Install Linux locally on Windows and run server on VirtualBox installed on Windows. The same story concerns the situation, when the production server have a lot of shit dependencies you don’t want to have on your developing environment, even it is Linux.

So how to connect VirtualBox Linux server from Windows?

  1. Download the VirtualBox and Linux distribution you want to install (.iso format will be convinience). I

    have coised Ubuntu, because of  rapid installation.

  2. Create a new virtual machine for your Linux. More info.
  3. Mount your .iso and install Linux on VirtualBox. Installation is really user-friendly.
  4. Now go to the setting of your virtual machine -> network adapters settings -> and change your network adapter to NAT. More info.
  5. Check if everything is ok, in particular that network adaper on virtual machine obtained the IP address. Just type:
    /sbin/ifconfig

    or:

    /sbin/ifconfig | grep addr

    Note the assigned IP address.

  6. Try to ping your virtual machine from host operating system, where VirtualBox is running:
    ping virtaul_machine_ip_address
  7. If everything is ok, your machines works mutualy. Now, install Open SSH server on your linux. For ubuntu:
    sudo apt-get install openssh-server
  8. Now, you can open the connection on your host device. On windows, you can use Putty for connect to the virtual machine’s command line.

My Ubuntu’s command line from Windows 8. Localy.

linux-windows8

Happy coddin’!

 

Parallel Matrix Multiplication in ADA95

I want to share my elaboration about Parallel Matrix Multiplication I have writed (as extra task) by the way Parallel Computations which is one of my subject in Silesian University of Technology in the Computer Science course I attend. The elaboration have been written of course in Polish.

I have sloved this problem very simply in ADA95 programming language, which gives an opportunity to write parallel programs very easly in Pascal-like syntax.

My solution of this problem divides an elementary operations between 1 to N provided processors, distributed with shared memory CRCW PRAM model (Parallel Concurrent Read and Concurrent Write). In particular, you can fire up computing in only one processor. Elaborate discuss about problems with value of memory cells working as an accumulator in adding (+) process. It’s overall only.

Finally, I have compiled the code under GNAT 2011 compiler in GPS 2011 IDE (GNAT Developer Studio). For people interested in ADA95 programming and Parallel Computations I recommend some polish books avaiable for example in Silesian Libraries:

  • Porębski, W. (2003). ADA95 Wprowadzenie do Programowania. Michałowice: Komputerowa Oficyna Wydawnicza “HELP”, Piotr Gomoliński.
  • Czech, Z. (2010). Wprowadzenie do obliczeń równoległych. Warszawa: Wydawnictwo Naukowe PWN.
  • Ben-Ari, M. (2009). Podstawy Programowania współbieżnego i rozproszonego (strony 99-133). Warszawa: WNT.

Xin Wang reveals another ways to slove this problem in Scalable Parallel Matrix Multiplication Algorithms with
Application to a Maximum Entropy Problem
publication, but it is only math theory, without implementation.

You can easly write parallel prorgams using MPI library for C++ or Parallel library Java. In general, there are many ways to implement algorythms, but the most important in Parallel Computations is not implementations, but problem decomposition and hardware structure of computing processors which exchanges information with each other.

Have fun!

 

 

How to send template and layout mail with Zend_Mail

Zend_Mail provides a great and simple in use and configuration mechanizm to send emails. The problem begins when you would like to specify fully templated and layouted messages.

In my current project I have several kinds of mails: customer invoices and messages, users notifications, admin notifications, webmaster email about critical errors in scheduled system tasks. In this case the Zend_Layout fits perfectly to redner rich text content by Zend_View, but it is implemented in Zend_Mail, wchih provies simply setBodyText() and setBodyHTML() methods.

This inconvenience is understandable by the way, mainly in context simpe, clear and flexible extendable code of Zend Framework. We will strive to extend the functionality od Zend_Mail following ZF developers concepts.

Overview

Writing class extending Zend_Mail I kept a several concepts:

  • Messages should be both templated and layouted using Zend_View and Zend_Layout.
  • The email view scripts (templates) there are in main view scripts directory nested in subdirectory (as deep as you want).
  • … The same path story with layouts.
  • You can use this object excatly the same way as Zend_Mail. It behaviour the same way as parent until you set special options (like point to view script path or file to render in body).
  • … and object should keep Zend_Mail fluent interface (returning $this in setters) to provide method chaining fluent interface.
  • Pointed view file is rendered as a mail body.
  • You can use this object excatly the same way as Zend_Mail. It behaviour the same way as parent until you set special options (like point to view script path or file to render in body).

Zend_Mail application.ini configuration and extending application

Simply paste several lines to application.ini configuration, theare are self-commented, description is not neccessary at this point. We will use SMTP transport:

resources.mail.transport.type = smtp
resources.mail.transport.host = YOUR_HOSTNAME
resources.mail.transport.auth = login
resources.mail.transport.username = "YOUR_ACCOUNT"
resources.mail.transport.password = "YOUR_PASSWORD"
resources.mail.transport.register = true
 
resources.mail.defaultFrom.email = YOUR_ACCOUNT
resources.mail.defaultFrom.name = "MyService.com"
resources.mail.defaultReplyTo.email = YOUR_ACCOUNT
resources.mail.defaultReplyTo.name = "MyService.com"

In addition we will create tho additional directories and files:

  • /application/views/scripts/email/–  just add a subdirectory /email to existing view scripts directory.
  • /application/layouts/scripts/email/ – the same story as above
TIP: I have moved default configured layouts direcotry to /application/views/layouts/ to unify structure of application. Just change in application.ini this line:
resources.layout.layoutPath = APPLICATION_PATH "/modules/default/views/layouts/scripts/"

To test our class let’s create additional two files:

/application/layouts/scripts/email/html.phtml

< ?php echo $this->layout()->content ?>
<p>--<br />Best Regards,<br />MyService.com</p>

and scond one, the information about successfull account register with your own content:

/application/views/scripts/email/AccountRegister.phtml

<p>Thanks for register.</p>

ZentUtil_Mail class usage

Before we will write a code, let’s think abous its usage, wchih should be the same as in Zend_Mail documentation witch additional methods:

$mail = new ZendUtil_Mail('utf-8');
$mail->addTo('athlanster@gmail.com', 'Piotr Pelczar');
$mail->setSubject('Testowy mail z zenda');
$mail->setBodyView('AccountRegister.phtml');
$mail->send();

Above code should send mail from AccountRegister.phtml view script nested in html.phtml layout.

If you want to change layout simply call setViewLayoutScript($script) method with string or set false to disable layouts. For change paths setViewPathDirectory($path), setViewLayoutPathDirectory($path) are available.

ZendUtil_Mail extends Zend_Mail

ZendUtil_Mail has been extended by Zend_Mail and _prepareBody() method has been added. It is called just before parent::send() method.

NOTE: I have added ZendUtil_ namespace.

I hope it will help.

 

How to get single error message with Zend_Validate_EmailAddress validation

I have just started introducing Zend Framework when I had to face the problem with output multiple error messages in form while email address validation. Checking domain (whith is enabled by default) causes additional error messages indicates anomalies in hostname segment of provided by user email address. In result, we receive several errors assigned to one email field.

The problem is easy to slove by overriding default behaviour of Zend_Validate_EmailAddress clearing all messages generating while validation and setup a new single error message.

Simply add namespace MyOwn_ for own needs and provide class in file /libraries/MyOwn/Validate/EmailAddess.php

class MyOwn_Validate_EmailAddress extends Zend_Validate_EmailAddress
{
  const INVALID = 'emailAddressInvalid';
 
  protected $_messageTemplates = array(
    self::INVALID => "Invalid Email Address."
  );
 
  public function isValid($value)
  {
    parent::setOptions(array(
      'allow' => Zend_Validate_Hostname::ALLOW_DNS,
      'domain' => true,
      'mx' => true,
      'deep' => true)
    );
 
    if(!parent::isValid($value)) {
      $this->_messages = array(); // clear all previous messages
      $this->_error(self::INVALID);
      return false;
    }
 
    return true;
  }
}

And provide above custom validator to form element in /application/forms/AccountRegister.php:

class Form_AccountRegister extends Zend_Form
{
  public function init()
  {
    $this->setMethod('post')
         ->setName('Account_Register');
 
    $email = new Zend_Form_Element_Text('email');
    $email
      ->setLabel('Email address')
      ->addValidator(new ZendUtil_Validate_EmailAddress)
      ->setRequired(true);
 
    $this->addElement($email);
 
  }
}

NOTE:

  • In addition, you can simply translate the emailAddressInvalid message.
  • For sticklers, setting options in isValid method is hardcoded with look like a messy code, but it is quick-fix

Hope it will help.