Archive for August, 2008

Mini-review: Gonzo: The Life and Work of Dr. Hunter S. Thompson

August 17, 2008

Before seeing Gonzo I wasn’t that proud to be a fan of Hunter S. Thompson.

A bit like Che Guevara, his anti-authoritarian image has a lot of appeal, but he and Che are deeply flawed as role models. Che’s problem was that he was a violent murderer… Whereas Thompson just seemed very, very drug-munched.

I suppose because (I’m guessing like a lot of younger people) my introduction to Thompson was the film Fear and Loathing in Las Vegas, I thought his drug-crazed adventures were his most remarkable point.

After seeing Gonzo I had new-found respect for Thompson.

I knew Thompson ran for Sheriff of Pinkin County, and the brilliant bit where he shaves his hair off so he can refer to the standing sheriff who had a crew-cut as “My long-haired opponent”. But seeing footage of his attempt, it wasn’t a random stunt, it was a stunt Thompson cared deeply about and really wanted to work.

And his involvement in the 1972 Presidential Campaign… Wow. New to me.

Gonzo is full of Thompson’s funny antics, but it’s a fantastic and informative documentary too. Some great music in there as well. Highly recommended.

Using a CakePHP model to loop over database records

August 12, 2008

I was quite pleased to get this working so easily CakePHP 1.2.

Problem: I needed to iterate over records in a table, but there’s potentially too much data to fetch every record at once with findAll().

This isn’t a case of premature optimisation–using a CakePHP model to fetch records with complex associations can cause your script to be killed for using too much memory (the default allowance is 32MB, I think).

I only need a single record at a time, so rather than increase the memory limit (which won’t scale that well) I’d like to change how data is fetched.

Solution: Use a while loop with the “Model->find( ‘first’ )” method and a page variable, like so:

$page = 1;
while ( $record = $this->Model->find( 'first', array( 'page' => $page++ ) ) ) {
  print_r( $record );
}

And that’s all there is to it. We can now work with each record, having only one record in memory at a time. Eventually find() will return false when it has passed the last record, cleaning up the $record variable.

This is a similar approach to querying the database with SQL directly, then using a method such as mysql_fetch_array() to parse the results.

The only difference is the addition of the $page variable, which acts as a pointer and is incremented so it returns the next record each time. Otherwise we would get the first record returned over and over, creating an infinite loop. mysql_fetch_array() uses a pointer like this too (as far as I know), but it’s hidden inside the method.

You could easily do the same in CakePHP to create a findNext() function on your CakePHP model that then calls find(), along with any other conditions passed in. It would be used like so:

while ( $record = $this->Model->findNext( $conditions ) ) {
  print_r( $record );
}

But I haven’t tested that yet. :)