Tag Archives: php

Crushing Code and Shaving Chars

Who has heard of Code Golf? I hadn’t up until about 3 years ago when I first stumbled across some on Stack Overflow. I faintly recall the horror as I gazed upon some of the most cryptic code ever – somewhat akin to the feeling I had the first time I was shown a regular expression.

According to Wikipedia, “Code golf is a type of recreational computer programming competition in which participants strive to achieve the shortest possible code that implements a certain algorithm.”

Now I would never claim to be able to hold my own against some of the veteran golfers, however I do find myself growing more and more interested in how I can shave off a few bytes here and there. Such was the case today when I set out to answer a question on Stack Overflow.

The OP was asking how he might take a single-dimension array of words, sort them alphabetically, and then print them out. Each new group of words, categorized by their first letter, should be preceded by that letter. So you would first see “A”, followed by all “a” words, then “B”, followed by all “b” words, and so on. I’ve personally wanted to do this in the past myself.

After a few minutes I had posted the following:

$firstChar = ''; 
sort( $aTest );

foreach ( $aTest as $word ) {
  $firstChar = substr( $word, 0, 1 );
  if ( $firstChar != $currChar ) {
    $currChar = $firstChar;
    echo $currChar;
  }
  echo $word; 
}

This is ugly, but fairly straight-forward. You cycle through the array, printing out the first letter of the current word whenever it differs from the last iteration. Simple enough. But then one of the members pointed out via comment that instead of writing

substr( $word, 0, 1 );

I could just access the first letter as though the word itself were an array:

sort( $aTest );

foreach ( $aTest as $word ) {
  if ( $word[0] != $currChar ) {
    $currChar = $word[0];
    echo $currChar;
  }
  echo $word; 
}

Now it had been a while since I did that. So I was pleased to be reminded of this. Then that little spark of brevity begin to grow, and I wanted to see where else I could shave off some chars. My eyes were then drawn to the assignment and echo portion:

$currChar = $word[0];
echo $currChar;

That would be shortened so that the assignment and echo take place all at once:

sort( $aTest );

foreach ( $aTest as $word ) {
  if ( $word[0] != $currChar ) {
    echo ( $currChar = $word[0] );
  }
  echo $word; 
}

So now it’s down to a single if statement, and a trailing echo. I wondered if I could just load this up into a ternary, so I set my hand to do that:

sort( $aTest );

foreach ( $aTest as $word ) {
  echo ( $word[0] != $currChar ) 
    ? ( $currChar = $word[0] ) . $word 
    : $word; 
}

At this point, I was getting a little OCD about my second and third expression. They seemed unbalanced. The second one was setting the new current category letter, as well as echoing out the word. The third one was just echoing out the word. This is when my mind returned to something Brendan Eich called an “abusage” – using && in somewhat of an if-statement fashion.

$cond && ($foo = 'bar');

The second part is only evaluated when the first part is determined to be true. If the first part is false, the operation short-circuits and the second part is never touched. I realized I could use this to test the equality of the current category letter and the first char of the current word. If they were not equal, I could use the right hand side of the operator to record the new letter:

sort( $aTest );

foreach ( $aTest as $word ) {
  echo ( $word[0] != $currChar ) && ( $currChar = $word[0] ) 
    ? $currChar . $word 
    : $word; 
}

Awesome. Looking very slim. Now that I have only one statement within my foreach loop, I can strip away the curly braces. I can also reduce even more space by moving away from long variables names. Instead of “word”, I can simply use “w”. Instead of “currChar”, I can use “l” (for “letter”). I can also collapse my ternary operator onto one line:

sort( $aTest );

foreach ( $aTest as $w ) echo ( $w[0] != $l ) && ( $l = $w[0] ) ? $l . $w : $w ;

Nearly there. Last we can strip out all of the white space possible. Unfortunately with the syntax of the foreach, we cannot remove the spaces around the keyword “as” in the condition.

sort($aTest);foreach($aTest as $w)echo($w[0]!=$l)&&($l=$w[0])?$l.$w:$w;

In the end we’ve reduced about 195 characters and 11 lines down to 1 line and roughly 70 characters! Granted, that’s nothing compared to what others have acheived, however it’s awesome to see this solution iteratively collapse before my very eyes.

With some clever substring alternatives, ternary operators, and hacking the way logical operators work, we’re able to reduce a dandy solution into a horrific and cryptic trace of insanity. I don’t suggest you actually produce code like this when you ship (outside of the obvious minification), as it’s far better to write readable code than it is to write short code.

In the end, I was able to switch away from the original array declaration and use the deprecated split function to save even more bytes:

$a=split(",","apple,pear,banana,kiwi,pineapple,strawberry");
sort($a);foreach($a as $w)echo($w[0]!=$l)&&($l=$w[0])?$l.$w:$w;

So how about you? Do you engage in this type of behavior? Have any tricks of the trade to share? Place them in the comments below! Or perhaps you can shorten my code even further – I’d love to see what you come up with!

n Parts for Sum in PHP

I was bouncing around on Stack Overflow, answering questions here, voting on questions and answers there, when I came across a question on how to construct an array of arbitrary size, whose members add up to an explicit sum. This sounded fun, especially since math has always been an area I’d like to see some personal growth in.

So I set out to answer the question, jotting down some pseudo-code in notepad, and working through some functional portions on writecodeonline.com/php and coderpad.org. After about 10 minutes or so I felt as though I had a good solution for the OP (original poster), so I clicked back over to my Stack Overflow tab. To my terror, the question had been closed as a duplicate.

Now what? Did I just waste all that time and brain-power constructing a solution that I cannot even share? Meh, screw it, I’ll share it on my blog!

My first step was to build up an array of values that were each a fraction of the sum, rounded down to keep away from decimals. This would, of course, leave me with a slightly larger number in the end if the sum isn’t equally divisible by the expected number of parts. That’s okay, I’ll just push that last number onto the end of the array.

$sum = 200; 
$parts = 10; 
$valus = array();

for ( $i = 0; $i < $parts; $i++ ) {
  $num = $i < ( $parts - 1 )
    ? floor( $sum / $parts )
    : $sum - array_sum( $valus );
  array_push( $valus, $num );
}

Awesome. This results in an array of values that are almost entirely the same number, with the exception of the last index, which will be slightly larger when the sum doesn’t divide equally.

Next I need to randomize the values. I figured I would cycle back through and have some of the values share the wealth, so to speak. Each number would have a random portion of itself donated to a random sibling. At the very least, any particular number could be reduced to 1, but no lower (more on that in a bit).

foreach ( $valus as $key => &$value ) {
  if ( $value == 1 ) continue;
  $rVal = rand( 1, $value - 1 );
  $rKey = rand( 1, $parts );
  while ( $rKey == ( $key + 1 ) )
    $rKey = rand( 1, $parts );
  $value -= $rVal;
  $valus[--$rKey] += $rVal;
}

That’s it! (KEEP READING! One important change yet to be made) Tell it how much, and how many, and it builds an array of randomized values for you. One run of the code against the above settings resulted in the following output:

Array
(
  [0] => 26
  [1] => 59
  [2] => 4
  [3] => 61
  [4] => 35
  [5] => 1
  [6] => 2
  [7] => 7
  [8] => 1
  [9] => 4
)

One interesting thing I noticed after toying with the input was that if your sum is less than your number of parts, the code will at times provide a negative number in order to provide adjusted values for each key. For example:

$sum = 2;
$parts = 5;

Produced the following results after one run:

Array
(
  [0] => -1
  [1] => 0
  [2] => -1
  [3] => 3
  [4] => 1
)

Count it up, -1 + 0 + -1 + 3 + 1 indeed equals 2. Of course this wasn’t at all what I wanted. But it did cause me to consider what would happen if somebody wanted more parts than their provided sum. This lead me to return to my share the wealth portion and rewrite the first condition:

if ( $value <= 1 ) continue; // change == to <=

Now, whenever our current value is less than or equal to 1, we skip it. It is possible for the value to be zero already, because we floor the results of the division in earlier code. If the sum is less than our parts, that result will be a fraction, which we promptly round down to 0. This will now prevent the code from further reducing the value from 0 into negative numbers. In cases where our sum is much larger than our parts, we don’t want to borrow so much from one key that we leave another with 0. This is why I skip if the value is already 1 as well.

So asking again for the following:

$sum = 2;
$parts = 5;

Will output the following array (or one similar to it):

Array
(
  [0] => 0
  [1] => 0
  [2] => 1
  [3] => 0
  [4] => 1
)
code-igniter-logo-black

Todays WTF Moment with CodeIgniter, MySQL and PHP

As routine as an oddly-twitching finger sabotaging any attempt to use your mouse, strange things  may take place with your environment, tools, or code. Today I was working on setting up a very small project with CodeIgniter when I came across the task of establishing database credentials so I could auto-load my resources and have a fresh connection waiting on me hand and foot.

Opening up application/config/database.php I went ahead and placed my hostname, username, password, and database name. Almost done, right? Next I went to application/config/autoload.php and updated the $autoload[‘libraries’] array to include “database”. Done, right?

To my surprise I had a whole storm of agony just waiting on me to try and pull some results from my model. When I did just that…

This took me back just a moment – I had put in the right data, right? I’m working on “localhost”, and my db user is “root” with a blank password. How exactly do you screw that up? After double-checking, my credentials showed to be valid. So I went to make sure I was auto-loading the database properly; perhaps I said “datbase” instead of “database”? Who knows, it’s happened before. Nope, I had this value correct as well.

It’s around this moment Google must necessarily be opened and error messages must necessarily be pasted into the search bar. Anytime I have problems like these, which turn me to Google, I’m reminded at just how unreliable forums are. I inevitably ended up looking at about 12 different forums, where people can post whatever the flip they think might be the problem and you have very little reason to doubt them in your ignorance.

“Did you provide your port number?” “Did you update your hosts file to associate ‘localhost’ with 127.0.0.1?” “Did you max out your connections?” All of these where the types of questions being asked, and yet none of them did me any good. My host file is fine – I run plenty of websites. I’m not maxing out my connections either – I’m the only sap accessing the laptop! It wasn’t until I came across a PHP bug filed in 2008 regarding PHP 5.3’s inability to use MySQL functions when using “localhost”.

Now, this bug submission was eventually marked as “bogus,” but it wasn’t entirely useless because it got me to explore another route in my troubleshooting. Out of curiosity I looked down to my instance of WAMPServer to see what version of PHP I was running; 5.3.1.

Out of curiosity, I switched to 5.3.5. My server went offline, restarted, and was back up and running in just a matter of seconds. Time to try my CodeIgniter app again…Bingo!

The connection issues were resolved by switching from 5.3.1 to 5.3.5. Just for some environmental facts and info, I’m running WAMPServer 2.0, Apache 2.2.11, MySQL 5.1.33 and PHP 5.3.1 (Well, 5.3.5 now). The CodeIgniter version is 2.0.2.

At this point, I still have no idea what causes this problem but I am sure glad it’s done with so I can get back to work. If you’re having a similar problem, on a similar setup, perhaps this will help you as well.

If anybody knows what actually causes this problem, I’d love to know in the comments below.

ternary

A Shorter Ternary Operator in PHP 5.3

The ternary operator is simply awesome. It allows for some really beautiful if-else style variable assignments:

$can_drink = ( $age <= 21 ) 
  ? true 
  : false ;

This operator let’s you evaluate a condition, and return one of two results based on that condition. In the example above we’re testing the legal drinking age. If the age is greater than or equal to 21, the value of $can_drink will become true (the first value after the question mark). Otherwise, the value of $can_drink will become false (the value after the colon) (this particular example doesn’t require a ternary operator as the condition evaluated will itself result in either true or false). You can test multiple conditions within the main ternary condition, but the rules still stay the same – if the main condition evaluates to true, the first result is returned, otherwise, the second result will be returned.

The operator is nice, don’t get me wrong, but it’s not always fun to play with. Suppose you’re searching for a value within an array and you would like to return it if found:

$job_title = array_search( "Jonathan Sampson", $emp )
  ? array_search( "Jonathan Sampson", $emp )
  : "n/a" ;

You’ll note that my white-spacing is a little different, but this won’t effect the results of the operator. What I’m doing here is checking to see if “Jonathan Sampson” is a value within the employees array. If “Jonathan Sampson” is in the array, I’d like to return the key for that entry, so I replicate the condition (which returns the key) in the first slot after the question mark so it will be returned if the condition is true. Otherwise, if “Jonathan Sampson” isn’t found in the array (and the condition returns false) I return the string “n/a”.

Either the $job_title variable will have a value like “Software Developer” (given the key for “Jonathan Sampson” is “Software Developer”) or it will be “n/a”. The problem here is that we’re performing the array search twice, which is really ugly. There’s another way we could do this:

$job_key = array_search( "Jonathan Sampson", $emp );
$job_title = $job_key ? $job_key : "n/a" ;

Now we’re only performing the array search once. The array_search function returns either the first key found, or FALSE. As such, $job_title will contain either the key, or the string. But this is still a bit ugly. We’ve got two lines, and repeated calls to the $job_key array.

In PHP5.3 we’re given the option of a much shorter ternary, eliminating the middle column completely. This is helpful when using functions like array_search() which themselves return the result we actually want. They serve both as the condition (since they will return FALSE when the value isn’t found) and the result (since they return the key if the value is found). Now we can do something like this:

$job_title = array_search( "Jonathan Sampson", $emp )  ?: "n/a" ;

Now, if array_search() finds the key, it’s automatically returned into the $job_title variable, else, “n/a” will be returned. Elegant.

thumbnail

Quickly Adding Thumbnails to WordPress Archives

Post thumbnails make archives look much more attractive in my personal opinion, yet they are not natively displayed in the otherwise-beautiful theme shipped with the latest version of WordPress, Twenty Ten.

As is the case with most WordPress stuff, this shouldn’t stop us from adding it in ourselves – this is exactly what we’ll do. I should note that I’m a student of WordPress, and wouldn’t consider myself an expert by any measure, but I do know enough to get around and do so without making a mess (correct me if I proceed to make a mess).

Our goal today is to add a small thumbnail next to our posts on the archive pages of the Twenty Ten theme. Of course what you’ll learn here can easily be applied to most themes. We’ll be making use of primarily two functions, modifying a third, and adding a few lines of CSS to accomplish this today.

We’ll be modifying only two files today, loop.php and style.css. Within loop.php we will add the code to show the image, and within style.css we’ll add the rules to style the post and the image itself. Let’s begin!

loop.php, where the magic happens

Within loop.php we will find and abundance of if-else-statements (at times I will break this down into numerous smaller files to improve readability). Within Twenty Ten version 1.1 we will find a comment on line 122 saying “How to display all other posts.” This is where we will do our initial changes. Look at the two lines following this comment:

<?php else : ?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

First we’ll want to determine whether or not the post has a thumbnail associated with it. If there is a thumbnail, we’re going to add a class to the post div which will make some changes to the formatting to accommodate the thumbnail itself. If there is no thumbnail, we’ll leave the post div as-is.

<?php else : ?>
<?php $tnail = has_post_thumbnail() ? "hasthumb" : "nothumb" ; ?>
<div id="post-<?php the_ID(); ?>" <?php post_class($tnail); ?>>
<?php the_post_thumbnail( 'thumbnail' ); ?>

There are a couple of things going on here, so let’s break them down individually. First, we’re building a CSS classname off of the presence (or lack) of a thumbnail. For anybody who might be confused with the syntax, we’re using the ternary operator to do this:

$tnail = has_post_thumbnail() ? "hasthumb" : "nothumb" ;

has_post_thumbnail() returns either true, or false. If it’s true, the value of $tnail will be “hasthumb,” and if it’s false the value of $tnail will be “nothumb”. We then carry that value down into our call to post_class() where it will be added to the beginning of a list of many other classnames generated by WordPress for this post.

Within the div that contains the post itself, we add a call to the_post_thumbnail() function and specify that we want the thumbnail size. This function assumes you want the thumbnail size even if you leave out a value. The thumbnail size is configurable in your settings (settings > media) – for my site I’m using the default 150px by 150px. If the post has a thumbnail, the HTML to show the image will be generated and the image will be placed within the resulting HTML.

Styling the Image

Now we need to style the image. Without adding our CSS, the image will sit on top of the post, which isn’t what we want. Instead, we would like to place the image to the left of the post, with a nice gutter between image and content. For this next step, let’s open up style.css and navigate down to the bottom of the file to add the following:

/* =Post Thumbnails
-------------------------------------------------------------- */
body.home div.post.hasthumb,
body.archive div.post.hasthumb,
body.search div.post.hasthumb {
  padding-left: 170px;
  position: relative;
}
body.home div.post.hasthumb img.attachment-thumbnail,
body.archive div.post.hasthumb img.attachment-thumbnail,
body.search div.post.hasthumb img.attachment-thumbnail {
  position: absolute;
  top: 0; left: -5px;
  border: 5px solid #fefefe;
  box-shadow: 0px 1px 3px #CCC;
  -moz-box-shadow: 0px 1px 3px #CCC;
  -webkit-box-shadow: 0px 1px 3px #CCC;
}

A careful look at these rules will show that they will only apply on the home, archive and search pages. Additionally, the selectors only apply to the posts that have images representing them since they are the only entries that have the hasthumb classname.

That’s it, you should be able to save all changes and begin adding a featured image for each of your posts and find it right along side your excerpt.

Kohana checks environment to ensure it can run properly with present configuration.

Install and Setup of Kohana 3, The

Kohana is the wildly popular PHP Framework used by many developers all over. I’ve used it numerous times in the past on some rather different projects and found it to be pretty versatile and reliable over-all. One of my largest projects received well over 100,000 unique visitors a day, and still managed to hold up exceptionally well under the stress.

This post will serve as nothing more than a guide to installing Kohana version 3.

Environment

In order to run Kohana you will need a server, but don’t worry too much as your average computer will do. I develop on windows (for now) so I typically install WAMPServer, which places Apache, MySQL, and PHP all on my box inside a live server environment so that I can develop on the domain http://localhost/ – awfully handy.

Depending on what operating system you’re using, you may not find WAMPServer to be all that helpful. There are always alternatives: MAMP and XAMPP are two popular ones.

The Classic Download, Copy and Paste Procedure

Like so many other frameworks, we’ll begin with downloading Kohana and extracting the files into our project directory. You can download Kohana 3 from the Kohana download page. At the time of this writing, the latest (stable) version is 3.0.9, which also happens to be the version I’ll use in the following examples.

Extract the contents of your download to your project directory. You may keep the standard /kohana folder that comes in the archive, or you can just pull the files themselves our and into your directory. Once you have this done though, load up your favorite browser and navigate to your project directory to begin the requirements testing.

Kohana checks environment to ensure it can run properly with present configuration.

This stage will test your environment for Kohana compatibility. Kohana will need to ensure that your server configuration allows for writable log directories, appropriate versions of PHP and so much more. This screen will give you a nice rundown of how you stack up. All green is all good, but if Kohana finds something it doesn’t like (like unwritable directories) be sure to handle it here and refresh to re-check your system.

If you require assistance setting up your server environment to allow for writable directories, or enabling extensions in the PHP library, please consider visiting serverfault, and online peer-reviewed question and answer website for server maintenance.

As indicated in the automated test, once your system is clear you may delete (or rename) the install.php file to continue the process of setting up Kohana 3.

Setting the Base URL

Some of you may have refreshed your browser only to find a aesthetically pleasing (yet heartbreaking) error on your screen. You got antsy, slow down and keep reading (we’re almost done, I promise). The next thing we need to do is update our base bath to the project on our server.

Kohana uses Apache’s mod_rewrite to beautify your url structure. Much of this logic exists within the example.htaccess file found immediately within your Kohana directory. Open this up to make our next edit.

If necessary, let’s update the following line:

# Installation directory
RewriteBase /

If your project is immediately inside your /www or /htdocs folder (your web-server directory) then you can leave this as /, however if you’ve created a project folder to house your Kohana application you need to point this to where that project is. Hint: it’s the same path that we accessed to get to the previous phase, the system check.

My project happens to be in a custom path, so I’ll update my example.htaccess file.

# Installation directory
RewriteBase /projects/demoKohana/website

When you are ready to save this file, save it as .htaccess in the same directory. It’s an odd filename, but trust me on this. This file is handled by Apache and often times contains very important rules for how requests ought to be handled. You can read more about .htaccess on the Apache website.

Now that we’ve modified the .htaccess file, our directory ought to look like this:

Basic Kohana 3 root directory appearance.

  • application (folder)
  • modules (folder)
  • system (folder)
  • .htaccess
  • build.xml
  • DEVELOPERS.md
  • example.htaccess
  • index.php
  • LICENSE.md
  • install.php (deleted or renamed)
  • README.md

If this looks like your directory, you’re well on your way to finishing the setup process.

Once you’ve confirmed your directory structure is correct, we can move on to the the final touches before starting development with the Kohana 3 framework.

Updating the Bootstrap

Our next, and final, step is to update an array found within application/bootstrap.php. Within bootstrap.php, locate the following lines:

Kohana::init(array(
	'base_url' => '/',
));

Here, again, we’ll want to change the base_url value. Within a comment the Kohana developers tell us that this value represents the “path, and optionally domain, of your application.” As such, if you want to provide the domain you are more than welcome to. I will be using a path instead:

Kohana::init(array(
	'base_url' => '/projects/demoKohana/website',
));

Save, and exit.

At this point, if all went as it should, you should be able to refresh your project directory and find one of the most glorious messages developers have enjoyed since 1974.

To the Controller!

By default, Kohana will run the index action of the default Welcome controller. The default controller and action are set within the bootstrap.php file, located just inside the applications folder. Locate the following lines:

Route::set('default', '(<controller>(/<action>(/<id>)))')
	->defaults(array(
		'controller' => 'welcome',
		'action'     => 'index',
	));

If you would like to change the controller and/or action, you may do so here. Instead of changing the present values, I’m going to leave them as they are and simply take a look at the welcome controller. You can find the welcome controller source located inside application/classes/controllers under the filename welcome.php:

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Welcome extends Controller {

	public function action_index()
	{
		$this->request->response = 'hello, world!';
	}

} // End Welcome

You can see from this code that all the action_index() method does is send the ‘hello, world!’ message directly to the response. No views are being loaded, so we’ll go ahead and load a view now. We’ll start by creating a new file at application/views/welcome.php and placing within it the text “This is my view.” Next, back in our controller we will make the following change to the action_index method body:

//$this->request->response = 'hello, world!';
$this->request->response = View::factory( 'welcome' );

Here we are loading the welcome view into the response. This now allows us to make changes to our applications/views/welcome.php file rather than modifying the output within the controller itself.

Next up, Using Views in Kohana 3.