Creating a simple debug() function

If you are ever like me and hate having to type print_r and echo pre blocks whenever you want to debug a variable or array, this function is for you! This is a global function that can be used to output any data that you need to debug and it comes equipped with some nifty features. For one thing, the debug() will not output any data on the website if error_reporting is turned off, which is good for instances where you forget to remove the debug() code! It will also display the file and line number where the debug() was called, and you can pass true as the second argument to do a var_dump instead of print_r. Here's the code for your enjoyment!

/**
 * Outputs/Debugs a variable and shows where it was called from
 *
 * @param mixed $var
 * @param boolean $dump
 * @param boolean $backtrace
 * @return string
 */
public function debug($var, $dump = false, $backtrace = true) {
	if (error_reporting() > 0) {
		if ($backtrace) {
			$calledFrom = debug_backtrace();
			echo '<strong>' . trim(str_replace($_SERVER['DOCUMENT_ROOT'], '', $calledFrom[0]['file'])) . '</strong> (line <strong>' . $calledFrom[0]['line'] . '</strong>)';
		}
		echo '<pre class="debug">';
		$function = ($dump) ? 'var_dump' : 'print_r';
		$function($var);
		echo '</pre>';
	}
}

Please note that this is a very basic debug function with very basic backtrace functionality. Here are a few examples on how to use the function (if for some reason you don't understand it).

debug($_SERVER);
// var_dump() instead of print_r()
debug($_SERVER, true);
// Do not display the backtrace
debug($_SERVER, false, false);

Two new scripts, Resession and Decoda

It has been a while since I released some of my scripts, but now I have two to reveal! Well actually the Resession script has been up for nearly 2 months now, but I'm finally getting around to announcing. And without further ado, I give you Resession (Session Manager) and Decoda (A BBcode style parser).

Decoda

Decoda is a lightweight class that extracts and parses a custom markup language; based on the concept of BB code. Decoda supports all the basic HTML tags and manages special features for making links and emails auto-clickable, using shorthand emails and links, and finally allowing the user to add their own code tags.

Download the latest versions of Decoda

Resession

A small lightweight script that can manage and manipulate Session data. Calls session_start() in memory so that no header errors are thrown, as well as stores the session id in the object.

Download the latest version of Resession

If you have any suggestions for either of these classes, please feel free to comment this post or send me an email!

Numword officially released

So I'm releasing this fun little script I built a few months ago, it's called Numword. This script will take a number and convert it into its word equivalent. For example, 12 will become twelve, and 7 will become seven. Now why did I create this? Well one day a friend asked me if there was a PHP function that would do this, but there wasn't, so I set out and a few hours later it was done! I thought it would be a good idea to release this to the public, for anyone who might need something like this, as rare as it would be. Enjoy!

Download Numword v1.2
View the complete change log

Databasic v1.10.3 Released

It seems the most recent version of my Databasic class had a few problems in it. I left some code in there (echos and comments) that was used while I was testing, and I forgot to revert it. I want to thank Tanax for sending me an email and pointing it out. To everyone else, please download the latest version (1.10.3) and be sure to email me if you find any problems.

Download Databasic v1.10.3
View the complete change log

Custom PHP Functions: Datetime functions

All of these functions can be found within the Titon Utility library.

It is now time for my second post, in my series of "Basic/Common PHP functions that all programmers should know". The first series was about basic PHP strings and with this issue I am going to tackle 5 more functions for date and time. As always, I try to make my functions short but powerful, enjoy!

If you have any ideas for a series you want to see, or a type of function, be sure to send me an email using the contact page (in the footer), thanks!

Days Between

This function finds the difference in days between two dates. Each date must be a unix timestamp; if not my function will try to convert it to one. This could be modified to find the difference in weeks, seconds, etc.

/**
 * Finds difference in days between dates.
 * 
 * @param int $start
 * @param int $finish
 * @return int
 */
public function daysBetween($start, $finish) {
	if (!is_int($start))	$start = strtotime($start);
	if (!is_int($finish))	$finish = strtotime($finish);
	$diff = $finish - $start;
	$days = $diff / (24 * 3600);
	return round($days);
}
Get Age

This is a pretty simple function, in that it will find the persons age depending on the year given and the current year. The birth year could either be a string of '1988' (4 numeric characters) or the full date 1988-02-26.

/**
 * Gets the age of an individual.
 * 
 * @param int $timeStamp
 * @return int
 */
public function getAge($timeStamp) {
	$seconds = time() - strtotime($timeStamp);
	$year = 60 * 60 * 24 * 365;
	return floor($seconds / $year);
}
Get Date/Time in Timezones

Now this is something that could be done in many numerous ways, but mine simply takes the timezone difference (-8, 0, +6, etc) as the second argument, and then returns a unix timestamp. This function does not have any input checking (so make sure your arguments are correct before hand) and does not apply Daylight Savings Time.

/**
 * Gets a unix timestamp in certain timezones.
 * 
 * @param int $timeStamp
 * @param int $timeZone
 * @return int
 */
public function timeInZone($timeStamp, $timeZone = -8) {
	return strtotime(gmdate('Y-m-d h:i:sa', $timeStamp + (3600 * $timeZone)));
}
Date within a Timeframe

This function will take a date and check to see if it was within a certain date range and return a boolean value. My function will attempt to convert non unix timestamps to unix; be sure to pass the data correctly. Also you can leave the 3rd argument empty ($finish date) and the current time() will be used.

/**
 * Checks to see if a timestamp was within a timeframe.
 * 
 * @param int $check
 * @param int $start
 * @param int $finish
 * @return boolean
 */
public function withinTimeframe($check, $start, $finish = '') {
	if (!is_int($check))	$check = strtotime($check);
	if (!is_int($start))	$start = strtotime($start);
	if (empty($finish)) {
		$finish = time();
	} else {
		if (!is_int($finish)) $finish = strtotime($finish);
	}
	if ($check >= $start && $check <= $finish) {
		return true;
	}
	return false;
}
Breakdown a timestamp

Now this next function is quite different then the previous ones, but is pretty powerful. This function breaks down the timestamp to find how many days, weeks, months, etc there are until the current time (using time()). This type of function is good for doing text like: Last comment 5 days, 3 hours ago.

/**
 * Breaksdown a timestamp into an array of days, months, etc since the current time.
 * 
 * @param int $timeStamp
 * @return array
 */
public function timeBreakdown($timeStamp) {
	if (!is_int($timeStamp)) $timeStamp = strtotime($timeStamp);
	$currentTime = time();
	$periods = array(
		'years'         => 31556926,
		'months'        => 2629743,
		'weeks'         => 604800,
		'days'          => 86400,
		'hours'         => 3600,
		'minutes'       => 60,
		'seconds'       => 1
	);
	$durations = array(
		'years'         => 0,
		'months'        => 0,
		'weeks'         => 0,
		'days'          => 0,
		'hours'         => 0,
		'minutes'       => 0,
		'seconds'       => 0
	);
	if ($timeStamp) {
		$seconds = $currentTime - $timeStamp;
		if ($seconds <= 0){
			return $durations;
		}
		foreach ($periods as $period => $seconds_in_period) {
			if ($seconds >= $seconds_in_period) {
				$durations[$period] = floor($seconds / $seconds_in_period);
				$seconds -= $durations[$period] * $seconds_in_period;
			}
		}
	}
	return $durations;
}

And there you have it, 5 functions dealing with date and time. Stay tuned for the next issue! And again, if you have ideas for functions, send me an email!

My open-source scripts officially released!

So it has taken me nearly a year to get to this point. Over the past year I have been building some very advanced PHP classes and scripts that I wish to release as open-source. The types of scripts range from database handlers, template engines, form validation and cleaning, session management, CakePHP components and behaviors, so on and so forth. For the time being im releasing 3 scripts that I deemed "stable" and "complete". I hope you love them and get as much use out of them as I have. The following 3 scripts are now officially released to the public!

Databasic - A basic wrapper class for the MySQL database engine. Contains methods for connecting to a database, fetching and returning results, building insert and update queries, optimization and more.

Gears - A template engine that loads template files, binds variables to a single file or globally without the need for custom placeholders/variables, allows for parent-child hierarchy and parses the template structure.

Commentia - Commentia is a CakePHP Behavior that automatically runs after a comment is made. Each comment is tested upon a point system to determine and classify it. If a comment has more then 1 point it is automatically approved, if it has 0 points it continues pending, and if it is in the negative point range it is either marked as spam or deleted entirely.

Custom PHP Functions: String functions

All of these functions can be found within the Titon Utility library.

It's now time for some PHP that isn't Cake related. This is the first part in a series of "Basic/Common PHP functions that all programmers should know". This series has to deal with manipulating strings. I try to make my functions short, sweet and powerful, and I hope you learn something from them.

Truncate

This function takes a long string and shortens it to a defined length and adds appends an ellipsis (or custom string) to the end. Instead of chopping a word in half (if the limit finished within it), it moves the pointer up to the previous space.

/**
 * Truncates a string to a certain length.
 * 
 * @param string $text
 * @param int $limit
 * @param string $ending
 * @return string
 */
public function truncate($text, $limit = 25, $ending = '...') {
	if (strlen($text) > $limit) {
		$text = strip_tags($text);
		$text = substr($text, 0, $limit);
		$text = substr($text, 0, -(strlen(strrchr($text, ' '))));
		$text = $text . $ending;
	}
	return $text;
}
Shorten

This function works similarly to truncate(), but instead of chopping off the end of the string, it chops out the middle. This is useful for shortening users long names or websites.

/**
 * If a string is too long, shorten it in the middle.
 * 
 * @param string $text
 * @param int $limit
 * @return string
 */
public function shorten($text, $limit = 25) {
	if (strlen($text) > $limit) {
		$pre = substr($text, 0, ($limit / 2));	
		$suf = substr($text, -($limit / 2));	
		$text = $pre .' ... '. $suf;
	}
	return $text;
}
Obfuscate

Now this function doesn't directly scramble the text and confuse the user, instead it scrambles the source code. This is useful for displaying emails or other strings that you don't want to show up directly in your source code.

/**
 * Scrambles the source of a string.
 * 
 * @param string $text
 * @return string
 */
public function obfuscate($text) {
	$length = strlen($text);
	$scrambled = '';
	for ($i = 0; $i < $length; ++$i) {
		$scrambled .= '&#' . ord(substr($text, $i, 1)) . ';';
	}
	return $scrambled;
}
Slugify

This function takes a string and makes it SEO and URL friendly (for example in the address bar for my blog posts). It lowercase's all words, replaces spaces with a dash, removes foreign/illegal characters and follows the guidelines for the best possible SEO. For example "Hello, my name is Miles Johnson!" would convert to "hello-my-name-is-miles-johnson".

/**
 * Rewrite strings to be URL/SEO friendly.
 *
 * @param string $text
 * @return string
 */
public function slugify($text) {
	$text = trim(strtolower($text));
	$text = str_replace(array('-', ' ', '&'), array('_', '-', 'and'), $text);
	$text = preg_replace('/[^a-zA-Z0-9\-_]/is', '', $text);
	$text = urlencode($text);
	return $text;
}
Listing

This final function takes an array of items and turns them into an ordered list with the last item having the word "and" in front of it instead of a comma. Very good for making lists.

/**
 * Creates a comma separated list with the last item having an "and".
 *
 * @param array $items
 * @param string $and
 * @return string
 */
public function listing($items, $and = 'and') {
	if (is_array($items)) {
		$lastItem = array_pop($items);
		$items = implode(', ', $items);
		$items = $items .' '. $and .' '. $lastItem;
	}
	return $items;
}

Now that's all I have for now, and I know you will use this in your code constantly just like I do! Be patient for my next series which will be dealing with basic date/time functions.

Riding the Frameworks

So for the past week I have been learning Symfony and CakePHP, both amazing PHP frameworks. I'm curious to learn a framework because I have many large scale projects I would like to build and it would just be easier to use a framework. Symfony is hosting this daily blog where each day it posts a new tutorial and within a month you should understand the framework. Its currently at day 5 and I already understand the structure of Symfony, albeit Propel is quite complicated.

Cake grabbed my interest first, simply because the structure and MVC is extremely easy to understand. The hardest part for me to grasp is the Model system and its hasMany, belongsTo, etc... but I am getting there. The documentation is also very easy to read, I read through the whole cookbook in about 5-6 hours and keep going back for examples and references. Ill admit though, the cookbook is a bit basic in that it doesn't explain some key features thoroughly, your best bet is to open the PHP files yourself and try and figure out what they do.

But right now I'm learning towards Cake, simply because its extremely lightweight compared to Symfony and I prefer its file structure and MVC. Ill give it to Symfony though, its YAML is the easiest thing to write and understand and it also encompasses a strong routing system. Ill be updating more along my PHP journey.