The drop is always movingYou know that saying about standing on the shoulders of giants? Drupal is standing on a huge pile of midgetsAll content management systems suck, Drupal just happens to suck less.Popular open source software is more secure than unpopular open source software, because insecure software becomes unpopular fast. [That doesn't happen for proprietary software.]Drupal makes sandwiches happen.There is a module for that

Write in C?

Submitted by nk on Sun, 2007-08-12 20:50

Sung to the tunes of Let it be.

When I find my code in tons of trouble,
Friends and colleages come to me,
Speaking words of wisdom:
"Write in C."

As the deadline fast approaches,
And bugs are all that I can see,
Somewhere, someone whispers:
"Write in C."
...

The oldest reference to this popular song I could find is from 1992, this Usenet post says that it was posted to rec.music.beatles "ages" ago, so I could not find the author alas.

However, it's not 1992 any more and quite sometimes PHP code allows for a quicker turnaround so we use that. Remember the wisdom of Rasmus Lerdorf: "Fail early and fail cheap" -- you just can't do that with C. However, PHP at its roots is not much more than C, with a few utility functions and a hell lot of libraries glued together (which explains the much criticized naming inconsistencies). So Cisms work in PHP but they are totally out of the environment and without the pointer magic, usually it's just clumsy.

To get to the point, the while ($object = db_fetch_object($result)) construct is used by almost everyone and I would bet that almost noone thinks about what does it mean and how weird it is. while runs as long as the expression given to it is TRUE. But what's the value of object = db_fetch_object($result)? It's not a comparison or something usual that would give you a boolean. Someone who does not know C might argue that loading a value always succeeds (unless you run out of memory which is a fatal error anyways) this construct should actually always be TRUE. Or simply it shall have a NULL value simply because it makes no sense to have any value.

But in C, the value of that construct is simply the value that is being copied from right to left. (Actually, that let's you do $a = $b = array();) In C this results in wonderous constructs like the classic strcpy while (*dst++ = *src++), in PHP on the other hand this is just ugly -- but because it works and it's a very succint way of doing things, people just use it. Why does it work? Because a nonempty array / object (in PHP5, any object) casted to boolean is TRUE.

All is well until some point someone tries to use $object after the loop. In C, you would never, ever use that src past that loop because it points past the terminating zero thus you are risking a total crash by reusing it. In PHP, no pointers, no problem, you can reuse it and I have seen people presuming that it's the last retrieved object, but it's not. Again, while stops when the expression becomes FALSE and the expression in this case is the value that gets copied from right to left, thus we know that $object is also FALSE.

If you write in C with a PHP syntax you better know what the heck happens in there or otherwise you will get burned.

Commenting on this Story is closed.

Submitted by pwolanin@drupal.org on Sun, 2007-08-12 22:49.

This post is amusing to me, since I learned to program in PASCAL and then C (with mandatory exercises in Sun assembly language), so I've never thought twice about the while loop construct you mention.

Is there a PHP-preferred way to do it? I guess you have to fetch once to seed the loop?

Immortalized as the Frankenwhile (i.e. chx says don't do this):

+  // Get the menu hierarchy for the current page.
+  $tree = menu_tree_page_data($menu_name);
+
+  // Go down the active trail until the right level is reached.
+  while ($level-- > 0 && $tree) {
+    // If the item is in the active trail, we continue in the subtree.
+    while (($item = array_shift($tree)) && !$item['link']['in_active_trail']);
+    $tree = (!empty($item['below'])) ? $item['below'] : array();
+  }

Submitted by nk on Mon, 2007-08-13 04:33.

First, your comment is another problem -- you put just a little too much in that while, that's while I called it a "Frankenstein while" :)

On the other hand, this construct works and as long as you are aware of how and why it works (ie. the value and the casting) it's fairly usable. Any other solution would be bloated.

Submitted by victorkane@drup... on Mon, 2007-08-13 10:01.

Don't know the song...
But, just the other day I needed to initialize several variables at once, and just Cautomatically wrote:

$block01 = $block02 = $block03 = '';

I smiled when I saw it worked just like in C.