Install PECL SSH2 Extension on Ubuntu

This took me a short while to work out, so I thought I’d post here how I achieved this to save people some time.

Check if you have the ssh2 extension installed:

php -r "print_r(get_loaded_extensions());"

If so, in the list of extensions, you will see this line:

Array
(
    ...
    [59] => ssh2
    ...
)

If you do not see this line, then you can install the PECL SSH2 extension like this:

sudo apt-get install libssh2-php

Don’t forget to bounce apache:

service apache2 restart

Ubuntu Version?

    Distributor ID:	Ubuntu
    Description:	Ubuntu 11.04
    Release:	11.04
    Codename:	natty

Permalink: http://www.websitefactors.co.uk/other/2012/05/install-pecl-ssh2-extension-on-ubuntu/

Posted in PHP | Leave a comment

data:urls – Reduce HTTP Requests!

So today I was looking at the latest Google Maps API. Whilst browsing I found out that the Google Maps api version 2 had been deprecated.

Anyway, back to the point of this article: This article is all about something called data:urls.

Er What?

So you know that Google now take page speed into account as a search ranking factor right? Well one of the most popular ways speeding up your website is by combining all your images into a css sprites file.

However, data:url is an even better alternative! It works by embedding the images into the website source html and therefore there is no extra http request required.

How does this work?

Say, for example you need an image as your logo. Let’s use this logo from a popular price comparison website:

<img src="http://www.pricespin.co.uk/images/logos/price-spin-uk.gif" />

This would require it to be loaded as an additional HTTP request. Now see this alternative:

<img src="data:image/gif;base64,R0lGODlhXgFYAOYAAH/Mf3" />

Doesn’t this make the page biggger?

Yes and no. If you have gzip caching enabled on your webserver, then this is no slower than loading the image it’s self, except of course, you benefit from the lack of an additional TCP connection and a http request to retrieve the image – I.e. faster!

The snippet below will give you the base64 encoded binary file contents. Use an image from your favorite website.

// Command line code:
php -r "echo base64_encode(file_get_contents('http://www.example.com/your-image.gif'));"

A handy function?

function embedImage($image, $mime = 'image/png')
{
    $raw = base64_encode(file_get_contents($image));
    return 'data:' . $mime . ';base64,' . $raw;
}

Which you can use as follows:

<img src="<?php echo embedImage('http://upload.wikimedia.org/wikipedia/commons/7/7a/Basketball.png', 'image/png'); ?>" />

Permalink: http://www.websitefactors.co.uk/php/2012/01/data-urls-reduce-http-requests/

Posted in PHP | 2 Comments

Installing PHP Codesniffer Properly In Eclipse

PHP Codesniffer Integrated into Eclipse

The Eclipse PHP Codesniffer tool for Eclipse allows you to detect coding standards errors as you are actually typing your code. Unfortunately, not everyone realises this and sets it up simply to output the errors to the console. Here, I will show you how to setup PHP Codesniffer to work natively in Eclipse.

You will need a copy of PHP installed and running on your machine to make this work.

1) Install PHP Codesniffer in Eclipse

Follow these instructions to install PHP Codesniffer in Eclipse.

Zend Studio Users: Please note that if you are using the Zend Studio version of Eclipse, you will need to go to “Help > Software Updates > Search for new feature to install > Find & Install…” then you will need to add a new source by clicking on “Add Remote Site…”.

However, it probably won’t work straight away, because you need to set-up your PHP executables in Eclipse.

2) Setup PHP Executables in Eclipse

Navigate to “Window > Preferences > PHP > PHP Executables” and if there is nothing in the list, then add a new one that points to your PHP executable.

3) PHP Codesniffer Settings

Now all we need to do is setup PHP Codesniffer in the Eclipse preferences settings.

Goto “Window > Preferences > PHP Tools > Codesniffer”.

  • PHP Executable:
    Select the one that you wish to use. You might have created one in the step above?
  • Codesniffer Standards:
    Select the one you prefer, I use Zend.
  • Standard Tab Width:
    Please ensure this is correct to your coding standard, I set it to 4.
  • File Extensions:
    This is a comma separated list of file extensions that PHPCS will try and validate. I only have php in my list. You may have some “.inc” files. Don’t allow it to validate Zend View “.phtml” files. If you allow it to validate .phtml files, it will show that all of your Zend View files are invalid as they contain HTML.

It will ask you if you want to do a “Full Rebuild” – you need to answer yes to this. Depending on the size of your codebase it could take a while to do this, so please be patient.

All done!

Once your rebuild is complete, Eclipse will now show you the files that have coding standards errors with a little red cross next to them. Furthermore, when you open the file, it will show you where the errors are down the left-hand side next to the line number.

Tip: Eclipse Settings

I use Zend Framework coding standards, mainly because I use it every day. I find it eaiser if my development environment is setup correctly. These are my Eclipse settings, feel free to use them:

  1. Click Window > Preferences
  2. General > Editors > Text Editors
    1. Set Displaid tab width to 4
    2. Tick Insert spaces for tabs
    3. Tick Show Print Margin
    4. Set Print Margin Column to 120
  3. General > Perspectives
    1. Select PHP and click Make Default
  4. General > Workspace
    1. Set Text File Encoding to UTF-8
    2. Set New Text File Delimiter to Unix
  5. PHP > Code Style > Formatter
    1. Set Tab Policy to Spaces
    2. Set Indentation size to 4
  6. PHP > Editor > Save Actions
    1. Tick Remove trailing whitespace
    2. Check All Lines

If you have any comments, please feel free to share them below.

Permalink: http://www.websitefactors.co.uk/other/2011/10/installing-php-codesniffer-properly-in-eclipse/

Posted in PHP | 2 Comments

Installing Apache Solr SolrClient PHP Extension in Debian/Ubuntu

Installing Apache Solr SolrClient PHP Extension is relatively simple in Ubuntu (and Debian). However it did take me a little while to work out the dependencies required.

Apache Solr SolrClient PHP Extension required the libcurl and libxml packages to be installed. It also requires the php5-curl extension. So the full set of commands to successfully install Apache Solr SolrClient PHP Extension is as follows:

Note: you will need to be logged in as root user in Debian or prefix these commands with sudo in Ubuntu.

[sudo] apt-get install php5-common
[sudo] apt-get install php5-pear
[sudo] apt-get install php5-curl

Now we have the php dependencies, we can go ahead and install the rest:

[sudo] apt-get install libcurl4-gnutls-dev
[sudo] apt-get install libxml2
[sudo] apt-get install libxml2-dev
[sudo] pecl install -n solr-beta

The next step is to create a file called solr.ini and place it into the extra php.ini configs folder which is located at /etc/php5/conf.d/.

[sudo] echo "extension=solr.so" > /etc/php5/conf.d/solr.ini
[sudo] cat /etc/php5/conf.d/solr.ini
# Should print extension=solr.so top the screen if it was successful

If you cannot do this due to some permission problem in Ubuntu, simply open the file in vim (or whatever text editor) and paste in the extension=solr.so line and close.

Finally, you will need to restart apache to activate the extension for use in PHP web pages:

ubuntu$ [sudo] service apache2 restart
debian$ /etc/init.d/spache2 restart

That’s it. It should now be fully operational.

I found a very useful article when on my hunt around the web today. It explains, not only a similar set of instructions to mine here but also, how to install the extension manually and how to do it in a Windows php environment, see below:

If you have any more information, or you think I may have missed something out, please feel free to comment below.

Permalink: http://www.websitefactors.co.uk/php/2011/10/installing-apache-solr-solrclient-php-extension-in-debian-ubuntu/

Posted in PHP | Leave a comment

Website Offline Holding Pages with PHP – Doing it Right!

When making major changes to your website it’s usually a good idea to put up holding pages. This is for many reasons, but mainly so that whilst your update is taking place, no-one tries to use your website and finds it broken.

This article makes the assumption that you have ssh access to your webserver. Most web hosting companies offer ssh access and it’s absolutely paramount that you have ssh access the purposes of this article. You can test if you have ssh access by typing ssh your-ftp-username@www.yourdomain.com in a linux terminal window or trying to connect to your www.yourdomain.com using a windows client such as PUTTY. If you have root access, switch to your website’s user:

shell [root] ~$ su <inert-user-name-here>

Let’s assume that you use a cPanel server and that your main document root folder (the one that the website browser can access) is public_html. We are going to move your main files from living in the public_html folder to now live in a new folder called public. We will then create a symbolic (soft) link from your public_html folder to your newly created public folder.

Why? Your website’s document root folder is specified in your apache config files as /home/[your-user-id]/public_html. By making this folder a symbolic link to your actual public means that it can be removed and pointed somewhere else if needed. Confused? Read on – all will become clear.

In your shell do this:

shell ~$ mv public_html public
shell ~$ ln -s public public_html

Now create a folder called holding, again using terminal:

shell ~$ mkdir holding

Create a file in the newly created holding folder called index.php:

shell ~$ nano -LwE holding/index.php

Put the following in the file:

<?php
    header('HTTP/1.1 503 Service Temporarily Unavailable');
    header('Status: 503 Service Temporarily Unavailable');
    header('Retry-After: 3600');
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Website Unavailable</title>
    </head>
    <body>
        <h1>Website Unavailable</h1>
        <p>Our website is available due to essential maintenance.</p>
    </body>
</html>

We have added a 503 Service Temporarily Unavailable (apache.org definition) header and we have also added a retry-after response header and 3600 delta-seconds which is 1 hour.

Now you have a default index file in your holding folder that gives the correct 503 Service Temporarily Unavailable response header.

But wait, this will only work if someone visits your home page. We also have to make sure that all other page requests give correct 503 Service Temporarily Unavailable response header. We do this by using a .htaccess file as follows:

shell ~$ nano -LwE holding/.htaccess

Add the following:

RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !index.php
RewriteRule ^(.*)$ http://www.yourdomain.com/index.php [R=302,L]

This will redirect, temporarily, all requested pages to the 503 Service Unavailable page.

Finally, swap your apache document root to point to holding instead of public

shell ~$ cd ~
shell ~$ unlink public_html
shell ~$ ln -s holding public_html

And – to swap this back, simply do this in reverse:

shell ~$ cd ~
shell ~$ unlink public_html
shell ~$ ln -s public public_html

Permalink: http://www.websitefactors.co.uk/php/2011/08/website-offline-holding-pages-with-php-doing-it-right/

Posted in PHP | Leave a comment

MySQL: LIMIT the values in the GROUP_CONCAT Function

One limitation of the GROUP_CONCAT function is that you can’t directly limit it’s output. Say for example you have an order table and a products table and you wanted to list all the orders for a specific product, you could probably do this:

SELECT
    p.product_name,
    GROUP_CONCAT(o.order_id ORDER BY order_id  DESC SEPARATOR ', ') as order_ids
FROM
    product p
INNER JOIN
    orders o ON (o.product_id = p.product_id)
GROUP BY
    p.product_id

This would produce this:

+--------------------------------+------------------------+
| product_name                   | order_ids              |
+--------------------------------+------------------------+
| some laptop                    | 100223, 100266, 100298 |
+--------------------------------+------------------------+

However, say for example you only want to show the last 2 orders for this product, you can do the following:

SELECT
    p.product_name,
    SUBSTRING_INDEX(
        GROUP_CONCAT(
            o.order_id ORDER BY order_id  DESC SEPARATOR ', '
        ),', ',2
    ) as order_ids
FROM
    product p
INNER JOIN
    orders o ON (o.product_id = p.product_id)
GROUP BY
    p.product_id

The select statement does select ALL of the matching rows from the tables, however, the SUBSTRING_INDEX function truncates the amount of values by counting the ‘, ‘ character occurrences. Here’s the result:

+--------------------------------+------------------------+
| product_name                   | order_ids              |
+--------------------------------+------------------------+
| some laptop                    | 100223, 100266         |
+--------------------------------+------------------------+

Permalink: http://www.websitefactors.co.uk/mysql/2011/07/mysql-limit-the-values-in-the-group_concat-function/

Posted in MySQL | 3 Comments

cPanel, PHP set_include_path Function & Apache php_admin_value

I’m exhausted. If you are unlucky enough to have come up against this problem then I sincerely hope that this article can help you. I found this problem by deploying a Zend Framework application to a cPanel server with Apache 2.2 and PHP5.3.

Are you finding that the PHP set_include_path() function is doing nothing? If so, see this article by Carl Evans and run the test he suggests to see if you have the same problem I had. If you do, read-on…

Another article showed me how to add custom apache vhost changes in cPanel. I wasn’t really sure whether it was of any help at first – but after reading Carl Evans’ article – this is exactly what I needed to know.

So what the hell is going on?

The latest version of cPanel includes a “genius” way of putting your ~/php/ folder in your php include path. However, instead of using php_value, which can be over-ridden in PHP code, they decided to use php_admin_value which cannot be overridden in PHP code.

So how can I fix this?

Edit the following files:

/usr/local/apache/conf/userdata/std/2/<username>/<file-name>.conf
/usr/local/apache/conf/userdata/ssl/2/<username>/<file-name>.conf

I have a file called cp_php_magic_include_path.conf. Change all instances of php_admin_value and make it php_value. If you have no interest in your ~/php/ folder being in your include path, you can just delete this file in both locations.

Next time cPanel decide to make some “innovative” change that will severely affect php include paths, maybe they’ll speak to the PHP community first? Probably not – at least this fixes the problem.

If you have a large server with loads of accounts – you will need to run a shell command to remove these files.

Edit: Here is a quick couple of lines of code that you can run from your shell prompt:

Run this at your peril – I’m not responsible for the consequences of this.

cd /usr/local/apache/conf/
find . -name "cp_php_magic_include_path.conf" -type f -exec mv {} {}bak \;
Posted in PHP | Leave a comment

A Simple Zend_Console_GetOpt Example

A colleague told me yesterday that he could not find any boilerplate examples for using the Zend Framework component Zend_Console_Getopt, which has led me to write this short article. He’s right, there seems to be many MVC tuturials and articles, but very few for using Zend Framework on the command line.

I can’t stress enough that you do not need to create a command line MVC to use Zend Framwork in your command line scripts. Simply follow the steps below and you will be up and running in two simple files.

Here is the Directory Structure:

.
|-- common.php
|-- library
|   `-- Zend -> [symbolic link to zend framework folder]
`-- scripts
    `-- getopt.php

Create a Common File:

common.php – Contents:

// Define the library path
define('BASE_PATH', dirname(realpath(__FILE__)));
define('LIBRARY_PATH', BASE_PATH . DIRECTORY_SEPARATOR . 'library');
 
// Add library path to PHP include path
set_include_path(implode(PATH_SEPARATOR, array(get_include_path(), LIBRARY_PATH)));
 
// Load Zend Autoloader
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);

Now, anything that require‘s (includes) this file will be able to load any component of the Zend Framework without a separate include as the autoloader will load it for you – smart ehh?

Create the getopt.php File to play with:

scripts/getopt.php – Contents:

// Load the shared common file...
$base = dirname(dirname(realpath(__FILE__)));
require_once($base . '/common.php');

What we have done so far is instantiate the Zend Autoloader in a common file (so that it can be shared with other files) and included it in our sample getopt.php file.

Simple Zend_Console_GetOpt Example:

scripts/getopt.php

// Load the shared common file...
$base = dirname(dirname(realpath(__FILE__)));
require_once($base . '/common.php');
 
// Here we show a basic example of using simple operators:
try {
    $opts = new Zend_Console_Getopt('b:p:');
    $options = $opts->parse();
} catch (Zend_Console_Getopt_Exception $e) {
    echo $e->getUsageMessage();
    exit;
}
 
print $b = $opts->getOption('b');
print $b = $opts->getOption('p');

Run the File:

Here, we ask the script for usage options. Because we wrapped the Zend_Console_Getopt in a try/catch block above and in the catch block, we are echoing the usage message, we will get this:

debian :~$ php getopt.php --help
 
# Outputs:
Usage: getopt.php [ options ]
-b <string>          
-p <string>

To run it correctly, we must do this:

debian :~$ php getopt.php -bp string1 string2
 
# Outputs:
string1string2

Now you have this working correctly, you should take a look at the Zend Console GetOpt page of the Zend Framework manual. The Zend Console GetOpt is very powerful and does much much more than what is in my simple example above.

Permalink: http://www.websitefactors.co.uk/zend-framework/2011/06/a-simple-zend_console_getopt-example/

Posted in Zend Framework | 1 Comment

Finding Duplicate Rows in MySQL

I sometimes do some work on an e-commerce website and I needed to find a way to find duplicate products in their database. I didn’t want to use PHP as this was just unnecessary as I just wanted a simple report.

This query assumes that you have a MySQL table called product with a column called name and you want to find products that have the same name.

SELECT a.name FROM product a, product b WHERE    (a.name = b.name) GROUP BY a.product_id HAVING COUNT(a.name) > 1;

This will give you a list like this:

+--------------------------------------+
| name                                 |
+--------------------------------------+
| sample product 1                     |
| sample product 3                     |
| sample product 4                     |
| sample product 5                     |
| sample product 6                     |
+--------------------------------------+

Permalink: http://www.websitefactors.co.uk/mysql/2011/06/finding-duplicate-rows-in-mysql/

Posted in MySQL | 1 Comment

Error Class On Form Field Errors Using Zend Form

One of the most powerful components of Zend Framework is Zend Form. In this article, I will show you how to put an error class on your form field when using Zend Form. This enables you to create a css class to style the form field in the instance of an error.

Extend Zend Form class:

Here we create a form class that extends Zend_Form. We override the isValid() method. We loop through the form->elements and add a class of “error” if the hasErrors() method returns true. We also do a check to see if a class attribute already exists using the getAttrib() method and if so we append the “error” class using a space to separate.

class MyForm extends Zend_Form
{
    public function isValid($data)
    {
        $valid = parent::isValid($data);
 
        foreach ($this->getElements() as $element) {
            if ($element->hasErrors()) {
                $oldClass = $element->getAttrib('class');
                if (!empty($oldClass)) {
                    $element->setAttrib('class', $oldClass . ' error');
                } else {
                    $element->setAttrib('class', 'error');
                }
            }
        }
 
        return $valid;
    }
}

Now, when you call the isValid method, it will automatically add a class of error to any fields that do not pass validation.

Here’s an example of a form field with the error class after a validation attempt:

Error Form Field Example

Error Form Field Example

Permalink: http://www.websitefactors.co.uk/zend-framework/2011/06/error-class-on-form-field-errors-using-zend-form/

Posted in Zend Framework | Leave a comment