About Me


Hi! I’m Wern Ancheta. I’m a Web Developer from San Fernando City, La Union, Philippines. I love building things for the web and sharing the things that I’ve learned through writing. When I’m not coding or learning something new, I enjoy watching anime and playing video games.

Services Offered

Here are some of the services that I normally offer:

  • Web Development – mainly PHP and its Frameworks (CodeIgniter, Laravel, Flight).
  • System Analysis and Design – from requirements analysis, database design, to system architecture design.
    Note that this is what I do most of the time. But I also work with JavaScript (NodeJS), Ruby, and WordPress projects from time to time.

If you have an interesting project or an idea that you want to implement please contact me:

  • Email
  • skype name: wernancheta



If you like this blog and you want to say thanks please consider making a donation. I’d really appreciate it.

How to install and configure apache, php and mysql

In this post I’m going to show you how to install apache, php, and mysql manually.

If you are doing this for the second time (you have already installed it before and you want to reinstall it because of some problems) you have to do the following before you continue:

  • Delete the MySQL folder located in the Program Files folder or where you installed it before. The uninstaller doesn’t automatically delete this folder (I don’t really know, maybe it does when you restart your computer).
  • Delete the MySQL folder located in the following address when you’re on Windows XP:
C:\Documents and Settings\All Users\Application Data

          And if you’re on Windows Vista or Windows 7 where user_name is the username of the current user.



Here’s the order of installation:

  1. Apache
  2. PHP
  3. MySQL



First we install Apache. Just follow the following screenshots.




Enter the network domain, server name and the administrator’s email address. If the website that you are hosting in the Apache server is just accessible in a local area network then you can use localhost. If not then enter what’s applicable to your configuration, you can use the example given in the installer as a reference.


Select Typical.


By default apache will be stored on the following location:

 c:\program files\apache software foundation

It’s fine if you just use the default but if you want to make it more memorable the use the example below:


Click Install.




Next is PHP.


If you’re bored you can read the EULA. If not then immediately accept it. And yes, you’re free to read the EULA even if you’re not bored.


To make it more memorable change the installation path to the following:


Select Apache 2.2


Now you need to browse the location where the http.conf file is located.


Select the extensions and extras that you wish to install.


Click Install


Click Finish




Lastly we install MySQL.


This EULA is way too long, you might as well skip it and just check on the agreement


Select Typical


Click Install.


Click Next twice. Then click Finish.



MySQL Configuration

At this point in time MySQL has already been installed but not yet configured. Click Next to continue with the configuration.


Select Detailed Configuration then click Next.


You can either choose Server Machine or Dedicated Server Machine. But for the purpose of hosting a site I think it’s better to use Server Machine Configuration. Click Next.


Again this requires you to decide. Just read the description for each type to determine the suitable configuration. You can just use Multifunctional Database if you’re not sure what to choose. If the system that you’re trying to host is a transactional type of system (Point of Sale, Billing System, Tax Collection System etc.) then select transactional database. If it’s just a system for a school project then you can choose non-transactional database.


This is where you choose the location of the mysql data (Data stored in your mysql databases)


This configuration depends on the number of concurrent users of the system. It’s up for you to decide what to choose.


The default port used by MySQL is 3306. You’re free to change it if you think another application is already using it. Check enable strict mode and click Next.


Again this depends upon you. If you think you’re going to store Chinese or Japanese or ASCII characters in your database today or in the near future then just select Best Support For Multilingualism. Click Next.


Just use the defaults. If you don’t want to use the MySQL console in running MySQL commands you might want to check the include bin directory in windows path option. This allows you to run MySQL commands from the Windows Command Line.


Enter your desired password:


Click Execute. This won’t take a minute, if it takes more than a minute maybe you haven’t deleted the folders I was talking about a while ago.



Configuring Apache

To configure Apache you need to open up the httpd.conf file and change the following line.

PHPIniDir ""
LoadModule php5_module "php5apache2_2.dll"

To something like the one below. Just change the location to where you installed php.

PHPIniDir "C:\php"
LoadModule php5_module "C:\php\php5apache2_2.dll"

Next you need to tell Apache to make use of the index files as default files on your server. Because by default index files are being treated like ordinary files. Here’s the default.

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all

You need to change it to this so that index.php and index.php will be treated as the default files. 

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    DirectoryIndex index.php index.html

We’ve done this so that you can avoid the problem wherein all the files in a specific directory are being listed in a nice way (not really nice).


Configuring PHP

To configure PHP open up the php.ini file. In this example the php.ini file is located in the following location:


First you need to change the error_reporting.

error_reporting = E_ALL & ~E_DEPRECATED  //default

error_reporting = E_ALL //change to this

Display errors, html errors and display startup errors is disabled by default.

display_errors = Off //default
display_errors = On //change to this
html_errors = Off //default
html_errors = On //change to this
display_startup_errors = Off //default
display_startup_errors = On //change to this

Only do this if you’re still on the testing phase. You don’t want your users to see any errors.

Next set the defaults for MySQL connection.

mysql.default_port = 3306
mysql.default_socket =
mysql.default_host = localhost
mysql.default_user = root
mysql.default_password = secret

Another one that you might want to look at is the time zone. If you’re setting the time zone in a configuration file you might also get warnings to avoid that all you need to do is to set the timezone in the php.ini file.

date.timezone = UTC //change this to your timezone

If you are a Wampserver user, you might have also noticed that your redirects aren’t working anymore. If you’re getting this kind of error then follow the answers of the people at Stackoverflow. That is if your code is not made up of 99.9% of bad code, modifying it might actually lead to even more bugs. Just do the following and try not to use Wampserver the next time you develop your php application. I’ve also learned my lesson here, Wampserver is actually hiding a lot of errors and warnings because its php.ini file is configured to do so. Just enable output buffering:

output_buffering = On

What this does is to allow you to send headers, cookies, sessions after you have already outputted something on the page. You might have noticed that php doesn’t actually allow you to redirect the page if you’ve already outputted something that is if you’re not using Wampserver. Yes, Wampserver encourages bad coding practice and I’ll admit that I’m also a victim. If you’re reading this as a beginner in the world of web development then I encourage you not to use Wampserver and XAMPP. As you might already know XAMPP also encourages bad coding practice because it’s short open tag directive is enabled by default:

short_open_tag = On //this is in XAMPP, don't do this

And what this means is that it allows you the developer to use shorthand php tags:

//code here

O yeah, you just saved 3 characters there but it’s not actually a good coding practice. Try to avoid this at all cost.


Configuring MySQL

Finally, if you’re like me and you’ve mindlessly checked the Enable Strict Mode a while ago just change the following line in the my.ini file.



Into this line:


Sorry about that, I’ve actually told you to enable strict mode a while ago. So if you didn’t do it. There’s no need for you to do this step.

So why exactly did we disable strict mode? Because it’s to strict. One example of it being strict is that if you don’t pass a value to a field while performing an insert query, the query won’t execute and you’ll get a warning which tells that one of the fields didn’t get any value. If you didn’t quite get the picture here’s an example.

We have a table named TABLE (yeah, very creative way of naming huh):


We performed an insert query:

INSERT INTO TABLE SET name = 'luffy'

As you can see we didn’t set a value for the address since we didn’t even call it in our query we can just go away with it if it’s not strict mode. But if it’s strict mode we have to set up a value for every field in the table. Pretty nasty isn’t it?



That’s it! I’ve written this tutorial while actually figuring out what’s wrong with the configuration. I hope I’ve help someone save some hours by writing this tutorial. The result is actually pretty nasty if you’ve developed your application using WAMP or XAMPP then you suddenly install each of the software manually. So I guess the lesson here is that don’t try to develop in WAMP or in XAMPP if you think you’re gonna be using the manual installation on system deployment.

Things to remember when saving files into the database

In this quick post I’m going to tell you about some of the things that you need to remember when saving files into a database to make it work flawlessly.

Saving files into the database is actually a bad idea, have a quick look at the answers to this question in Stackoverflow:

Storing images in DB – Yea or Nay?

If you’re still on it then continue reading.



There are things that you need to configure in order to make uploading files to database flawless. First is the my.ini file or the mysql configuration. Yes, this post is actually mysql-centric so if you’re using another database then I suggest that you Google some more you’ll eventually find what you’re looking for.
If you’re on XAMPP my.ini is located at:


And if you’re on WAMP:


All you have to do is to look for this line:

max_allowed_packet = 15M

Yeah, I don’t know if it’s 15M by default but what it means is 15Mb. Be sure to change that  to whatever max file size you wish to upload on your database.

Next open up the php.ini file, if you’re on XAMPP its in:


And if you’re on WAMP:


And there’s actually a second php.ini file which is located under:


It’s only in WAMP, the one that is in the Apache folder is the one used for the php that is being run on the browser. And the php.ini in the php folder is for the php that runs on the command-line. Just edit both of them so that you won’t need to worry about anything.

Okay so here’s the line that you need to edit. It’s not actually 50M by default. Just modify it to whatever value you like. Just be sure not to forget the big M after the numeric value.

post_max_size = 50M

Next you also have to change the maximum execution time. It’s 30 seconds in my file but I don’t know if it’s the default, be sure to change it if you think the file that your users are going to upload will take more than 30 seconds to complete.

max_execution_time = 30 

You might also want to consider changing the value for the upload_max_filesize if you’re also planning to upload the files on the filesystem as a form of backup. This is 2Mb by default.

upload_max_filesize = 2M



For the database you might know it already that’s why I decided to place it on the latter part of this post. If you’re storing files into the database you should use the BLOB data type. If you will allow your users to upload videos and other media files use LONGBLOB it’s the safest possible bet.



I guess that’s it for this quick post. Remember that storing files into the database is not actually a good practice, awesome people at Stackoverflow are discouraging it since you’ll lose a lot of performance just by saving and accessing those files from the database.  The file system is actually the best place to be storing files. Another bad thing about saving files into the database is that your database will rapidly grow in size which means that it will consume much more space on your hard drive and it will also take some time just to backup. Lastly, you will have to set the header types on every page where you plan to output your files. The only advantage of storing files into the database is that it’s more secure and it’s really portable. Portability is really useful in cases wherein you need to migrate your system from one operating system to another since you don’t need to take care of the file paths when migrating.  In the end it’s still up to you to decide which path you want to go, is it the file system path or the database path.

Zenoir Online Classroom

Zenoir Online Classroom is a personal project by yours truly. It’s actually just a modern version of the Manhattan Virtual Classroom with some additional features. Some of the useful features like the visual indication that a post is still not opened by the current user is still present. Unread post are indicated by a red star at the end of the title of a message and once its opened the star goes off.




Users can edit information such as the photo that they will use for their account and password.




Groups can also be created by any user. Groups can be used for grouping people in a specific class. Groups can be created by the teacher or the student and only the creator of the group can add or remove members from the group. This is similar to the groupings created by the teacher in a real-world classroom.





The dashboard is the landing page of the students and the teachers whenever they log in with their accounts. Classes in which the student or teacher belongs are all listed in this page. Unread post from every class, notifications, people, and the previous classes attended to are also listed. Previous classes can be accessed as long as it wasn’t explicitly locked by the teacher.




The messages module is where the users can send private messages to one or more users who also belong to the classroom where the user is currently logged in. image

Users can also reply to a specific message where they have the option to attach files.


There is also a conversation history feature. This allows for viewing the past messages that has been sent as a reply to an original message. Entries that are listed here are ordered by the date and time it was sent, the recent messages are on the top portion. If the original message is a group message all the replies of the people who received the message can also be seen by other people in the conversation history.


Original messages are created using the create new message link. The main difference between an original message and a reply message is that the original message can be sent to many people while reply messages can only be sent to a single person.




There is also a quizzes module that allows the teacher to create quizzes such as the one below. The scores of the students in a particular quiz is stored in the database so that the teacher can view it at a later time to monitor the performance of students.




Handouts can also be created by the teacher to give the students reading materials in e-format such as pdf files and word files. The attached files can be downloaded by the students. It can also be viewed as long as the browser that is used by the student supports viewing of that specific kind of file.




Assignments can also be created by the teacher. In the screenshot below a student is trying to reply to an assignment. The body of the assignment reply is automatically filled up with the body of the assignment that is selected by the student, this eliminates the need to open another browser window or tab to see the contents of the assignment. The student can just delete it later once the reply to that particular assignment has been written.


Replies to a particular assignment can also be viewed by the teacher.




Sessions can also be created by both students and teachers. There are 3 kinds of sessions one is the class session which can only be created by the teacher. In a class session all the students in the class are automatically a part of the session which means that every student in the class can enter the session as long as it is still valid. Another kind of session is the masked session which is similar to the class session as all students in the class are automatically members, the only difference is that there is a choice for the session members to use an alias. The alias is used to conceal the identity of the student. This feature is useful for the students to share their thoughts on something without revealing their identity. The third kind of session is the team session where a student can choose who will join the session. Session members can either be composed of a single group or multiple groups to which the student belongs. 


Here is what a masked session looks like as I have mentioned earlier the members of this session can actually choose an alias to use. A session is really just a traditional chat box where the students and teachers can discuss about things related to their class. I used Node.js and Socket.io to ensure optimum performance.



Class Settings

There’s also a separate module where the teacher can enable or disable specific modules in the class. Disabling a module will cause it to be inaccessible by both the teacher and the student. This feature is useful for the teacher to control which modules can be used by the students this also saves space in the database because modules that aren’t necessary to the class is disabled therefore the students cannot post anything which consumes space on the database.


Student accounts created by the administrator can also be invited by the teacher as long as they’re not already a member of the class. Only students which aren’t a member of the current class is listed.


Once invited there will be a new entry listed on the invites panel where the student has the option to accept it or leave it be. I’m also planning to have a decline button in there just in case the student was added by teacher by accident.



Existing students can also be removed from the class. This is useful in cases wherein the teacher accidentally invited a student into the class and the student also confirmed the invite even if he is not formally a member of the class.



Classroom data can also be exported by the teacher to other classes that he handles. At the time of writing of this post only students and handouts can be exported to another class. Some of the obvious limitations is that it’s only good for bulk export, the teacher cannot select what specific data to export to another class. And that only one export at a time is allowed.




There’s also a reports module which allows the teacher to view the student activity log. This module is still under development. I’m planning to add reports that will answer questions like: who are the students who aren’t submitting their assignments, who are the students who has not viewed their handouts, who are the students that always gets low on quizzes, who are the students who doesn’t participate in class sessions and other reports that might be useful to the teacher.



User Visibility

To ensure the visibility of a user to another user I’m also planning to add a feature wherein every user who is currently logged into the system can set if they are online or offline. This gives the user an option if he wants to declare that he’s currently using the system or not. Just like what has done by Facebook on their chat box.



Here is what the class looks like when an administrator is looking at it. There’s an additional module accessible to the administrator which allows him to change the settings in the class.


The administrator can access any classroom and view its contents. But it’s only for viewing. The administrator cannot be involved in any class activity like posting assignments and handouts. The administrator module is still under development so I’m still thinking of the possibility for the administrator to be an automatic member of every class that he creates.

The administrator is the only one who can create new classes so the teachers has to approach the administrator if they want to create a class. Every class has only one teacher. A class has also a start and lock date, once a class has reached its lock date a notification on the teachers dashboard will show up prompting the teacher to lock the classroom if the teacher wants the classroom to be continually accessible to the students then he can just ignore the notice. But once the teacher has chosen to lock the classroom it will no longer be accessible to both the teacher and the students. But the admin can still unlock it if the teacher requests for it.




As you can see Zenoir Online Classroom is still incomplete, there are still features which are not incorporated in the system and there are still some bugs because I haven’t done a thorough testing of it yet. If you want to contribute to this project feel free to visit it’s page on Github and either download, clone or fork it.

Zenoir Online Classroom

If you have any questions or suggestions regarding this project feel free to throw them in the comments! Thanks!

Rendering files from MySQL Database into the browser

Howdy! I haven’t posted anything on this blog for more than 3 weeks now. I’m really sorry especially to those who are subscribed to this blog via email. I was just too busy with my projects and school that’s why I wasn’t able to post anything new.

Okay enough with my life story. Let’s proceed to the main topic. In this tutorial I’m going to show you how you can read files that are saved on the database and then render it into the browser.

I’m going to make this quick because I’m really super sleepy now.


Rendering Images

Rendering images is really simple, you just have to use the traditional image tags in html:

<img src="renderer.php?id=2"/>

But wait, why are we linking to a php file? Good question. Images, audio files, video files, documents are actually stored in the database in a gibberish form. Don’t believe me? Here’s a screenshot taken from Heidi Sql when opening a file that is saved on the database.


That is binary data, you cannot really make sense out of it unless you have a brain of a computer.

Okay so what does this renderer.php contain?

As you have seen a few seconds ago we supplied an id on the url and that’ what were going to use as a basis for what were going to fetch from the database. This is actually an approach for the naïve and lazy, I don’t recommend using $_GET and strings from the url as a basis for your database queries. It’s dangerous because people are getting smarter and smarter everyday there’s almost always a security hole on almost every application.

First include the database configuration, then assign the query to a variable called $id then perform the query for fetching the file in the database.

require_once('zenoir_config.php'); //database config $id = $_GET['id']; //don’t do this in real life, for example only $file = $db->get_row("SELECT * FROM tbl_files

WHERE file_id='$id'"); //fetch data

Now we got all the values that we need:

$filename = $file->filename;
$data = $file->file_data; //binary gibberish
$mime = get_mime_type($filename); //mime type of the file

The first two variables are self-explanatory we need the data and the filename. But what is this mime type thingy? If I am to describe it on my own, mime types are like instructions to the browser on what type of data it’s going to render. If the browser can’t render that specific data then the default action taken by the browser is to store it on the local machine or the computer of the user that is accessing the website. Here’s an extensive explanation from Wikipedia about mime types:


Here’s the code for getting the mime type of a specific file. I actually got this piece of code from someone at php.net in the comments section. Yep! comments section is really a gold mine.

function get_mime_type($filename, $mimePath = 'yeah'){ 
   $fileext = substr(strrchr($filename, '.'), 1); 
   if (empty($fileext)) return (false); 
   $regex = "/^([\w\+\-\.\/]+)\s+(\w+\s)*($fileext\s)/i"; 
   $lines = file("$mimePath/mime.types"); 
   foreach($lines as $line) { 
      if (substr($line, 0, 1) == '#') continue; // skip comments 
      $line = rtrim($line) . " "; 
      if (!preg_match($regex, $line, $matches)) continue; // no match to the extension 
      return ($matches[1]); 
   return (false); // no match at all 

The function above uses a file called mime.types, which can be found on the following location if you’re on Wamp:


But if you’re on Xampp it’s in:


Never mind the Drive letters, its dependent on where you installed the Xampp or Wamp.

In the example I placed the mime.types file on the yeah folder:


Oh yes, I still haven’t told the story of this get_mime_types function. What it does is just to get the file extension of the file which is determined from the filename. This isn’t actually an accurate method of determining the true mime type of a file. What if someone naughty changed the extension of a php script to .jpg. The function will actually label the php script as an image and not a script which can do nasty stuff on the server. A good practice for this is when you plan to upload files on the file system of the server be sure to upload the files on a non-web accessible folder so that the naughty guys will not be able to execute it. 

After determining the mime type all you have to do now is to include the header information and then output the actual data.

header('Content-Type: ' . $mime); 
header('Content-Disposition: attachment; filename='.$filename);

echo $data;

In the case of an image this data will be rendered as an ordinary image in the browser such as this one:



Rendering Other Files

Rendering other file types is still a problem at the time of writing of this article. How I wish the following tags were already existing:

<document src="msword.doc"/> <!—doc files—>
<spreadsheet src="worksheet.xlsx"/> <!—spreadsheets—>
<presentation src="awesome.ppt"/> <!—powerpoint—>
<code src="php.js"/> <!—for rendering source code with highlighting etc.—>

Don’t copy and past those code, those are just my dream. I hope it would be possible to render just about any type of file that makes sense in the browser.

Good news is you can actually store mp3, ogg, mp4, and webm files on the database and render them using either the html5 video or audio tags. But remember that not every browser supports this awesomeness (IE I’m looking at you).



That’s it for this tutorial. Rendering image files that are stored in the database is actually easy, but other file types are not.

ChatRo–Instant Messaging Application

I always create tutorials for this blog. This time I want to break the ice and share something else, and I guess I’m going to continue writing these types of post whenever I have a personal project or maybe a formal project if the product owner allows me to write something about it.

In this post I’m going to share about ChatRo, a web application that allows for team collaboration through instant messaging, file sharing, and file management.



Everybody knows about this one. No need to trouble you from reading.




This is where users invited via email can register. After registering the user will automatically be added into the group as long as the link on the email is the one that is used to get into the application.



Instant Messaging

This is where users that belong to the same group can interact with each other through a chat box. Documents, pictures, audio and video files can also be shared to the users currently on the session through this form. Any user who are on the current session can end the session, not just the user who created the session. Every user can only participate in one session at a time.


Creating a new session is done by clicking on create session link and specifying the group and session name. The group name is an auto-suggest field which fetches all of the groups to which the current user belongs.



Group Management

This is where users can create new groups or manage existing groups.



Group Invite

Anyone can be invited into a group via email.


Existing members of other groups can also be invited. This is an auto-suggest text field that fetches all the users of the chatRo.


The invited user isn’t automatically added to the group. He has to accept or decline the request. Either way, the notification will stay on the home tab until the user decides to decline or accept the invite.


New groups can also be created.



 File Sharing

This can be used to share files to the other members of a session. In the screenshot below I’m uploading an Ebook from Makeuseof.


After the file has finished uploading, a message will automatically be created pointing out to the file that has been uploaded.


Clicking on the magnifying glass icon will preview the file. As of the time of writing of this article there’s still no preview for the front page of a pdf file, its just a link that the user can click to view the pdf file on the browsers built-in reader. But if there’s no built-in reader, it will just download the file into the local disk.


If the uploaded file is images it will be previewed with a download link on top of the image preview.


There’s also a preview for excel files.


Audio files can also be played as well, brought to you by html5 <audio> tag.


Lastly, video files can also be viewed brought to you by html5 <video> tag.


Yes it’s good that were able to play mp3, mp4 and other html5 compatible files but this magic still doesn’t work on some browsers. As of the time of writing of this article, I only managed to make it work for Chrome.



Once a session is ended it goes into the archives. This is simply a box where you can view the conversations in previous sessions. It’s only used for viewing previous sessions so there isn’t actually a link for the files that are mentioned in the conversation. These files can be viewed in the files tab.




There’s also a separate tab for viewing all of the files that were uploaded. This disregards the session to which the file was uploaded. It is simply a box wherein you can search for previously uploaded files of the people that are in your group.




I guess that’s it, if you want to test, contribute, fork this software then you could visit its GitHub page. All the files that you need are already in there, you could also go through the README file if you want to learn more about this application.


There’s still a lot of bugs and a lot of room for improvement and additional features, I’d really appreciate it if someone could contribute to this project. If you have some questions regarding this project feel free to ask them on the comments section. Thanks for reading!




Javascript and Jquery



Programming Practices

.Net Framework

Ruby on Rails


PHP Frameworks






Theme Customization




PSP Games

Things to do before you present your php project

In this article I’m going to share to you some of the things that you need to check before you present your php project. Some of these things often get left out and actually stays unpatched. Yup! I’m talking about errors here. Errors which only shows up accidentally. Errors which can only appear by letting an idiot or a monkey use your system. Yes, systems are made for humans but sometimes you need to act like a monkey in order to uncover the errors.


String Sanitization
Sanitizing your string is number one on this list folks. Most of the web applications today uses databases to store and retrieve data. And to store and retrieve data, we use SQL or the Standard Query Language. And SQL only allows certain keywords, you actually get an error if you don’t comply with the syntax just like with any programming language.
So where does string sanitization enter from here? Here’s an example query to let you understand where will we need string sanitization, try to run it if you don’t know the output yet:

SELECT * FROM def_transactions WHERE transactionID='''

That’s just the query, in php it looks like this:

$transaction_id = $_POST['trans_id'];
$db->query("SELECT * FROM def_transactions WHERE transactionID='$transaction_id');

You can conclude now that the same SQL error will pop out if someone inputs a single quote on the transaction id field. Go ahead and try it.

So how do we sanitize the string?The simplest way to sanitize a string is already built-in to php. The mysql_real_escape_string() function. You use it this way:

$transaction_id = mysql_real_escape_string($_POST['trans_id']);
$db->query("SELECT * FROM def_transactions WHERE transactionID='$transaction_id');

The error won’t bother you again. What mysql_real_escape_string() does is to escape all the characters which are invalid in SQL. You might say that it’s an addslashes() on steroids.


Empty Results
Second on the list is empty results. Its crucial to check if the query that you’re trying to call actually returns any result set. You’re asking for trouble if you don’t perform checks. Consider the following example:


$name = $_POST[‘name’]; $results = $db->get_results("SELECT * FROM tbl_people WHERE name LIKE ‘%$name%’"); foreach($results as $r){ echo $r->name.'<br/>'; } ?>

So what’s wrong with the code above? Aside from the fact that we didn’t perform sanitization. You might also noticed that we’ve gone ahead and loop through the results without even checking if there are any results at all. The code returns an error which tells you that the argument passed to the foreach loop is invalid. To fix the code we change it to the one below.

<?php$name = $_POST[‘name’];
$results = $db->get_results("SELECT * FROM tbl_people WHERE name LIKE ‘%$name%’");
        foreach($results as $r){
            echo $r->name.'<br/>';


Thorough Checking
Before you present any application you must thoroughly check that its working fine and that errors doesn’t show up here and there. But test your application in such a way that errors will actually show up. Here’s how:

  • Input all sorts of crazy stuff, symbols, and other unnecessary characters on the text fields.
  • Test all the possibilities, not just one. For example, if you have a function that returns either true or false based on the value of the argument that is passed to it, then test it in such a way that you see true and false. Don’t conclude that its working 100% if you’ve only seen one side of the coin.
  • Examine your application. If you see something that you think isn’t user friendly, something that you think might cause some errors in the future, or a text field which shouldn’t take a specific data type. Then take note of it and change it if you have enough time. Don’t push lots of changes overnight if you think you can’t make it.
  • Make sure that the flow of the program is correct.
  • Let others use your application. And ask them for suggestions or if they’ve seen any errors.


Turn Off Error Reporting
This might be your last option. Turning off error reporting is not advisable if you’re still in the process of testing your application. But if you don’t want anyone to be seeing errors while your presenting your application this is your best bet. To turn off error reporting just uncomment the production values just like the one below, you can use the find tool to quickly jump to the lines below:

; display_errors
;   Default Value: On
;   Development Value: On
    Production Value: Off

; display_startup_errors
;   Default Value: Off
;   Development Value: On
    Production Value: Off

; error_reporting
;   Default Value: E_ALL & ~E_NOTICE
;   Development Value: E_ALL | E_STRICT
    Production Value: E_ALL & ~E_DEPRECATED

; html_errors
;   Default Value: On
;   Development Value: On
    Production value: Off

Here’s a sample code that will issue an error if the default values for error reporting are being used:

echo $a;

Here’s what you usually get if you run the code above:

And here’s what you get if you uncomment the production values for error reporting:


Awesome, but I only recommend this one as  a last resort. Be careful to comment out the production values after your presentation as this might give you the illusion that there is nothing wrong with your program.


I guess that’s it! You’ve learned some of the things that you should do before presenting your php application. These tips might also apply to other programming project not just in php. I hope you enjoyed reading!

Web Development Resources August 2011

This kind of stuff must be familiar to you if you’re always reading web design blogs like Smashing Magazine and NetTutsPlus. They often times call it roundups, wherein they put together a collection of resources on web design.

Well, what you’re reading now is basically my very own roundup. These are things that I might have shared on my GooglePlus, Twitter or Facebook account. Or just something that I stumbled upon recently.



Rumble is a jQuery plugin that rumbles, vibrates, shakes, and rotates any element you choose. It’s great to use as a hover effect or a way to direct attention to an element. You can control the X, Y, and rotation range, the speed, and event trigger for the rumble.



40 Online Generators

A collection of button generator, tabs generator, css3 generator, graph generator, and other online generators that can make a designer’s life easier.



PHP tutorial

If you think that stuff at php.net are not beginner friendly. Then this page might give you a second thought:



Mega drop-down menus

Another goodie from Soh Tanaka. Mega drop-down menus as the name suggests are drop-down menus which has lots of sub-menus.



Live Validation

javascript plugin for validating text fields



PHP MySQL Web Development Security Tips 

A nice collection of tips for making secure php applications



PHP Magic Constants

magic constants on php are more like built-in functions which returns a value.




10GB of free cloud storage

This isn’t a joke, go visit the link below and try it yourself. Its really 10GB of free storage, and there is no  size limit for each uploaded file. Which means that you can upload a full blu-ray movie as long as your internet connection is faster than lightning mcqueen.


HTML 5 essential resources

A collection of html 5 resources. From the official whatwg site, html5 gurus on twitter, to different frameworks and tutorials on html5



Current state of html5 forms

awesome collection of new html5 forms, and form attributes and their support to the different browsers.



Determine IP address

If you need to quickly know the external ip address used by your computer, then visit:



PHP Ground

Collection of php tutorials. Ranging from the bare-bones php to php frameworks like code igniter.



css background animation

shows you how to animate background using css and a static png file.



Command-line php

Bringing php in the command-line for debugging purposes



PHP Chaining

method chaining in php similar to jquery




awesome site which brings tips, tutorials on web development. Expect to see some jquery, javascript and php stuff.



twig php templating engine

yet another templating engine for php similar to smarty.




The search engine for php developers



sparks on google plus

a nice content discovery tool from google



code hosting sites

another nice collection of sites which hosts web application, desktop application projects.


How to use dompdf with css

I think its about time I create another tutorial on this awesome php library called dompdf.
For the sake of the innocent, dompdf is a php library used for generating… Surprise!
PDF documents using php.

So what the heck am I going to discuss in this article? What’s the relevance of this article?
To get you fired up, were going to create a sample page which has a sample table on it, then a print button and when the user clicks on it. A pdf file pops out of the browser.

So let’s go ahead and get started.


  • Dompdf


I assume that you already know how to make use of css. Not the inline css, because that’s a thing of the past. I guess in the 90’s people used that. When I say css, were talking about this:

   font:14px Georgia, serif, calibri;

And this:

<link rel="stylesheet" href="external.css" type="text/css"/>

Oh,and definitely NOT this:

<th style="height:90px;">Some Header</th>

I also assume that you already know the basics of using dompdf, which I unfortunately tackled here:

How to use dompdf

Unfortunately because I believe that I had not explained the concept of output buffering and the whole dompdf thing in that article. So the article that you’re reading right now can be considered a remake. You can also visit the link above if you want.

And yes, I almost forgot that you must also know the basics of php and programming itself. Variables, echo, dollar signs, loops and every basic thing about php and programming that you can think of.


First you have to prepare the table for all the food that were going to eat today.
Yup! I’m saying that you download dompdf, extract it, place it on a testing folder, then create 2 files.

  • One for viewing the output – this page will have the PRINT button on it.
  • Another for generating the pdf

After setting up all the necessary requirements…

Ooops, I guess that’s a little bit redundant, but never mind I’m a little energetic tonight(10:30pm) so please bear with me.
Go ahead and write your own css for the first page(view). But if you want to make your life easier, then just copy the one below.

<style type="text/css">
	background:url(print.png) no-repeat;

That’s an internal css. You can also make it external if you are the outgoing type.
And sorry if I disappointed you with that stylesheet. I just used it to put a background image on a link disguised as a button(don’t worry, you’ll know what I mean soon enough..)

Next, let’s create the array where we will fetch the data for our table later.

$x= array(array('name'=>'wern', 'age'=>10),array('name'=>'vongola','age'=>20),
array('name'=>'mikado ryugamine','age'=>15), array('name'=>'pikachu','age'=>50));

When I make tutorials like this, I see to it that I don’t make much effort on naming things. Just like that $x variable. And all the names in the array are anime characters except the wern because that’s my name.

After that, start buffering the output. Any code whether html, php or css which comes after the code below are being stored somewhere I do not know. What’s important is that it is stored with all the format, the markup and everything.

<?php ob_start(); ?>

Then create the header for the table:


Yup, I didn’t include the table tag on purpose just to make sure that the output of those who just copy paste ain’t gonna work.

After that, go ahead and loop through the array that we created a while ago.

foreach($x as $y){

That’s yet another incomplete code. Its just basic so go figure out how to do it before you continue.

Then call the ob_get_contents() function that’s built in to php. This function gets all the content that was stored in the ob_start() function. In other words, every single markup, css that came right after calling the ob_start() function. I still haven’t tested if this function also buffers the all the markups (html) that are enclosed in if or switch statement. You go try it out yourself and comment what you got in this post.

   $out = ob_get_contents();

After that, you can put the buffered contents on a session array or a cookie. For this tutorial were going to make use of a session even if cookies sounds more delicious.

   $_SESSION['prints'] = array('table'=>$out);

What we just did is to assign the $out variable which has all the buffered contents, into a session array item called ‘table’. Its important that you remember the name of the session because were going to need it later on. If you’ve not yet decided, the name of the session here is ‘prints’.

You can close the file that you’re working on for a while or just leave it as it is (if you’re not using notepad). Because were gonna work on the SECOND FILE now.

First, do the housekeeping:

$dompdf = new DOMPDF();

Include the dompdf class into your current file, then initialize the dompdf class by creating an object. The name of the object is not necessarily $dompdf, you can use $puke if you want. Ooops, sorry if you’re eating while reading this.

Then assign the contents of the table session to a variable.

$tbl = $_SESSION['prints']['table'];

Then buffer the current page:

<?php ob_start(); ?>

Put some css:

<style type="text/css">
* {
  margin:0; padding:0;
  font:14px Georgia, serif;

  margin: 0 auto;

   border-collapse: collapse; width: 100%;

   border:1px solid #ccc; padding:10px;


This really got me on my first try, I didn’t buffer the css along with the html, that’s why the output was a pure html pdf file. Oh and don’t get confuse with the pure html pdf file. It just means that it’s a pdf file without any styling or anything fancy formatting on it.

Then output the contents buffered from the first file that we created:

  echo $tbl;

Finally, get the buffered contents again. It’s still the same markup we just added a css into it:

  $out = ob_get_contents();

Don’t forget the ob_end_flush() function. If I’m not mistaken it’s the function that clears the cache for the output that has been buffered. We don’t need it since we already assigned it to the variable $out.

Okay, so here’s a little function that I created to generate pdf’s:

function generate_pdf($filename){
	global $dompdf;

	$dompdf->stream($filename. ".pdf", array("Attachment" => 0));

Remember that in every function, whether its  a function declared inside a class or just a plain function in your good old php written in procedural form. You always have to put the word global right before an object of a class. In this case the $dompdf object.

Finally, go ahead and do the last 2 steps. First, put the contents of the $out variable into a file called styled.html

file_put_contents('styled.html', $out);

After that, just call up the function that generates a pdf file from the html file that we just generated.


Of course, you can be creative and put the current time as the suffix for the filename. But I’m not going to show it here since I also don’t know how to do that.


If you still haven’t noticed. We can actually strip down the process by directly converting the buffered contents into pdf. To cut things really short, here’s what you need in the most basic level:

$dompdf = new DOMPDF();
$tym = date('g:i s');
$filename = 'print'.$tym;

$dompdf->stream($filename. ".pdf", array("Attachment" => 0));

The code above just showed you the answer for the question a while ago. Appending the current time to the filename of the pdf that will be generated.

We then loaded the html from the ‘prints’ session that we created a while ago.

Then we called the render() function from the dompdf class. This will render the html into pdf. By the time you call this function a pdf file already exist somewhere I don’t know, maybe the browser cache, a temporary folder in the server(wampserver if you’re on windows) or anywhere else.

Lastly, we called the stream() function. This will pop out the pdf file into the users face. It takes two arguments: the filename for the file, you also have to place the file extension which is pdf. The second argument is the option, the one above does not force the browser to open a download dialog box(I don’t know the actual name so bear with me). If you place 1 as the value for the attachment, it does the exact opposite.


That’s it! I guess this tutorial has already taken too long for you to be bored to death. As always, I hope that you learned something. Here’s a summary of what we did here:

  • Using output buffering in php
  • Generating html file from the data stored by the ob_start() function
  • Generating pdf from an html file
  • Generating pdf directly from the buffered output or html

Don’t forget to comment if you don’t understand something. Or if you have any suggestions.