Wednesday, November 11, 2015

Failed to load Zend/Loader.php - Easy permanent solution

I encountered this error message today:

"Failed to load Zend/Loader.php"

-or some people also experienced -

"Failed to load Zend/AutoLoader.php"

What caused the issues above?  Basically a script somewhere in your PHP app is requiring Zend Framework Library, and it can not find it.

This is how I solved this issue:

1. Install Zend framework library (if it does not already exists).
   
    for Ubuntu > 9.04 use:   apt-get install zend-framework

    The above command will install Zend Framework in /usr/share/php

2.  Then you should create .ini file for PHP to include your newly install Zend extension

     nano /etc/php5/conf.d/zend-framework.ini

with the following content:

[Zend]
include_path=${include_path} ":/usr/share/php/libzend-framework-php"

3.  Restart your webserver.
   
     service apache2 restart

Your error message should now disappear.

I hope this helps someone.

Thursday, October 29, 2015

Assign values to dynamic variable in PHP without using eval()

In PHP eval() function is evil.  I try my best not to use it. The eval() function has been misused by hackers so much... that I usually scan through my (or somebody else's)  PHP scripts when I suspect some malware has been installed (infected PHP files).

Here is a quick grep command to find all files with keyword 'eval(':

grep -rn "eval(" /data_local/app 


One situation when I have the need to use eval, is when I am assigning a dynamic variable.  Okay first I should probably explain what I mean by dynamic variable.  Dynamic variable is a technique to define a variable programmatically, meaning your scripts are defining the PHP variables automatically.

Look at this code as an example:

<?php
$variable_name = 'my_variable';

$variable_value = 123;

$$variable_name = $variable_value;

echo $my_variable;
?>

The output of the above PHP codes will be:

123

 Lets examine what the code did... on line 3 ( $$variable_name = $variable_value; )

We are actually defining $my_variable with the value 123.

PHP makes this very simple with using $$ operator, which kind of makes sense.


Saturday, July 25, 2015

Remove accented character from string accents accent char characters in PHP

Here is an array of accented characters and a function to replace them to normal un-accented version


$unwanted_array = array( 'Š'=>'S', 'š'=>'s', 'Ž'=>'Z', 'ž'=>'z', 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U',
'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss', 'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c',
'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o',
'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y' );

$str = strtr( $str, $unwanted_array );

Sunday, February 1, 2015

GEOIP pear pecl PHP extension for location IP based conversion to city country, longitude, latitude

  1. Download .dat.gz databases from maxmind: http://geolite.maxmind.com/download/geoip/database/
  2. Install geoip via yum.
    yum install GeoIP GeoIP-devel
  3. You also might want to download database with ip addresses from Maxmind website and place it in /usr/share/GeoIP (which is a default location of geoip upon installation).
  4. Install PECL extension
    pecl install geoip
  5. Add extension=geoip.so to your /etc/php.ini
  6. Restart apache /etc/init.d/httpd restart

For Ubuntu:

apt-get install libgeoip-dev libgeoip1
apt-get install php5-geoip

then you need to copy GeoLiteCity.dat.gz to /usr/share/GeoIP/ and extract it and rename it to GeoIPCity.dat
then restart your web server:

service apache2 restart

Check if PHP session already started? session_start check

Simplest way to check if PHP session has already started or not


<?php
  if (!isset ($_COOKIE[ini_get('session.name')])) {
    session_start();
  }
?>

Check if PHP script was executed from command line CLI or not

Simple and fool proof PHP code snippet to detect if the current running script was executed from command line (CLI) or not (most likely browser).



if(is_null($argc)) {
    //NOT CLI
} else {
    //FROM CLI
}

Check if another instance / process (by PID) of PHP script running / executed already exists via temporary file lock

If you are trying to make sure your back-end running script will only have a single instance running, you may want to use a script like this.


// ---- SOMEWHERE AT THE TOP OF YOUR SCRIPT -----------
// TRY TO GET EXCLUSIVE LOCK

$fp_pid_pathfilename = "/tmp/your_script_name.php.lock";

$fp_pid_lock = fopen($fp_pid_pathfilename, "w");

// try to get exclusive lock, non-blocking
if (!flock($fp_pid_lock, LOCK_EX|LOCK_NB)) {
	// failed to get lock
	die("Another instance is already running.\n");
} else {
	// got lock, write PID
	fwrite($fp_pid_lock, getmypid());
}

.
.
.


// ---- THEN AT THE END OF THE SCRIPT ------------
// CLOSE OR RELEASE PROCESS PID LOCK

fclose($fp_pid_lock);
unlink($fp_pid_pathfilename);


TIP: Please make sure you store your lock file in /tmp, the reason is simple, most linux server will remove all files/directory for /tmp directory, therefore if you have a sudden power failure, your lock file will not be stuck.

My personal list of HTTP codes along with usage for PHP

Here are my personal list of HTTP codes I frequently used with PHP:



header('HTTP/1.1 200 OK');
 
// Page was not found:
header('HTTP/1.1 404 Not Found');
 
// Access forbidden:
header('HTTP/1.1 403 Forbidden');
 
// The page moved permanently should be used for
// all redrictions, because search engines know
// what's going on and can easily update their urls.
header('HTTP/1.1 301 Moved Permanently');
 
// Server error
header('HTTP/1.1 500 Internal Server Error');
 
// Redirect to a new location:
header('Location: http://www.example.org/');
 
// Redriect with a delay:
header('Refresh: 10; url=http://www.example.org/');
print 'You will be redirected in 10 seconds';
 
// override X-Powered-By value
header('X-Powered-By: PHP/4.4.0');
header('X-Powered-By: Brain/0.6b');
 
// content language (en = English)
header('Content-language: en');
 
// last modified (good for caching)
$time = time() - 60; // or filemtime($fn), etc
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT');
 
// header for telling the browser that the content
// did not get changed
header('HTTP/1.1 304 Not Modified');
 
// set content length (good for caching):
header('Content-Length: 1234');
 
// Headers for an download:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="example.zip"'); 
header('Content-Transfer-Encoding: binary');
// load the file to send:
readfile('example.zip');
 
// Disable caching of the current document
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Pragma: no-cache');
 
// set content type
header('Content-Type: text/html; charset=iso-8859-1');
header('Content-Type: text/html; charset=utf-8');
header('Content-Type: text/plain'); // plain text file
header('Content-Type: image/jpeg'); // JPG picture
header('Content-Type: application/zip'); // ZIP file
header('Content-Type: application/pdf'); // PDF file
header('Content-Type: audio/mpeg'); // Audio MPEG (MP3,...) file
header('Content-Type: application/x-shockwave-flash'); // Flash animation
 
// force basic HTTP authentication
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Top Secret"');
print 'Text that will be displayed if the user hits cancel or ';
print 'enters wrong login data';

PHP array sort ascending using closure function usort sorting

Any PHP developer who has used usort() or uasort() function before PHP support closure know it is a pain in the rear.  Having to declare a callback function just liters your code.  I have been doing this code which I found to be the simplest and most elegant:

<?php
usort($input_array, function(){
	if($a['something'] == $b['something']) return 0;
	return ($b < $a ? -1 : 1);
});
?>

Converting SimpleXMLElement returned object to associative PHP array

This trick is pretty cool, putting SimpleXMLElement output through json encode and decode actually yield a perfect PHP associative array. Nice!


<?php
$xml = '<blah>123</blah>';

$simpleXML_obj = new SimpleXMLElement($xml);
// echo __LINE__.':simpleXML_obj: '.print_r($simpleXML_obj, true)."\n";

if(!empty($simpleXML_obj)){
	$json = json_encode($simpleXML_obj);
	if(!empty($json)){
		$arr = json_decode($json, true);
		if(!empty($arr)){
			// Got nice associative array!
			echo __LINE__.':arr: '.print_r($arr, true)."\n";
		}
	}
}
?>

Output image file content using PHP with correct header for cache control (using etag and last-modified)

Creating code to read and output image content using PHP is easy. However it takes a little bit more PHP-fu to make your code to communicate with browser so cache can be used effectively.

What do I mean by that?  we will generate additional headers like:

Cache-control: public
Last-Modified:  ....
Etag:  ....


and we will check if browser provide us with HTTP_IF_MODIFIED_SINCE and HTTP_IF_NONE_MATCH to be compared against current file content to check if file_content have changed.

If the current file content is the same we will delivery

HTTP/1.1 304 Not Modified

if content is NOT the same, we will deliver the actual content of the file.

Here is the my code snippet to accomplish this:



Enjoy!

Saturday, January 24, 2015

How to convert PHP associative multi-dimensional array to XML using DomConstructor

There are many solutions to accomplish PHP array to XML conversion, however many are complicated. I found this technique is the simplest. The function fromMixed below was written by Van de Voorde Toni. I hope this help someone.

This solution works for multi-dimensional array also.


$xmlDomConstructor_obj = new XmlDomConstructor('1.0', 'UTF-8');

$xmlRoot = $xmlDomConstructor_obj->createElement("WhatEverYourRootElement");
$xmlRoot = $xmlDomConstructor_obj->appendChild($xmlRoot);
$xmlDomConstructor_obj->fromMixed($your_associative_array, $xmlRoot);

$xml_output = $xmlDomConstructor_obj->saveXML();

To use the code above you need to include the class below (from Van de Voorde Toni):

<?
/**
 * Extends the DOMDocument to implement personal (utility) methods.
 * - From: http://www.devexp.eu/2009/04/11/php-domdocument-convert-array-to-xml/
 * - `parent::` See http://www.php.net/manual/en/class.domdocument.php
 *
 * @throws   DOMException   http://www.php.net/manual/en/class.domexception.php
 *
 * @author Toni Van de Voorde
 */
class XmlDomConstructor extends DOMDocument {

    /**
     * Constructs elements and texts from an array or string.
     * The array can contain an element's name in the index part
     * and an element's text in the value part.
     *
     * It can also creates an xml with the same element tagName on the same
     * level.
     *
     * ex:
        \verbatim
             <nodes>
                <node>text</node>
                <node>
                    <field>hello</field>
                    <field>world</field>
                </node>
             </nodes>
        \verbatim
     *
     *
     * Array should then look like:
        \verbatim
             array(
                "nodes" => array(
                    "node" => array(
                        0 => "text",
                        1 => array(
                            "field" => array (
                                0 => "hello",
                                1 => "world",
                            ),
                        ),
                    ),
                ),
             );
        \endverbatim
     *
     * @param mixed $mixed An array or string.
     *
     * @param DOMElement[optional] $domElement Then element
     * from where the array will be construct to.
     *
     */
    public function fromMixed($mixed, DOMElement $domElement = null) {

        $domElement = is_null($domElement) ? $this : $domElement;

        if (is_array($mixed)) {
            foreach( $mixed as $index => $mixedElement ) {

                if ( is_int($index) ) {
                    if ( $index == 0 ) {
                        $node = $domElement;
                    } 
                    else {
                        $node = $this->createElement($domElement->tagName);
                        $domElement->parentNode->appendChild($node);
                    }
                }
                else {
                    $node = $this->createElement($index);
                    $domElement->appendChild($node);
                }

                $this->fromMixed($mixedElement, $node);
            }
        } 
        else {
            $domElement->appendChild($this->createTextNode($mixed));
        }
    }
}