Archive for 2nd March 2007

Variable Assignment, Exception Handling, and Destructors in PHP

I had the craziest set of “bugs” the other day — well, that was until I realized they weren’t bugs. It turns out, at least in PHP, if you try to assign an object to a variable, but during the assignment, an exception is thrown, the variable keeps its original value. Oh, and the destructor fires immediately before anything else. I am not sure if this is true in other languages, but if it is, please let me know. :)

Not sure what the hell I’m talking about, or want to learn more about exception handling? If I get any requests in my comments, I’ll follow up on a walk-through about the topic. Same goes for destructors. Speak up or forever hold your peace.

Exceptions and Variable Assignment

So back to the problem at hand:

$connection = ‘hello’;
try {
    $connection = new Database($parameters);
    $connection->doStuff();
} catch (Exception $exception) {
    echo $exception->getMessage();
} // continue as if nothing happened
var_dump($connection);

So what’s the result when I dump $connection?

  1. If no exception is thrown anywhere, the value is the Database object.
  2. If an exception is thrown during doStuff(), the value is the Database object (as expected).
  3. If an exception is thrown in the constructor of Database, the value of $connection is “hello”.

This makes sense. During the assignment, the code is short circuited, and the object is never assigned.

In other words:

  1. new Database() is processed.
  2. During processing (the constructor), throws an error.
  3. The code exits out of the constructor and looks for a catch statement.
  4. The first catch statement found is below the assignment line.
  5. Thus not only does doStuff() never get executed, but the Database object is never assigned.
  6. The $connection variable is never modified.

The lesson I take away from this is to not throw exceptions in constructors. This is largely whey I only do property assignments during constructors and any potentially error causing stuff is tossed in an initialize() function I call later during the first operation that might require more than simple assignments. But that’s just me.

Destructors on Exceptions During Constructors

For those of you still reading, and understanding what I’m talking about, I have another point to add: destructors fire before the exception is thrown out! As in, as soon as the program sees the throw keyword and we leave the constructor, the destructor fires! I imagine this is because since the variable was never assigned, it’s just a dangling variable in memory, and thus gets cleaned up immediately.

This is probably nothing unexpected, but surely something to keep in mind if you use PHP destructors (as I was). This is relevant because I was trying to log some stuff during the destructor, even on an error. Exceptions cause text to get dumped, so I figured I would just collect the text in the destructor (from the output buffer) and then toss it in a file. Unfortunately, that didn’t work because the destructor fired way before the exception had a chance to display anything. My (broken) code looked something like this:

ob_start();
$framework = NULL;
try {
    $framework = new Framework();
    $framework->initialize();
} catch (Exception $exception) {
    echo $exception->getMessage();
}
unset($framework); // make the destructor go off

During the destructor, anything written to the output buffer (error or no error) was tossed in a file. This worked unless an exception was tossed in the Framework constructor.

Output Buffers and Destructors (tricky!)

Lastly, as a golden bonus to those still reading, the reason I manually unset the variable is because through trial and error, I discovered that at the end of a program’s execution, the output buffer is flushed (and cleaned) before variables are erased. This meant that by the time my destructor fired (when $framework got erased), the output buffer was already empty and crap was already on the client’s screen. Thus, I had to unset it manually. :)

I hope this helped somebody.

Mac Sales Doubled Since Year Ago

Apple Insider is reporting that Macs are now selling twice as much as one year ago. What’s more interesting is that the average price has also gone up, giving Apple a 108% revenue growth. Now that’s impressive.

Apple has doubled their business from two years ago:

Apple, Inc: 2005 - 2007

And this paints an interesting scenario to me. Clearly, the iPod halo effect on Macs is delayed since people buy computers much less frequently than music players. It would take months of using the iPod and iTunes before someone might finally think, “Hey, maybe Macs are this easy too…”

Either way, it has to be some rough proportion of all iPod consumers. And this made me think. Just how fast are iPod sales growing? Well, the news of this post is that Mac sales are up 100%, so iPod sales must have been up 100% recently right?

Nope. The 2006-2007 sales “only” grew by 50%. However, you’ll notice 2005-2006 was a 200% increase. Well, let’s be honest here, Mac sales have never grown 200% in any year. But what if that 200% was responsible for the surge that happened this year? Wouldn’t that mean next year, we’ll see weaker Mac sales?

Well, let’s be honest here. It may be only 50% more iPod buyers, but it’s 7 million extra people exposed to the Apple experience. Sales can’t keep doubling forever. After all, iPods grew something like 400% between 2004-2005.

Either way, if the halo effect stays as strong as it has so far, we should see an even greater uptake of Macs this year, albeit not at a growth rate that matched 2006, but a double-digit growth nonetheless.