Archive

Monthly Archives: October 2014

Since as long as I have used Php, I have carried around some code that I use for quick shell scripts and the occasional data mangling. It’s not particularly great code, in fact I would say its pretty bad but it was never really used for anything other than the occasional quick hack (I use Propel, RedBean, or PDO for other Php projects). I have been using this code copy+paste style for over 5 years and it has remain mostly unchanged:

if (!$link = @mysql_connect('localhost', 'user', 'pass')) {
  die('Could not connect: ' . mysql_error());
}

@mysql_select_db('database', $link) or die('Could not select database.');

function query($query) {
  $rows = array();
  $result = @mysql_query($query);
  if ($result && mysql_num_rows($result)) {
    while ($row = mysql_fetch_assoc($result)) {
      $rows[] = $row;
    }
  }
  return $rows;
}

foreach(query("select * from foo") as $row => $record) {

  // do stuff with $record

}

Yeah… I can see you cringing right now. But for banging out the occasional script it usually worked (as long as the result fit into memory). You may also notice the use of error suppression with @. That’s because I’ve been using this code for so long that the mysql_* functions have been deprecated (as they should be) and they will throw warnings on newer versions of Php when you use them… ouch.

As we all know too well, sometimes our little hacks and kludges work so well that they end up in production, get scheduled as cronjobs, get rolled into internal web pages and the like. Recently this code put me in a bit of a bind. It had found it’s way into a very complex data-mangling cronjob that was needed to generate a table which was used for reporting. The table stopped being generated when the result set had grown too large to fit into memory and the script was crashing.

I realized I had to fix this script but the query function and foreach loops were peppered throughout the code, sometimes nested, sometimes used in recursive functions. I didn’t have time to re-write a large portion of the code so I came up with this backwards compatible version which limited the amount of re-writing I needed to do. I could use it in such a way that when I knew the result set would be small I could use the old in-memory query (no changes were needed), but when I knew it would be large result set, I could use a callback that was called for each row.

function query($query, $callback = FALSE) {
  $rows = array();
  $result = @mysql_query($query);
  if ($result && mysql_num_rows($result)) {
    while ($row = mysql_fetch_assoc($result)) {
      if ($callback === FALSE) {
        $rows[] = $row;
      } else {
        call_user_func($callback, $row);
      }
    }
  }
  return $rows;
}

// new use, with callback
query("select * from foo", function ($record) {

  // do stuff with each $record

});

I realize this code is STILL not ideal, but it is a backwards compatible fix and got the job done.

Advertisements

I recently downloaded the Fedora 21 XFCE4 Alpha iso and used the LiveUSB Creator to write the iso to a USB disk. When I tried to boot the USB image I hit an error I haven’t seen before:

vesamenu.c32: not a COM32 image

The quick fix is pretty simple, but not at all obvious: just provide the kernel and arguments manually:

vmlinuz0 initrd=initrd0.img root=live:CDLABEL=LIVE rootfstype=vfat ro rd.live.image quiet  rhgb rd.luks=0 rd.md=0 rd.dm=0 nomodeset

Just type the above in in the “boot:” prompt (all on one line) and it should boot the image to a desktop. Not sure why this happens but it is Alpha.