PHP Certification.
Oct 28th
Have you ever wondering whether your PHP skill is up for the test, is it good enough for the world to look at and make use of? and How to make the world acknowledge you as a PHP developer? To be a certified PHP developer. You have to take tests, obviously, but where and why? There are various places you could take tests online to save your time and money and of course, being a certified PHP developer doesn’t make you a better ones, it just improves your chances to get a professional job in PHP.
You will need to have knowledge of PHP (obviously), MySQL, HTML (basic) and Web Administration skill alongside with some smaller skill set such as XML, CSS…. to actually be confidence in the test. And when I mean THE test, there are not just one test. Each tests are different and are offered by different organization
Zend
The industry standard, awarded from the guys who is behind PHP and alike, is always THE best award in all. Zend has been running the PHP certification for more than 4 years and have been awarding certificates for thousands of PHP developer and alike. If you are totally serious in your PHP development, Zend is the way to go.
You can look at the price tag for each of the examination bundles that Zend offers, alongside with all the exam preparation guides.
W3C
One of the most understandable sites. And one of the guys that have been running free programs and having a wide web resources for new web developers around the world. If you don’t know W3C, you are not a real developer. W3C also give out certificate and roll out free practice test for people to try. This really worth a try to know your level.
However, the real test is nothing like the practice test, it consists of in depth material with around 70 multiple choice questions that would really rule out the weak and the strong… Also, 70 questions in 70 minutes, yes, there is a time limit. And you have to nominate someone creditable to be your supervisor. The price for the exam is $75 USD.
OST
O’Reilly School of Technology also offers PHP certification through 4 courses. On completion of all 4 courses offered by OST (with a price tag of $398 each course) you will be awarded a PHP certification. All 4 courses work in conjuction to give you a thorough understanding of PHP, ranging from beginner to advanced PHP, logical design, database management to Web2.0 integration. It surely worths the price tag.
That’s all?
Yea, for now. There are others, offering similar certification, but I’ve ruled out the 3 most popular ones. The others including Expert Rating (really a job seeking site, offering PHP certification for 10 bux, 45 multiple choice questions in 45 minutes) and Brainbench which is, in my opinion, not as creditable as the others (please don’t flame me, that’s my personal preference)
OpenID for CodeIgniter made easy – All about it
Oct 21st
A few months back, I have been struggling to have openID authentication loaded to my application. It’s a hazard… the simple idea of having it integrated to my application and have users logged in using their existing facebook, google account is pretty fancy, but the code behind it is a mess, a complete tragedy. Luckily RPXNow stepped in and provided me a hand in authenticate people and handling the magic works. No one likes to reinvent the wheel after all, and this is a PRETTY HARD wheel to deal with…

Also, I’ve been exposed to the wonderful world of Codeigniter, and have found a wonderful library handling all the dirty works for me, (75% of those have been dealt with by RPXNow). All I have to do is have a small iframe in my view, and then deal with what I have to offer when I have successfully authenticated the users.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | function login() { $this->load->library('openidrpx'); // In the view, display an iframe pointing to the "embedurl" $this->load->view('loginview', array('embedurl', $this->openidrpx->EmbedUrl('start/openidverify')); } function openidverify() { $this->load->library('openidrpx'); if($token = $this->input->post('token')) { $data = $this->openidrpx->AuthInfo($token); if($id = OpenIDRpx::Identifier($data)) { // Authorize user! } } } |
However…
The idea is great, having some other web service do the dirty authentication work, and have a web framework ready library to do the integration dirty work… Having not to dirty your hands, but get things done. This is too easy to be true. But… I think using RPXNow is a bad idea, at least for me.
By using RPXNow, I am entrusting a third party site to deal with my users. There’s an extra hop in the process and thus, I am really relying on their service for my login process… What if they gone out of business for a while…?
Also, when the users login, the OpenID provider will direct them to yoursitename.RPXNow.com instead of your root website. Although RPXNOw offers ability to customize this hopping point, or with an extra cost ($20/month) to have it named as your root website (www.yoursitename.com). This serves to confuse your naive user even more.
By having a monthly fee, you can whitelist/blocklist certain provider, but this feature is not available in the free ones.
So!
It’s up to you, if you are really confident that you can deal with OpenID on your own, I suggest you do. But if you have absolutely no idea of how to even start looking at the problem, RPXNow is a definitive choice, it saves you “10 years of pain of extensive coding” and have your application up and running in under 2 hours (or less!!!). And if you like RPXNow and pay to be a loyal customer, you’ll gain a lot of extra functionality.
Have FPDF integrate with CodeIgniter
Oct 16th
This is a simple, plug it in, it runs, guide. It is still highly recommended that you try and run FPDF successfully without Codeigniter first. So that you know how to actively runs it or your web server supports it.
Step 1: Download the Classes from the FPDF pages.
The fpdf.php in the Codeigniter directory.
The font directory in the fonts directory
Step 2: Config File
1 | $config['fonts_path']= "path-to-your-fontsdir/fonts/"; |
Step 3: Create the init_fpdf.php
1 2 3 4 5 6 7 8 9 | <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); if ( ! class_exists('fpdf')){ require_once(BASEPATH.'libraries/fpdf'.EXT); } $obj =& get_instance(); $obj->fpdf = new fpdf(); $obj->ci_is_loaded[] = 'fpdf'; ?> |
Step 4: Call it, use a controller to test
1 2 3 4 5 6 7 8 | $this->load->library('fpdf'); define('FPDF_FONTPATH',$this->config->item('fonts_path')); $this->fpdf->Open(); $this->fpdf->AddPage(); $this->fpdf->SetFont('Arial','B',14); $this->fpdf->SetY(30); $this->fpdf->Cell(40,10,'Hello World!'); $this->fpdf->Output('output.pdf','D'); |
Handpicked Handy PHP Libraries
Oct 15th
Do you ever wondering how to do certain things in PHP like generating graphs, generating pdf or parse RSS efficiently and easily. I found myself rewriting these codes every once in a while and was lucky enough to find these wonderful libraries/framework that are completely free and easy to use.
There are more, but I will only listed my handpicked best one out of these categories
RSS Parser
Normally I would use Jquery to do this stuff, but meh. When it comes to PHP, it’s all the way PHP
SimplePie: Very fast, easy to use, PHP driven RSS Parser
Demo | Documentation | Screencast (Yay!!)
I once used MagpieRSS for performance, but SimplePie offers a greater deal of functionality and when web servers are getting stronger days by days, the performance difference is not that big. One thing I love about this SimplePie is that it is actively being developed and actively updated.
Also, SimplePie got an integration with Codeigniter, my favourite PHP framework
Graph Generator
pChart: an Object Oriented framework that is capable of generating charts, graphs and best of all, it’s free. Data is grabbed from SQL Queries or CSV Files or just manually put them in.
Screenshots | Demo | Documentation (Very detailed!)
However, this library requires GD Library to be installed onto your web server and have PHP compiled with it. If you don’t have GD installed, better check for my second alternative: Libchart, a little bit old but suffice.
PDF Generator
FPDF: This little baby works splendid. It can stand alone or with zlib for compression and GD for GIF support.
It can be easily integrated with Codeigniter
Excel Generator
php-excel: very easy and fast way to generate excel spreadsheet using PHP on the fly
The approach is to convert a 2 dimensional array in PHP to a spreadsheet in Excel. However, because of it’s easy to use and fast performance, it does not have quite a few of features like cell styling, functions creating, sort…. If you need those (I don’t!), your choice is PHPExcel
Payment System
PHP-OpenID: for paypal, authorize.net and 2checkout (2CO). Yeah, the 3 most popular ones, who needs the lesser unpopular ones?
Checkout the links, it’s very detailed with code examples and all other stuff that you need to know. Scrap those you don’t need to know
This guy, Emran, is my hero by delivering this wonderful library to us
Handy PHP Code Snippets
Oct 14th
Send Simple Mail
1 2 3 4 5 6 7 8 9 10 | function send_simple_mail($from,$to,$subject,$body) { $headers = "From: $from\r\n"; $headers .= "Reply-To: $from\r\n"; $headers .= "Return-Path: $from\r\n"; $headers .= "X-Mailer: PHP5\n"; $headers .= 'MIME-Version: 1.0' . "\n"; $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n"; @mail($to,$subject,$body,$headers); } |
List a Directory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Destroy a Directory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /***** *@dir - Directory to destroy *@virtual[optional]- whether a virtual directory */ function destroyDir($dir, $virtual = false) { $ds = DIRECTORY_SEPARATOR; $dir = $virtual ? realpath($dir) : $dir; $dir = substr($dir, -1) == $ds ? substr($dir, 0, -1) : $dir; if (is_dir($dir) && $handle = opendir($dir)) { while ($file = readdir($handle)) { if ($file == '.' || $file == '..') { continue; } elseif (is_dir($dir.$ds.$file)) { destroyDir($dir.$ds.$file); } else { unlink($dir.$ds.$file); } } closedir($handle); rmdir($dir); return true; } else { return false; } } |
Send File via FTP
1 2 3 4 5 6 | $connection = ftp_connect($server); $login = ftp_login($connection, $ftp_user_name, $ftp_user_pass); if (!$connection || !$login) { die('Connection attempt failed!'); } $upload = ftp_put($connection, $dest, $source, $mode); if (!$upload) { echo 'FTP upload failed!'; } ftp_close($connection); |
Zip File
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* creates a compressed zip file */ function create_zip($files = array(),$destination = '',$overwrite = false) { //if the zip file already exists and overwrite is false, return false if(file_exists($destination) && !$overwrite) { return false; } //vars $valid_files = array(); //if files were passed in... if(is_array($files)) { //cycle through each file foreach($files as $file) { //make sure the file exists if(file_exists($file)) { $valid_files[] = $file; } } } //if we have good files... if(count($valid_files)) { //create the archive $zip = new ZipArchive(); if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) { return false; } //add the files foreach($valid_files as $file) { $zip->addFile($file,$file); } //debug //echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status; //close the zip -- done! $zip->close(); //check to make sure the file exists return file_exists($destination); } else { return false; } } /***** Example Usage ***/ $files=array('file1.jpg', 'file2.jpg', 'file3.gif'); create_zip($files, 'myzipfile.zip', true); |
UnZip File
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /********************** *@file - path to zip file *@destination - destination directory for unzipped files */ function unzip_file($file, $destination){ // create object $zip = new ZipArchive() ; // open archive if ($zip->open($file) !== TRUE) { die (’Could not open archive’); } // extract contents to destination directory $zip->extractTo($destination); // close archive $zip->close(); echo 'Archive extracted to directory'; } |
Parse JSON
1 2 3 4 | $json_string='{"id":1,"name":"foo","email":"foo@foobar.com","interest":["wordpress","php"]} '; $obj=json_decode($json_string); echo $obj->name; //prints foo echo $obj->interest[1]; //prints php |
Parse XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | //xml string $xml_string="<?xml version='1.0'?> <users> <user id='398'> <name>Foo</name> <email>foo@bar.com</name> </user> <user id='867'> <name>Foobar</name> <email>foobar@foo.com</name> </user> </users>"; //load the xml string using simplexml $xml = simplexml_load_string($xml_string); //loop through the each node of user foreach ($xml->user as $user) { //access attribute echo $user['id'], ' '; //subnodes are accessed by -> operator echo $user->name, ' '; echo $user->email, '<br />'; } |
Get Client’s real IP address
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Force File Download
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /******************** *@file - path to file */ function force_download($file) { if ((isset($file))&&(file_exists($file))) { header("Content-length: ".filesize($file)); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $file . '"'); readfile("$file"); } else { echo "No file selected"; } } |
Tag Cloud Generation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | function getCloud( $data = array(), $minFontSize = 12, $maxFontSize = 30 ) { $minimumCount = min($data); $maximumCount = max($data); $spread = $maximumCount - $minimumCount; $cloudHTML = ''; $cloudTags = array(); $spread == 0 && $spread = 1; foreach( $data as $tag => $count ) { $size = $minFontSize + ( $count - $minimumCount ) * ( $maxFontSize - $minFontSize ) / $spread; $cloudTags[] = '<a style="font-size: ' . floor( $size ) . 'px' . '" class="tag_cloud" href="#" title="\'' . $tag . '\' returned a count of ' . $count . '">' . htmlspecialchars( stripslashes( $tag ) ) . '</a>'; } return join( "\n", $cloudTags ) . "\n"; } /************************** **** Sample usage ***/ $arr = Array('Actionscript' => 35, 'Adobe' => 22, 'Array' => 44, 'Background' => 43, 'Blur' => 18, 'Canvas' => 33, 'Class' => 15, 'Color Palette' => 11, 'Crop' => 42, 'Delimiter' => 13, 'Depth' => 34, 'Design' => 8, 'Encode' => 12, 'Encryption' => 30, 'Extract' => 28, 'Filters' => 42); echo getCloud($arr, 12, 36); |
use Gravatars
1 2 3 4 5 6 7 8 9 10 11 12 | /****************** *@email - Email address to show gravatar for *@size - size of gravatar *@default - URL of default gravatar to use *@rating - rating of Gravatar(G, PG, R, X) */ function show_gravatar($email, $size, $default, $rating) { echo '<img src="http://www.gravatar.com/avatar.php?gravatar_id='.md5($email). '&default='.$default.'&size='.$size.'&rating='.$rating.'" width="'.$size.'px" height="'.$size.'px" />'; } |
Resize Image
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /********************** *@filename - path to the image *@tmpname - temporary path to thumbnail *@xmax - max width *@ymax - max height */ function resize_image($filename, $tmpname, $xmax, $ymax) { $ext = explode(".", $filename); $ext = $ext[count($ext)-1]; if($ext == "jpg" || $ext == "jpeg") $im = imagecreatefromjpeg($tmpname); elseif($ext == "png") $im = imagecreatefrompng($tmpname); elseif($ext == "gif") $im = imagecreatefromgif($tmpname); $x = imagesx($im); $y = imagesy($im); if($x <= $xmax && $y <= $ymax) return $im; if($x >= $y) { $newx = $xmax; $newy = $newx * $y / $x; } else { $newy = $ymax; $newx = $x / $y * $newy; } $im2 = imagecreatetruecolor($newx, $newy); imagecopyresized($im2, $im, 0, 0, 0, 0, floor($newx), floor($newy), $x, $y); return $im2; } |
Validate Email Address
1 2 3 4 5 6 7 | function is_valid_email($email) { if(eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$",$email)) return true; else return false; } |
Thanks to jakyra points out that the eregi() function has been deprecated as of php 5.3.0 and completely removed in php 6.0. An alternative would be preg_match_all()
Validate Domain Name
1 2 3 4 5 6 7 | function is_valid_url($url) { if (preg_match('/^(http|https|ftp)://([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+):?(d+)?/?/i', $url)) { echo "Your url is ok."; else echo "Wrong url."; } |
SQL Injection Prevention
Oct 12th
What is SQL Injection?
SQL Injection is evil. Period. SQL Injection is where people gain access to your system using method unknown to you. Injection usually occur when you require the user to fill in a form, often in a form of a username or a password => They put something evil in the box and crashes your system. That evil something is of a form of a SQL statement and actively running their code onto your database.
Types of SQL Injection
There are 2 types: ones that gains access to your system (as an admin) and ones that corrupt your database.
First type:
1 2 3 4 5 | // user input that uses SQL Injection $injection_string = "' OR 1'"; // our MySQL query builder, however, NOT a very safe one $query_bad = "SELECT * FROM users WHERE username = '$injection_string'"; |
This will grant them unlimited power, since the OR 1 part always return true… evil….
Second Type:
1 2 3 4 | // user input that uses SQL Injection $injection_string = "'; DELETE FROM user WHERE 1 or username = '"; // our MySQL query builder, however, NOT a very safe one $query_bad = "SELECT * FROM users WHERE username = '$injection_string'"; |
This will destroy your database…
SQL Injection Prevention
SQL Injection is a common thing. Easy to try, easy to implement. out of a thousand people going to your website, would only 1 of them try if your application is secure or not? That’s why, it’s a common thing to prevent such an obvious security hole. All you need to do is apply the mysql_real_escape_string function to the thing.
1 2 3 | $injection_string = "'; DELETE FROM user WHERE 1 or username = '"; $query_ok = "SELECT * FROM users WHERE username = 'mysql_real_escape_string($injection_string)'"; |
and it will be ok, basically, they will replace all single quote and double quote character with the escaped string \’ and covered this security hole.
And due to the problem of PHP versions support, this function is not available in older versions of php… So this will do for all version
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function prep($value){ $magic_quotes_active = get_magic_quotes_gpc(); $new_enough_php = function_exists( "mysql_real_escape_string" ); // i.e. PHP >= v4.3.0 if( $new_enough_php ) { // PHP v4.3.0 or higher // undo any magic quote effects so mysql_real_escape_string can do the work if( $magic_quotes_active ) { $value = stripslashes( $value ); } $value = mysql_real_escape_string( $value ); } else { // before PHP v4.3.0 // if magic quotes aren't already on then add slashes manually if( !$magic_quotes_active ) { $value = addslashes( $value ); } // if magic quotes are active, then the slashes already exist } return $value; } |
Introducing Codeigniter
Oct 10th
This is my first post about Codeigniter, a free MVC PHP framework that is very easy to understand and implement. I have been using Codeigniter for quite a while now and is very please with what I’ve achieved.
Hold on, what is MVC?
MVC is short for Model View Controller and is an abstract way of separating the logic, display and controlling decision. I wouldn’t go through defining them but for the sake of simplicity, I’ll throw in a simple example. And also, I’ll go through this example in Codeigniter’s way of talking, so that we won’t go to outer space without knowing it
Model is where the information is. View is how the information will be presented. Controller is which information to choose.
For example we want to view a page with the id of 3. we will have the controller called “view_page” and pass it an argument id = 3. The controller will then grab the information (page detail) by calling the “page” model and ask for page detail with the id of 3. After retrieving the page detail from the model, the controller would then call the “display_page” view and give it what to display.
In detail:
The Controller’s code will be:
1 2 3 4 5 | $id=$_GET['id']; $data=$this->page_model->loadpage($id); $this->load->view('page-display', $data); |
The Model’s code will be:
1 2 3 4 5 6 7 8 9 | function loadpage($id) { $data = db->query('SELECT * FROM page WHERE id=$id'); return $data; } |
The View’s code will be:
1 | echo $data['content']; |
If that’s not understandable, please, dig in to the framework and see what’s in there. Also, Codeigniter offered a 20 minutes video tutorial (oh, I love theses!) to quickly setup codeigniter and have a blog running in less than half an hour. Pretty impressive to me.
If you’d ever run into a wall, the user guide is always there to help you.
Have fun igniting codes