Code

Coding, Programming & Algorithms, Tips, Tweaks & Hacks
Search

Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

PHP 7's Null Coalescing Operator

PHP 7's Null coalescing operator is more useful than I thought.

PHP
public static function read($id)
{
    $Row = MySQL::query("SELECT `Data` FROM `cb_sessions` WHERE `SessionID` = '$id'", TRUE);    
    
    # http://php.net/manual/en/function.session-start.php#120589
    //check to see if $session_data is null before returning (CRITICAL)                        
    
    if($Row['Data'] == false || is_null($Row['Data']))
    {
        $session_data = '';
    }
    else
    {
        $session_data = $Row['Data'];
    }
    
    return $session_data;    
}
PHP 7.4
can be replaced with :
PHP
public static function read($id)
{
    $Row = MySQL::query("SELECT `Data` FROM `cb_sessions` WHERE `SessionID` = '$id'", TRUE);    

    # Introduced in PHP 7 : https://stackoverflow.com/a/59687793/126833
    return $Row['Data'] ?? '';    
}
PHP 7.4
Vanakkam !

Encrypt and Decrypt strings in URL in PHP 7 using openssl

Here's a dead simple solution to pass through encrypted data as a value in your URL. Say you wanted to load something like https://my-product.com/loadProduct.php?id=1234 but don't want to show the real id as it may be the primary value in your database's table.

Instead, you can load it like this : https://my-product.com/loadProduct.php?id=33797030395539366e55673d and decrypt the value in your script.
PHP

<?php
define("ENCRYPTION_KEY", "123456*");
function encrypt($string) { return bin2hex(openssl_encrypt($string, 'BF-ECB', ENCRYPTION_KEY)); }
function decrypt($string) { return openssl_decrypt(hex2bin($string),'BF-ECB',ENCRYPTION_KEY); }
?>
PHP 7.2
More details on security : https://stackoverflow.com/a/50373095/126833
Vanakkam !

Always check for existence of a file in spl_autoload_register's function call

PHP
<?php
function my_autoloader_1($className)
{    
    $filename = 'test1/'.$className.'.php';
    if (file_exists($filename))
    {
        require_once $filename;
    }
    else
    {
        return false;
    }
}

# foo.php is in test2
function my_autoloader_2($className)
{    
    $filename = 'test2/'.$className.'.php';
    if (file_exists($filename))
    {
        require_once $filename;
    }
    else
    {
        return false;
    }    
}

spl_autoload_register('my_autoloader_1');
spl_autoload_register('my_autoloader_2');
 
$a = new foo();
?>
PHP 7
Vanakkam !

Availability of a file / link publically on Google Cloud Storage

If you want to check if a file exists publically on Google Cloud Storage,

PHP
<?php
$flyer = "http://commondatastorage.googleapis.com/bucket/path/to/directory/image.jpg";
$headers = @get_headers($flyer);
if ($headers[0] != "HTTP/1.1 200 OK" && $headers[0] != "HTTP/1.0 200 OK")
{
    # Load file locally / from elsewhere
    $flyer = IMG."/image.jpg";
}?>
PHP 5
Vanakkam !

Compressing HTML

Compress might not be the right word, as it doesn't really compress / zip the output HTML code, but combines all the HTML lines to a single line and removes trailing / leading whitespaces.

This has to be your index.php and am assuming you are routing all incoming page requests to index.php which will be handled by either rewrites in htaccess or direct query strings. For example, I would have either

RewriteRule ^about\/vision$ index.html?page=about-vision [QSA,L]
or
RewriteRule ^register$ index.php?module=Register

PHP
<?php
ob_start();
require_once "index.phtml";
$html = ob_get_clean();
$htmls = explode("\n", $html);
for ($i = 0; $i < count($htmls); $i++)
{
    $htmls[$i] = trim($htmls[$i]);
}
$html = implode("", $htmls);
echo $html;
?>
PHP 5

There is one gotcha in this. You can't use single line comments start with // in inline Javascript code in the HTML. Either place the JavaScript code outside of the HTML page, in separate .js page or use multi-line comments /* */

Vanakkam !

Using WebP image format for browsers that support it

The WebP image format for the web is starting to get a lot of hype for its massive file compression. Chrome supports it since ver 9 and Opera since ver 11.10.
Image file sizes are reduced by more than 50% in WebPs when compared to JPGs.
Looking at Google Analytics on various sites, Chrome 9+ users constitute 20% - 25%. So providing one-fifth or one-fourth of the users with a much reduced page load is worth the extra effort.

1. Convert JPGs / PNGs to WebPs :

for i in *.jpg; do j=`echo "$i" | cut -d . -f 1`; convert -colorspace RGB "$i" "$i"; ~/libwebp/cwebp -q 75 "$i" -o "${j}.webp"; done

convert is used to convert the colourspace from RGB to CMYK since as of now, webp encoder doesn't support CMYK colourspace.

2. Use 2 different CSS files for background images - one for standard jpg/png and another for webp. Chrome 9+ and Opera 11.10+ would be served webp.css while all others img.css.

get_browser is pretty useful for browser detection, but requires to set browscap in php.ini which is a PHP_INI_SYSTEM directive and can't be set in using ini_set(), .htaccess or user php.ini which rules out almost all shared hosting enviroments.
But interestingly, this is possible in WebFaction where I could set browscap in a user php.ini file which was parsed.

PHP
<?php
$imgCSS = "img";
$browser = get_browser(null, true);
if (($browser['browser'] = "Chrome" && $browser['version'] >= 9) || ($browser['browser'] = "Opera" && $browser['version'] >= 11.10))
$imgCSS = "webp";
?>
.
.
.
<link rel="stylesheet" type="text/css" media="all" href="<?php echo $imgCSS ?>.css" />
PHP 5.2

If you are getting something like ...

<b>Warning</b>:  get_browser() [<a href='function.get-browser'>function.get-browser</a>]: browscap ini directive not set in <b>/path/script.php</b> on line <b>7</b>

and if there is no way to set browscap, then you need to find an alternative browser detection like phpbrowscap.

I benchmarked this on a graphically heavy wordpress site, having 11 photographs in a slider on the homepage which takes a megabyte alone.

BrowserRequestsSizeTime
FireFox 3.6311.9 MB21.48s (onload: 20.62s)
Chrome 1132577.90KB6.51s (onload: 6.51s, DOMContentLoaded: 2.88s)

(I could not find the option to view total bytes downloaded in Opera dragonfly's network tab)

Side Note : When uploading webp images to google storage, S3 or any other cloud service, specify the content-type / mime-type.

gsutil -h "Cache-Control:public,max-age=31536000" -h "Content-Type: image/webp" cp -a public-read kitten.webp gs://[bucket]/images/kitten.webp
s3cmd put kitten.webp s3://[bucket]/images/ --acl-public --mime-type "image/webp" --add-header="Cache-Control:max-age=315360000"
Vanakkam !

One-liner check for the existence of all required fields from a POSTed form

If you have a simple contact / registration form for a non-CMS / non-framework website with many input fields, it becomes cumbersome to do a server check if all fields passed through doing isset for every field. Many people just check for the existance of a single POST field, but for security reasons, it is better to check for the existence of all required fields.

PHP
if (isset($_POST['name']) && isset($_POST['email']) && isset($_POST['phone']) && isset($_POST['message']))
{
    # POSTed
    # Process form
}
PHP

What if there were 20 fields ? That'll be one long line of issets.
array_diff is a built-in array function in PHP that computes the difference between arrays - it returns an array containing all the entries from the first array that are not present in any of the other arrays.
All we need to check is if the list of required fields are all present as keys in $_POST - this is easily achievable by checking against array_keys of $_POST.
And finally for the count - if all required fields are present in the $_POST's keys, it'll return 0 which is what we want and how we can confirm that all POST field values got sent through.

PHP
$requiredFields = array('name','email','phone','message');
if (count(array_diff($requiredFields, array_keys($_POST))) == 0)
{
    # POSTed
    # Process form
}
PHP
Vanakkam !

Property getters & setters

In traditional OOP, if we wanted to get or set an object's private member, we would need to write a public method to do the job.
The reason behind making a member data private and then accessing it through a public method is to avoid the implementing-user to access it directly.
There can be many reasons for prohibiting direct access to member data to the implementing-code.
For example, you may want a radius of a Circle to be within the range of 10 - 500.

C++: Traditional OOP
class Circle
 {
        private:
          int radius;

        public:
          Circle(int radius = 15)
           {
                  setRadius(radius);
           }

          void setRadius(int radius)
           {
                  if (radius < 10 || radius > 500)
                   {
                          this->radius = -1;
                          cout << "Radius must be within the range of 10 - 500" << endl;
                   }
                  else
                   this->radius = radius;
           }

          int getRadius()
           {
                  return this->radius;
           }
 }

void main()
 {
        Circle c = Circle();
        c.setRadius(25);
        cout << c.getRadius();
 }
C++

In languages like PHP & Python & PERL which have a weak type system, a further check of the data type may be necessary.
But for Python unfortunately even traditional getter & setter methods cannot be implemted because Python doesn't have a public or private. Everything is public by default - though a member can be made private by prefixing two underscores to it. But this is only for convention, it doesn't really serve its true purpose.

PHP 5 and C# .NET have a getter and setter method feature, making it look like we're accessing the data member directly.

PHP
<?php
class Circle
 {
        private $radius; # integer

        # Constructor
        public function __construct($radius = 15)
         {
                self::__set('radius', $radius);
         }

        # Setter
        public function __set($name, $value)
         {
                switch ($name)
                 {
                        case 'radius':

                          if (!is_numeric($value)) # is_int() for strong type checking
                           throw new Exception('Radius must be of a numeric type');

                          if ($value < 10 || $value > 500)
                           throw new Exception('Radius must be within the range of 10 - 500');

                          $this->radius = $value;

                        break;

                        default:
                          throw new Exception("Attempt to set a non-existing property: $name");
                        break;
                 }
         }

        # Getter
        public function __get($name)
         {
                if (in_array($name, array('radius')))
                 return $this->$name;

                switch ($name)
                 {
                        default:
                          throw new Exception("Attempt to get a non-existing property: $name");
                        break;
                 }
         }

 }

$c = new Circle();
$c->radius = 25;
echo $c->radius;
>
PHP 5.x
C#
using System;

public class Circle
 {
        private int __radius = 5;

        public Circle()
         {
         }

        public Circle(int radius)
         {
                this.radius = radius; // This will call the property defined below
         }

        public int radius // Property getter/setter name cannot be the same as the member variable name
         {
                get
                 {
                        return __radius;
                 }

                set
                 {
                        if (value < 10 || value > 500)
                         throw new Exception("Radius must be within the range of 10 - 500");

                        __radius = value;
                 }
         }
 }

public class main
 {
        public static void Main(string[] args)
         {
                Circle c = new Circle(); // Circle c = new Circle(5); will throw an Exception
                c.radius = 25;
                Console.WriteLine(c.radius);
         }
 }
.NET 2.0

C# .NET 3.0 has introduced Automatic Properties where you don't need to specify code for the getter & setter - the compiler takes generates the method body.

JavaScript does seem to have a getter and setter method which I came across just now when searching for the official source to Java 7's new features' documentation, but :

  • only within an object initializer - not inside a function so it doesn't seem to be of much use as we can't create instances
  • doesn't hide the member from being accessed directly
  • doesn't work in IE.

JavaScript
var someObj =
 {
        a : 7,
        get b()
         {
                return this.a * 3;
         },
        set c(x)
         {
                this.a = x / 2;
         }
 }

someObj.foo1 = function()
 {
        //
 }

alert(someObj.a); // 7
alert(someObj.b); // 21
someObj.c = 5; alert(someObj.a); // 2.5
someObj.foo1();
JavaScript 1.5

The Getter & Setter feature does not seem to be a much "wanted" feature in the Java community.
Still, this has been proposed by Rémi Forax for JDK 7.

Java: Proposal
public class Circle
 {
        private int __radius = 5;

        public Circle()
         {
         }

        public Circle(int radius)
         {
                this.radius = radius; // This will call the property defined below
         }

        public property int radius // Property getter/setter name cannot be the same as the member variable name
         {
                get
                 {
                        return __radius;
                 }

                set (int radius)
                 {
                        if (radius < 10 || radius > 500)
                         throw new Exception("Radius must be within the range of 10 - 500");

                        __radius = radius;
                        // firePropertyChange(radius);
                 }
         }

        public static void main(String[] args)
         {
                Circle c = new Circle(2); // Circle c = new Circle(5); will throw an Exception
                c.radius = 25;
                System.out.println(c.radius);
         }
 }
JDK 7
Vanakkam !

Generating a Random String

PHP
<?php
class RandomText
 {
        const RAND_NUMBERS       = 1;
        const RAND_SMALL_LETTERS = 2;
        const RAND_CAP_LETTERS   = 4;
        const RAND_ALL           = 7;

        /**
         * @access public
         * @param Type (INT) One of the random constants RAND_*
         * @NoOfChars [INT] Optional - No of characters to generate
         * @return (string) random string
         * @example echo RandomText::Random_String(RandomText::RAND_NUMBERS + RandomText::RAND_CAP_LETTERS, 25);
         */
 	public static function Random_String($Type = self::RAND_NUMBERS, $NoOfChars = 6)
 	 {
 	 	$strList = array();

 	 	// Convert to binary format and find out what combination of random characters are required
 	 	$binType = base_convert($Type, 10, 2);

 	 	// Loop through the bits from Right To Left
 	 	for ($i = strlen($binType) - 1; $i >= 0; $i--)
 	 	 {
 	 	 	if ($binType[$i])
 	 	 	 {
 	 	 	 	switch (pow(2, strlen($binType) - $i - 1))
 	 	 	 	 {
 	 	 	 	 	default:

 	 	 	 	 	case self::RAND_NUMBERS:
 	 	 	 	 	 $Ascii_Range = array(48, 57);  // Numbers - Characters 0 to 9
 	 	 	 	 	break;

 	 	 	 	 	case self::RAND_SMALL_LETTERS:
   	 	 	 	 	 $Ascii_Range = array(97, 122); // Small Letters - Characters a to z
 	 	 	 	 	break;

 	 	 	 	 	case self::RAND_CAP_LETTERS:
 	 	 	 	 	 $Ascii_Range = array(65, 90);  // Capital Letters - Characters A to Z
 	 	 	 	 	break;
 	 	 	 	 }

 	 	 	 	for ($j = $Ascii_Range[0]; $j <= $Ascii_Range[1]; $j++)
 	 	 	 	 $strList[] = chr($j);
 	 	 	 }
 	 	 }

 	 	$RndString = "";
 	 	for ($i = 0; $i < $NoOfChars; $i++)
 	 	 $RndString .= $strList[rand(0, count($strList) - 1)];

 	 	return $RndString;
 	 }
 }

echo RandomText::Random_String(RandomText::RAND_NUMBERS + RandomText::RAND_CAP_LETTERS, 25);
?>
PHP 5.2.3
C#
using System;
using System.Text;

public class RandomText
 {
        public const int RAND_NUMBERS       = 1;
        public const int RAND_SMALL_LETTERS = 2;
        public const int RAND_CAP_LETTERS   = 4;
        public const int RAND_ALL           = 7;

        public static string Random_String()
         {
                return Random_String(RAND_NUMBERS, 6);
         }

        public static string Random_String(int Type)
         {
                return Random_String(Type, 6);
         }

        public static string Random_String(int Type, int NoOfChars)
         {
                StringBuilder strList = new StringBuilder();
                int[] Ascii_Range;
                int i;

                // Convert to binary format and find out what combination of random characters are required
                string binType = Convert.ToString(Type, 2);

                // Loop through the bits from Right To Left
                for (i = binType.Length - 1; i >= 0; i--)
                 {
                        if (binType[i] == '1')
                         {
                                switch ((int)Math.Pow(2, binType.Length - i - 1))
                                 {
                                        default:

                                        case RAND_NUMBERS:
                                         Ascii_Range = new int[] {48, 57};  // Numbers - Characters 0 to 9
                                        break;

                                        case RAND_SMALL_LETTERS:
                                         Ascii_Range = new int[] {97, 122};  // Small Letters - Characters a to z
                                        break;

                                        case RAND_CAP_LETTERS:
                                         Ascii_Range = new int[] {65, 90};  // Capital Letters - Characters A to Z
                                        break;
                                 }

                                for (int j = Ascii_Range[0]; j <= Ascii_Range[1]; j++)
                                 strList.Append((char)j);
                         }
                 }

 	 	StringBuilder RndString = new StringBuilder();
 	 	Random rnd = new Random();
 	 	
 	 	for (i = 0; i < NoOfChars; i++)
 	 	 RndString.Append(strList[rnd.Next(strList.Length - 1)]);

 	 	return RndString;
         }

        public static void Main(string[] args)
         {
                Console.WriteLine(RandomText.Random_String(RandomText.RAND_NUMBERS + RandomText.RAND_CAP_LETTERS, 25));
         }
 }
.NET 2.0
Java
import java.io.*;
import java.util.Random;

public class RandomText
 {
        public static final int RAND_NUMBERS       = 1;
        public static final int RAND_SMALL_LETTERS = 2;
        public static final int RAND_CAP_LETTERS   = 4;
        public static final int RAND_ALL           = 7;

        public static String Random_String()
         {
                return Random_String(RAND_NUMBERS, 6);
         }

        public static String Random_String(int Type)
         {
                return Random_String(Type, 6);
         }

        public static String Random_String(int Type, int NoOfChars)
         {
                StringBuilder strList = new StringBuilder();
                int[] Ascii_Range;
                int i;

                // Convert to binary format and find out what combination of random characters are required
                String binType = Integer.toString(Type, 2); // Type.toString(2);

                // Loop through the bits from Right To Left
                for (i = binType.length() - 1; i >= 0; i--)
                 {
                        if (binType.charAt(i) == '1')
                         {
                                switch ((int)Math.pow(2, binType.length() - i - 1))
                                 {
                                        default:

                                        case RAND_NUMBERS:
                                         Ascii_Range = new int[] {48, 57};  // Numbers - Characters 0 to 9
                                        break;

                                        case RAND_SMALL_LETTERS:
                                         Ascii_Range = new int[] {97, 122};  // Small Letters - Characters a to z
                                        break;

                                        case RAND_CAP_LETTERS:
                                         Ascii_Range = new int[] {65, 90};  // Capital Letters - Characters A to Z
                                        break;
                                 }

                                for (int j = Ascii_Range[0]; j <= Ascii_Range[1]; j++)
                                 strList.append((char)j);
                         }
                 }

                StringBuilder RndString = new StringBuilder();
                Random rnd = new Random();

                for (i = 0; i < NoOfChars; i++)
                 RndString.append(strList.charAt(rnd.nextInt(strList.length() - 1)));

                return RndString.toString();
         }

        public static void main(String[] args) throws Exception
         {
                System.out.println(RandomText.Random_String(RandomText.RAND_NUMBERS + RandomText.RAND_CAP_LETTERS, 25));
         }
 }
JDK 6.0
JavaScript
function RandomText()
 {
        this.RAND_NUMBERS       = 1;
        this.RAND_SMALL_LETTERS = 2;
        this.RAND_CAP_LETTERS   = 4;
        this.RAND_ALL           = 7;

        this.Random_String = function(Type, NoOfChars)
         {
                var strList = "";
                var Ascii_Range;
                var i;

                // Convert to binary format and find out what combination of random characters are required
                binType = Type.toString(2);

                // Loop through the bits from Right To Left
                for (i = binType.length - 1; i >= 0; i--)
                 {
                        if (binType[i] == '1')
                         {
                                switch (Math.pow(2, binType.length - i - 1))
                                 {
                                        default:

                                        case this.RAND_NUMBERS:
                                         Ascii_Range = new Array(48, 57);  // Numbers - Characters 0 to 9
                                        break;

                                        case this.RAND_SMALL_LETTERS:
                                         Ascii_Range = new Array(97, 122); // Small Letters - Characters a to z
                                        break;

                                        case this.RAND_CAP_LETTERS:
                                         Ascii_Range = new Array(65, 90);  // Capital Letters - Characters A to Z
                                        break;
                                 }

                                for (var j = Ascii_Range[0]; j <= Ascii_Range[1]; j++)
                                 strList += String.fromCharCode(j);
                         }
                 }

                var RndString = "";
                for (i = 0; i < NoOfChars; i++)
                 RndString += strList[Math.floor(Math.random() * strList.length)];

                return RndString;
         }
 }

var oRandomText = new RandomText();
alert(oRandomText.Random_String(oRandomText.RAND_NUMBERS + oRandomText.RAND_CAP_LETTERS, 25));
JavaScript 1.5
Python
import array
import random

def int2bin(n):
    "Convert an integer to binary - no built-in function"
    bStr = ''
    while n > 0:
          bStr = str(n % 2) + bStr
          n = n >> 1
    return bStr

class RandomText:

      RAND_NUMBERS       = 1;
      RAND_SMALL_LETTERS = 2;
      RAND_CAP_LETTERS   = 4;
      RAND_ALL           = 7;

      def Random_String(Type = RAND_NUMBERS, NoOfChars = 6):
          strList = array.array('c', '')

          # Convert to binary format and find out what combination of random characters are required
          binType = int2bin(Type)

          # Loop through the bits from Right To Left
          for i in range(len(binType) - 1, -1, -1):

              if binType[i] == '1':

                 x = 2 ** (len(binType) - i - 1)

                 if x == RandomText.RAND_NUMBERS:
                    Ascii_Range = [48, 57]   # Numbers - Characters 0 to 9
                 elif x == RandomText.RAND_SMALL_LETTERS:
                    Ascii_Range = [97, 122]  # Small Letters - Characters a to z
                 elif x == RandomText.RAND_CAP_LETTERS:
                    Ascii_Range = [65, 90]   # Capital Letters - Characters A to Z
                 else:
                    Ascii_Range = [48, 57]   # Numbers - Characters 0 to 9

                 for j in range(Ascii_Range[0], Ascii_Range[1] + 1):
                    strList.append(chr(j))

              RndString = array.array('c', '')

              for i in range(0, NoOfChars):
                  RndString.append(strList[random.randint(0, len(strList) - 1)])

          return RndString.tostring()

      Random_String = staticmethod(Random_String)


print RandomText.Random_String(RandomText.RAND_NUMBERS + RandomText.RAND_CAP_LETTERS, 25)
Python 2.5
Vanakkam !

Detecting the Absolute URI

In PHP there's a function called parse_url which splits a given absolute url into various parts as an array.

PHP
<?php
function AbsURI()
 {
        $ThisLink = 'http'.(isset($_SERVER["HTTPS"]) ? $_SERVER["HTTPS"] == 'off' ? '' : 's' : '').
                    '://'.
                    $_SERVER['HTTP_HOST'].
                    $_SERVER['REQUEST_URI'];

        $UrlParts = parse_url($ThisLink);

        $Path = $UrlParts['path'];

        // Get rid of filename.html in /folder1/folder2/filename.html
        $Path = preg_replace('#(/)([^/]*?\..*?$)#i', '$1', $Path);

        // Make it standard to have trailing / at the end of a foldername
        if (substr($Path, -1) != '/')
         $Path .= '/';
        
        $absURI = $UrlParts['scheme'].'://'.$UrlParts['host'].$Path;

        return $absURI;
 }
?>
You can probably get the absolute URI with something as simple as :
PHP
<?php
$s = substr($_SERVER["SCRIPT_FILENAME"], strlen($_SERVER["DOCUMENT_ROOT"]));
// Not very sure if the above always evaluates to $_SERVER["SCRIPT_NAME"]

$ThisPath = 'http'.
            (isset($_SERVER["HTTPS"]) ? $_SERVER["HTTPS"] == 'off' ? '' : 's' : '').
            '://'.$_SERVER['HTTP_HOST'].
            substr($s, 0, strrpos($s, '/') + 1);
?>
but unfortunately, how filename & directory name values are stored in $_SERVER varies in server setup and relying on it may not be 100% accurate, though in 99% of the cases, it should do just fine.

There's another reason to use the 2nd snippet instead of the 1st - that's if a RewriteRule is used for the given current url ($ThisLink).
Lets say I had the 1st code snippet in absURI.php in test folder in my document root. So http://localhost/test/absURI.php would be the link. And something like this in my .htaccess file :
Apache
RewriteEngine On
RewriteRule ^fakefolder/test\.html$ absURI.php
and I access the url using http://localhost/test/fakefolder/test.html?a=2&b=c
AbsURI() will end up returning http://localhost/test/fakefolder/ which would be incorrect.

Tested on different hosts having Apache 2.0.x.
Vanakkam !

fputcsv for PHP4

I found it strange why fgetcsv() was included since version 3.0.8 and fputcsv() only since 5.1.0RC1 when both are so closely interrelated. Heres fputcsv for ones not running on a minimum of PHP 5.1.0RC1.
PHP
if (!function_exists('fputcsv'))
 include_once("php4.inc.php");
Assuming php4.inc.php includes functions that natively exist in PHP 5 and not in version 4.
PHP
function fputcsv($fh, $arr)
 {
        $csv = "";
        while (list($key, $val) = each($arr))
         {
                $val = str_replace('"', '""', $val);
                $csv .= '"'.$val.'",';
         }
        $csv = substr($csv, 0, -1);
        $csv .= "\n";
        if (!@fwrite($fh, $csv))
         return FALSE;
 }
The str_replace('"', '""', $val); is because Excel doesn't seem to understand \".
Vanakkam !

Absolute path of current php file in execution

Sometimes it is necessary to know the absolute path of the current php-file in execution. A common example is when you have loaded a 3rd-party module and all its related files (like php, css, js, images etc) are in a folder of its own and moving these related files to your own specific-folders for the sake of organization can be disadvantageous instead of structuring them to match your own. If moving the files to different locations, editing the module code could end up being cumbersome. Hence, modules are like Java packages where all the files are kept in a separate folder and better left untouched. In php, if we can extract a lot of file and folder information from these global variables $_SERVER['DOCUMENT_ROOT'], $_SERVER['SCRIPT_FILENAME'], $_SERVER['SCRIPT_NAME'], $_SERVER['PHP_SELF'] But none of these would give the current php-file name in consideration if mod_rewrite, include() etc were used to retrieve a php file. PHP's __FILE__ magic constant is the only way to retrieve the absolute path. Given this path you can create a OO module within which you can access the related-files within the folder and thus be independent of any CMS. This is one very simple function you'll come across but I still felt the need to emphasize on this function.
PHP
<?php
echo __FILE__AbsolutePath(__FILE__)."\n";

function __FILE__AbsolutePath($Filename)
 {
        switch (PHP_OS)
         {
                case "WINNT": $needle = "\\"; break;
                case "Linux": $needle = "/";  break;
                default:      $needle = "/";  break; // TODO : Mac check
         }
        $AbsPath = substr($Filename, 0, strrpos($Filename, $needle));
        return $AbsPath;
 }
?>
I haven't done a MAC and other OS checks. If you have tried this on an OS that shows a different value for PHP_OS, please do share it with others.

Update: Getting the current file equivalent to __FILE__ can be retrieved using the debug_backtrace() function.
PHP
<?php
function __FILE__AbsolutePath()
 {
        $d = debug_backtrace();
        $Filename = $d[0]['file'];

        switch (PHP_OS)
         {
                case "WINNT": $needle = "\\"; break;
                case "Linux": $needle = "/";  break;
                default:      $needle = "/";  break; // TODO : Mac check
         }
        $AbsPath = substr($Filename, 0, strrpos($Filename, $needle));
        return $AbsPath;
 }
?>
Vanakkam !

get_file_contents

Sometimes we need to retrieve a remote file/url's content which is easily done using PHP's file_get_contents(). This returns FALSE on failure but on many occasions file_get_contents() returns FALSE due to a network error or server overload and could've worked the next second. Here is a function get_file_contents(), that tries to retrieve the url's contents over and over again until its TRUE (it has successfully fetched the contents) or until it has exhausted the number of tries. Because threading is not yet available in PHP, it is not recommended to set the $totalTries to a higher value.
PHP
function get_file_contents($url, $totalTries = 5)
 {
        $Tries = 0;
        do
         {
                if ($Tries > 0) sleep(1); # Wait for a sec before retrieving again
                $contents = @file_get_contents($url);
                $Tries++;
         } while ($Tries <= $totalTries && $contents === FALSE);
         if ($contents == "") $contents = FALSE;
         return $contents;
 }
This ends the beginning of my first post here !
Vanakkam !