Tag Archives: PHP

Crop an Image with PHP

I spent a few minutes working on this function that lets me crop the center of an image by width and height. Sometimes you want to create a photo gallery and use album covers for the image that links to the gallery page. Most of the time you want these images to be of a uniform size, i.e. thumbnails. This function (crop_image()) crops an image equally proportioned in the center depending on the size you give it.

Side note: If the spacing in the code is still FUBAR’d when you read this, sorry, I don’t know wtf’s up with my syntax highlighter, but I’m working on it.

Requirements for this to work properly (strictly recommended)

  • PHP 5.2.x (at least, however I’m pretty sure it will work in PHP 4)
  • GD 1.8

The function

/**
* @copyright crainbandy.com
* @since November 6th, 2008
* @author bryan maxwell - www.crainbandy.com
* --------------------------
* @name crop_image
* @package image editing
* @subpackage cropping
* --------------------------
* @link http://www.crainbandy.com/2008/11/06/crop-an-image-with-php/434
*
* This is a function that allows you to take any image $image and crop it to a specific size.
*
* @example crop_image('images/something.jpg', 'images/cropped.jpg', 125, 125);
*
* $_SERVER['DOCUMENT_ROOT'] is included on all image paths.
*
* @param string $src_image
* @param int $width
* @param int $height
* @param bool $cropped_image
* @param bool $link
* @return either true if it worked, or false if it didn't. or a string link to the image that has been cropped depending on $link's value.
*/
function crop_image($src_image, $width, $height, $cropped_image = false, $link = false) {
/**
* Setup some variables
*/
$dir = dirname($src_image);
$image_filename = $src_image;

/**
* Get the extension
*/
$len 		= strlen($image_filename);
$extension 	= substr($image_filename, $len - 4, $len);

/**
* Create the handles
*/
$src_file = $_SERVER['DOCUMENT_ROOT'] . $image_filename;

/**
* What kind of file is it?
* --
* Clean it up a bit, then instantiate the image.
*/
$clean_extension = str_replace('.', '', $extension);
switch ($extension) {
case '.jpg':
case '.gif':
case '.png':
/**
* Use a variable as a function name to call it, dynamically.
*/
$type = ($clean_extension == 'jpg') ? 'jpeg' : $clean_extension;
$dynamic_function = "imagecreatefrom$type";
break;
}
$src  = $dynamic_function($_SERVER['DOCUMENT_ROOT'] . $image_filename);
$dest = imagecreatetruecolor($width, $height);

/**
* Are we renaming this? or just following suit with $src_image appending to it?
*/
if (!$cropped_image) {
$cropped_image = $_SERVER['DOCUMENT_ROOT'] . str_replace($extension, '_cropped' . $extension, $image_filename);
} else {
$cropped_image = $_SERVER['DOCUMENT_ROOT'] . "/$dir/$cropped_image";
}

/**
* Get size of the $src_file
*/
$size_array = getimagesize($src_file);

/**
* Set the size of the crop from the image.
*/
$crop_width  = 125;
$crop_x 	 = $crop_width / 2;
$crop_height = 125;
$crop_y 	 = $crop_height / 2;

/**
* Set original sizes
*/
$original_width  = $size_array[0];
$original_height = $size_array[1];

/**
* Logic
*/
if ($crop_width > $original_width || $crop_height > $original_height) {
die('Image dimensions are too big for the crop x-y you provided.');
}

/**
* Output the image
*/
imagecopy($dest, $src, 0, 0, $crop_x, $crop_y, $original_width, $original_height);
switch ($extension) {
case '.jpg':
case '.gif':
case '.png':
$dynamic_function = "image$type";
$result = $dynamic_function($dest, $cropped_image);
break;
}

/**
* Little bit of error control.
*/
if ($result) {
if ($link) {
return $cropped_image;
} else {
return true;
}
}

/**
* Trash.
*/
imagedestroy($dest);
}

How to use it

The function has five basic parameters. Three of which are required.

  1. src_image
    This is the relative path, including file name of the image you want to crop. $_SERVER['DOCUMENT_ROOT'] is appended already, so you can leave that out.
  2. width
    This is the width of the crop.
  3. height
  4. This is the height of the crop.

Two that are optional

  1. cropped_image
    This is the relative path to the output file including file name.
    Note: If you leave this blank it will append cropped_ to the src_image. image.jpg becomes cropped_image.jpg.
  2. link
    If yes, this will return the path to the cropped image.

Examples

This file is included with the download at the end of this article. You can reference these again in examples.php if you need.

/
**
* @copyright www.crainbandy.com
* @author bryan maxwell
*
* Crop image examples
*/
include('crop_image.function.php');

/**
* Crop an image to 125px by 125px.
*/
crop_image('uncropped_images/crop_me.jpg', 125, 152, 'cropped_images/i_got_cropped.jpg');

/**
* Crop an image 50x50 using the functions default naming convention
*/
crop_image('images/something.jpg', 50, 50);

/**
* Crop an image 25x25 using all properties.
*/
$cropped_image = crop_image('image.jpg', 25, 25, 'cropped.jpg', true);
echo "<img src="" alt="" />";

/**
* Crop an image 100x100 using the link function, but default naming.
*/
echo crop_image('image.jpg', 100, 100, false, true);

There you go, I hope you’re getting the hang of it.

Download

RAR Format (.rar) | Zip format (.zip)

Enjoi. If you have any questions please post in the comments. Spanks. Oh yeah, and DIGG IT.
Bryan

Data sanitization in PHP

I’m going to show you a simple, yet effective way to clean your data (sanitize it) before you attempt to insert into your database. I prefer using the $_REQUEST superglobal array instead of just $_POST or $_GET.

$_REQUEST encompasses $_GET, $_POST, and $_COOKIE inside one array.

We take the $_REQUEST array and do a foreach() loop over it assigning $k for the key and $v for the value of the array element we’re currently looping over. We then re-assign the value to the array after we have cleaned it.

foreach($_REQUEST as $k => $v) {
    $_REQUEST[$k] = addslashes($v);
}

You’re not limited to just the $_REQUEST array, you can use this method on any array that you need to perform specific actions on. There’s even functions built-in to PHP such as array_walk() that allow you to iterate over an array issuing callbacks on each element. The choice is up to you, I just prefer the simplest method.

Sanitization is not the same as validation.

The elephants instep,
Bryan

Templates & PHP together in harmony

NOTE: There were a couple bugs in this code, but they’ve been fixed. Feel free to copy and paste this code (following the instructions), and test for yourself. The newly corrected code is in bold.

So a lot of people ask me how I seperate “business logic” from “display logic” in my sites and just in general. Usually you have two options, well, the third one (which i’m not going to show) pretty much defeats the purpose but don’t worry about that.

The first choice you have is to create functions referred to sometimes as “get” functions, such as the following:
<title><?php get_title(); ?></title>
or something like <?php get_pages_content($active_page); ?> you get the point. These functions are very specific and are obviously pre-built.

Second choice you have is to create a template file and make it with real content and then replace it with template variables encased in curly braces. Like {THIS} and {THIS_VARIABLE} actually, you can use whatever you want to encase the variables in dashes, brackets, percent symbols. Just for the record I use curly braces. Basically what you’re going to end up doing is replacing the variables with values and then echoing the entire file. It’s cool, so, check it out.

This whole routine is going to take 3 files.

  1. A template file (template.tpl)
  2. a class to handle the template file (the template class, this will be inside template.class.php)
  3. an index.php page to initialize the class and draw the data.

For the sake of length, I’m going to use the second method (The first one is too difficult and not as efficient)
Step 1 – Create the template file (usually .tpl just for consistency) we’ll call this file template.tpl

<title>{TITLE}</title>
<body>
{NAVIGATION}
{CONTENT}
</body>

Copy this and save it as template.tpl
Incase you didn’t notice, this is not well-formed XHTML. It’s just for space-sake.

The template class (save this as template.class.php)

class template {
public $template;

public function __construct() {
// load the templates contents into a variable
$this->template['TEMPLATE'] = file_get_contents('template.tpl');

// set some default values in the construct
template::set('{TITLE}', 'Page title here');
template::set('{NAVIGATION}', '<a href="index.php">Home</a>');
template::set('{CONTENT}'], 'Some example content');
template::set('{STYLE}'], 'sytle.css');
}
// a function for setting template variables values
public function set($variable, $value) {
$this->template[' . $variable . '] = $value;
}

public function render() {
echo (str_replace(array_keys($this->template), array_values($this->template), $this->template['TEMPLATE']));
}
}
?>

Save this as template.class.php

Now, the index.php file (make sure all of these files are in the same folder in order for htem to work correctly)

<?php
include(’template.class.php’);
$t = new template;
// render the template
$t->render();
?>

So save that as index.php and put it in your web root directory and open it up! You should see an ugly, but working page! Let me know if you have any problems. Now, if you want to add more template variables, go right ahead! If you want to change values on conditional statements, just use the set method like this:

<?php
include(’template.class.php’);
$t = new template;
$t->set(’{TITLE}’, ‘New page title’);
$t->render();
?>

Profiling your PHP scripts (performance benchmark)

This is going to be a short post. I’m going to show you my profiling class and explain it block by block, then I’m going to stop typing and click the “Publish” button on the bottom right hand corner, capisci? Good.

A little summary – “What is profiling & performance benchmarking anyways?”
This provides a way for you to determine how “long” it takes for PHP to parse a script from start to finish and then returns the time (in microseconds) so that you can judge how “well” you’re writing your scripts.

The profiler() class

<?php
// profiler class
class profiler {
public $start_time;

function start() {
$t = microtime();
$time = explode (” “, $t);
$this->start_time = doubleval($time[0])+$time[1];
}

function finish() {
$t = microtime();
$time = explode (” “, $t);
$end_time = doubleval($time[0])+$time[1];
echo substr(sprintf (”%01.4f”, $end_time-$this->start_time), 0, 6);
}
}

// instantiate the class
$profile = new profiler;
$profile->start();
// code goes here to benchmark
$profile->finish();
?>

That’s the profiler() class. Now let’s break it down and see what it’s actually doing.

The start() function

function start() {

Store the current timestamp (in microseconds) into a variable for further reference (start the timer)

$t = microtime();

Take the microtime & the miliseconds (to the right) into an array (explode it)
$time = explode (” “, $t);

Fill the $start_time with the $t (microseconds) actual value (numbers only)
$this->start_time = doubleval($time[0])+$time[1];
}

The finish() function

function finish() {
Get the microtime again
$t = microtime();

You recognize this already
$time = explode (” “, $t);

You see it again
$end_time = doubleval($time[0])+$time[1];

Return the actual time subtracting this, from the actual $start_time (what we got from start())
sprintf returns a formatted string USING a format, in this case it’s %01.4f which says it’s a float (f)
and echo it.
echo substr(sprintf (”%01.4f”, $end_time-$this->start_time), 0, 5);
}

Now don’t get all smart on me and say “Yeah but how long does it take to run the profile class, because if you don’t know that then you..” shhh. It takes (I ran this) 0.0001 to 0.0002 seconds to run the profiler class.

The code for what I just said was simply this

$profile_profile = new profiler;
$profile_profile->start();
$profile = new profiler;
$profile->start();
$profile->finish();
$profile_profile->finish();

Which just tells you how long it takes to run it (you’re profiling your profiler)

So you can use this in all of your code to see how long it takes in microseconds (or full seconds) to run.
A couple of examples of benchmarked times (on an AMD K6-2 660MHz with 256MB PC100 RAM & 5400 RPM HD)

  • It took me 0.00010 seconds to run this while loop to echo a value and increment by 1
    $i = 0;
    while ($i <= 200) {
    echo $i . ‘<br />’;
    $i++;
    }

And that’s about it so if you’re any good at math you know that to run that loop 400 times it would take 0.00010.

This should help you judge your scripts quality & performance.

Hope this helps someone.

I eat styrofoam cups because I can’t,

bryan

Digg This

Data validation in PHP

Update: I have a new post that explains data sanitization.

One of the most important things to do in any PHP script or program, interface whatever it may be is to check the data and verify it’s what YOU want and not allow any spoofs. One of the biggest most common pitfalls newer programmers make (and for some reason, PHP programmers) is the lack of data validation. There is a known rule of program and it, simply put is:

NEVER TRUST USER SUBMITTED DATA – BAR NONE.

I get responses like “You’re too uptight about security” or “Yeah well then how’s the site supposed to work if you never take user submitted data?” Both can be true, but the latter is simple. Just check the data, what’s so friggin’ hard about that? The most commonly checked type of data seems to be an Email address with all of its quirks and workarounds it’s hard to verify whether or not an email address is real. Mind you data validation isn’t always just about malicious MySQL injection attemps or XSS (Cross site scripting) it can even be as simple as verifying a blog for bad links/language.

Usually I use pre-build functions (or class methods) to verify data integrity returning true/false for qiuck usability.

You don’t have to know Regex to be good at data validation but, you can’t really go very far without it. There are lot sof pre-built functions in PHP to verify what kind of content data is. Okay, enough talking, lets get to some code.

Here’s a few built-in PHP functions that can save you some time

  • ctype_digit() – checks for numeric characters like 123 etc
  • ctype_alpha() – checks for letters of the alphabet
  • ctype_xdigit() – checks for characters representing a hexadecimal digit
  • ctype_alnum()  – checks for alpha numeric characters

Some other built-in functions

  • is_array() – checks if a variable is an array
  • is_int() – checks if a variable is an integer
  • gettype() - returns the type of a variable
    Fore more of these functions go to php.net/is_int
    Also look at this page

For more of these functions, or any functions in general you can visit one of the most resourceful sites you’ll end up visiting php.net. I should also mention that if you haven’t read the PHP manual please do, they made it for a reason. It has almost everything you’ll ever need and if you’re running windows there is an awesome windows .CHM manual you can download that is searchable. It’s a great reference. Anyway, no more tangent.

These functions are built directly in to PHP so you don’t have to recode a lot of stuff, now, I will say, they don’t exactly do everything you want them to do, granted; but they’re a start.

Note – anytime you want to lookup a function just go to php.net/function to look it up. PHP automatically will return the corresponding page if there is one for that function/topic.

Anyways, back to data validation.

Like I said earlier, some things just aren’t built-in to PHP quite yet, like email validation, or content validation or whitespace checking. Regex (as it is commonly referred to) is a method in which you can check for literally any type of value.

I will write a followup article on Data validation with Regular Expressions in PHP after this one, I just thought people should know aside from writing their own data validation methods, PHP has a couple handy built-in functions.