Awful code I’ve written today

$row = $table->tr();

if(!($amIAltOrNot = !$amIAltOrNot))
{
    $row->class = "alt";
}


//  Edit: Much better now
$row = $table->tr();

$row->class = ($amIAltOrNot = !$amIAltOrNot) ? "" : "alt";

Posted on

Now with added Slicehost

This website is now hosted on Slicehost (along with section99.net). It’s a little early to know how it will turn out, but so far I’m loving having not only a shell, but root access.

Signing up was completely painless and the the VPS was provisioned within minutes with several different operating system options (though I’m aware that this can sometimes take weeks depending on current capacity). While I run the bleeding edge version of Ubuntu at work, I opted for the slightly safer option, Ubuntu 6.06 LTS.

Setting up Lighty / PHP and Mysql took mere minutes thanks to apt-get and Debian’s sane default configuration. WordPress took a tiny bit of fiddling in Mysql so I could test it on another domain name, but aside from that, everything has been very painless.

I’m hoping that this gives me the chance to play with some webpy and even (maybe) some rails applications.

The only problem I’ve had (except for screwing up the DNS) is editing my crontab when loged in as a normal user. I’m unable to edit it due to a weird permission error. While it’s not a huge problem (root can edit anybodies crontab easily) but it’s odd that the only real information I can find is related to an old Debian bug.

Posted on

More useless PHP – Inplace Reverse

Code

<?php

/*

    PHP implementation of a common programming problem:

        Reversing a singly linked list

*/


    error_reporting(E_ALL | E_STRICT);


    //  This is our basic node
    class WordNode
    {
        public $word;
        public $nextNode;

        public function __construct($word = null)
        {
            $this->word = $word;
        }

        //  Print all content of this node, and linked nodes
        public function __toString($separator = '')
        {
            $buffer  = '';
            $current = $this;

            do
            {
                //  Append the separator as long as there is a next node
                $buffer .= $current->word . (($current->nextNode !== null) ? $separator : '');
            }
            while(($current = $current->nextNode) !== null);

            return $buffer;
        }
    }


    //  Takes an array and turns it into a linked list
    //  (Remember this is purely an academic exercise :-)
    function buildWordNodeList($sourceArray)
    {
        //  First step create the linked list
        $firstNode = new WordNode($sourceArray[0]);

        $lastNode = $firstNode;

        foreach(array_slice($sourceArray, 1) as $word)
        {
            $thisNode = new WordNode($word);

            $lastNode->nextNode = $thisNode;

            $lastNode = $thisNode;
        }

        return $firstNode;
    }


    //  Inplace reverse
    function reverseWordNodeListInplace(WordNode &$head)
    {
        //  Init the loop by separating the top node, and
        //  keeping track of what is left ($tail)
        $tail = $head->nextNode;

        //  This is set to null as it will end up being the
        //  last node and shouldn't point anywhere
        $head->nextNode = null;

        while($tail !== null)
        {
            //  Take the next node, and seperate it, and again
            //  keep track of what's left
            $next = $tail;
            $tail = $next->nextNode;

            //  Now make this node the parent of the previous top node
            $next->nextNode = $head;

            //  This node is now at the top
            $head = $next;
        }
    }


    $list = buildWordNodeList(array("a","b","c","d","e","f","g","h", "i", "j", "k"));

    echo $list . "\n";

    reverseWordNodeListInplace($list);

    echo $list . "\n";

    reverseWordNodeListInplace($list);

    echo $list . "\n";

    echo $list->__toString(" ") . "\n";

?>

Output

abcdefghijk
kjihgfedcba
abcdefghijk
a b c d e f g h i j k

Posted on

No More WoW Complaning

I’m not allowed to complain about raiding any more.

Went to Zul’Aman a couple of weeks back, after a few tries took down the first boss, and then a couple of tries on the second boss, but things didn’t go so well (I kinda wiped the raid). Also did a Kara run with 7 guildies to one shot everything up to Curator (and then called it without attempting). Was pretty happy then about the guilds progress, alot of it is thanks to a > Kara geared tank who been organizing the guild raids.

This week after a fairly epic Kara run (just over six hours):

  • Attumen the Huntsman & Midnight – 1x attempt
  • Moroes – 2x attempts
  • Maiden of Virtue – 1x attempt
  • Opera Event – Romulo and Julianne – 2x attempts
  • The Curator – 1x attempt
  • Shade of Aran – 1x attempt
  • Prince Malchezaar – 3x attempts
  • Netherspite – 2x attempts, not downed… Yet

Just a little bit of an improvement over last time :-)

Posted on

More WoW

Can’t have a post about PHP at the top of the page for more that an couple of days. So on with the WoW gloating and moaning.

  • Karazhan — Nothing at all to report. Haven’t run for weeks, no one seems interested (two that were interested left yesterday. Kara group one leader, and Kara group two leader). Would be seriously looking for another guild, but I feel bad now that I have highest guild rank next to the GM
  • 3 more epics since last post
  • Eternium Runed Blade – Highest DPS crafted dagger (168 spell damage)
  • Icon of the Silver Crescent – Finally, took a long time to get all 41 badges
  • Bands of Rarefied Magic – Actually slightly lower damage than the Bracers of Havoc, but much more balanced. Now with a +15 spell damage enchant too

Stats are looking pretty good. Hit is suffering a little though (says someone who can count his Kara raids on one hand :-(

  • Health: 6643
  • Mana: 7616
  • Hit: 10.70% (+3% from Talents)
  • Fire crit: 24.40% (+3% from Molten Armor)
  • Fire damage: 970 (944 excluding Spellfire set bonus)

Overall, very happy with my mage… Just running out of things to aim for, there is one more item I want for badges, but I’m only 5 / 60 so far. I would really like to run Kara on a regular basis with a group of dedicated people, I don’t think it’s possible with this guild, and who on earth wants a Mage for Kara :-(

Posted on

Very Simple (Pretend) SQL Paramaters

<?php

/*

    Some hacked up code for Very Simple (Pretend) SQL Paramaters
    -- For when you don't have PDO, or just can't be bothered

    Examples:

        >>> SQL("SELECT * FROM users WHERE id=? AND name LIKE ?", 123, '"123\"');
        SELECT * FROM users WHERE id=123 AND name LIKE "\"123\\\""

        >>> SQL("INSERT INTO user (nameFirst, nameLast) VALUES (?, ?)", "Fred", "Nurk");
        INSERT INTO user (nameFirst, nameLast) VALUES ("Fred", "Nurk")

*/

function SQL($sql)
{
    $params = func_get_args();
    $params = array_map('mysql_real_escape_string', $params);
    $sql    = explode('?', $sql);

    if(count($params) != (count($sql)-1))
    {
        throw new Exception(sprintf("Incorrect number of paramaters.  Expected %d got %d", count($sql)-1, count($params)));
    }

    $newSql = '';

    for($i = 0; $i < count($params); $i++)
    {
        $newSql .= $sql[$i] . (is_numeric($params[$i]) ? $params[$i] : '"' . $params[$i] . '"');
    }

    return $newSql . $sql[$i];
}

?>

Update: This is not only the wrong way to escaping, but introduces more bugs. Don’t ever use.

Posted on

PHP interface for the DecentUrl API

PHP version of the Python script located at http://decenturl.com/tools#api.

Update: Thanks to a quick update by Ben, DecentURL now returns valid JSON, so the quote workaround is no longer needed.

<?php

/*

    PHP interface for the DecentUrl service
        by Matthew D (project-2501.net)

    Based on the Python script by Ben Hoyt
    See http://decenturl.com/tools#api

    Example:


    <?php

        require_once("decenturl_interface.php");

        //  returns: "youtube/medieval-helpdesk-with-english"
        DecentUrl::Get('http://youtube.com/watch?v=pQHX-SjgQvQ');

        //  returns: "http://youtube.com/watch?v=pQHX-SjgQvQ"
        DecentUrl::Resolve('youtube/medieval-helpdesk-with-english');

        //  returns: array("DecentURL - Making ugly URLs decent", "making-ugly-urls-decent")
        DecentUrl::Title('http://decenturl.com/');

        //  returns: "brush.co.nz"
        DecentUrl::Domain('http://brush.co.nz');

        //  throws a DecentUrlException("resolve request failed:  notfound")
        DecentUrl::Resolve('baddy');
    ?>

*/

    class DecentUrlException extends Exception {}
    class DecentUrl
    {
        const BASE_URL = 'http://decenturl.com/api-';

        //  Create or get decent URL from given ugly one and return it
        public static function Get($url, $title="")
        {
            $response = self::Request("get", array("u" => $url, "t" => $title), 2);

            return $response[0];
        }

        //  Resolve decent URL and return ugly original
        public static function Resolve($decentUrl)
        {
            $response = self::Request("resolve", array("d" => $decentUrl), 2);

            return $response[0];
        }

        //  Return tuple of full <title> and decent title for given URL
        public static function Title($url, $maxLength = 1000)
        {
            return self::Request("title", array("u" => $url, "l" => $maxLength), 2);
        }

        //  Return URL's base domain
        public static function Domain($url, $maxLength = 1000)
        {
            $response = self::Request("domain", array("u" => $url, "l" => $maxLength), 1);

            return $response[0];
        }

        //  Call generic DecentUul API function, throw DecentUrlException if not ok
        private static function Request($type, $parameters, $expectedResponseSize = false)
        {
            //  Take a key value pair, and join them together, making sure to
            //  urlencode the value
            foreach($parameters as $key => $value)
            {
                $parameters[$key] = sprintf("%s=%s", $key, urlencode($value));
            }

            $queryString = implode("&", array_values($parameters));

            $url = sprintf("%s%s?%s", self::BASE_URL, $type, $queryString);

            $contents = file_get_contents($url);

            $response = json_decode($contents);

            if($response == null)
            {
                throw new DecentUrlException("Response was not valid JSON");
            }

            if($response[0] != "ok")
            {
                throw new DecentUrlException("{$type} request failed:  {$response[0]}");
            }

            //  Remove the first element (which we proved was 'ok' above)
            $trimedResponse = array_slice($response, 1);

            //  If requested, we check to see that the response is the correct
            //  size.
            if(($expectedResponseSize !== false) && (count($trimedResponse) != $expectedResponseSize))
            {
                throw new DecentUrlException("{$type} request failed:  expected {$expectedResponseSize} fields, got " . count($trimedResponse));
            }

            return $trimedResponse;
        }
    }

?>

Posted on

The timewaster

Yep, another WoW post.

  • Karazhan is still at exactly the same place it was last time… That is pretty embarrassing :-)
  • I’ve respec’d yet again. Now 10/48/3 Fire
  • My health and mana are now tiny, at 6463 / 7166 unbuffed
  • Spell damage is now: +885 fire unbuffed (Including Wrath of Spellfire Set bonus)
  • I think most impressively upgrade is my hit: +129 (10.23%) not including the 3% bonus from Elemental Precision :D

Future Upgrades

November 21st Update

I’m not even going to mention Kara today. As good as my current guild is, I’m seriously thinking about moving (but then again, no one really wants a level 70 mage)

  • +915 Fire damage (Unbuffed but with Spellfire Set bonus)
  • 6513 / 7421 Health/Mana
  • 23.38% Fire crit (Unbuffed)
  • 12.13% Spell hit (Before +3% Talent bonus) – For someone who doesn’t actually raid, I think this is a pretty good achievement
  • I spent all my badges on a Carved Witch Doctor’s Stick as Quagmirran’s Eye finally dropped.
  • Still trying to collect badges for the Icon of the Silver Crescent and the Runed Spell-cuffs. Going to be a while though
  • I’m really running out of practicable things to buy/craft (an Epic Flying Mount is completely out of the question) :-(

Posted on

5 Things I hate about PHP

Articles on why PHP sucks are fairly common (PHP is a really easy target). So rather than repeat what’s already been said (lack of namespaces, function naming, and argument positions, etc), I though I’d try and come up some more obscure ‘features’ and ‘bugs’ in PHP that I hate.

create_function()

//  Actually creates a new named function, in the global namespace every
//  time it's called, even if it's called with the exact same arguments.
//  Syntax is pretty bad too, need to pay close attention to quoting strings

$args = '$r';
$body = 'return $r;'

$f1 = create_function($args, $body);
$f2 = create_function($args, $body);

// Displays false
var_dump($f1 == $f2);

Automatic creation of class members

//  This should throw a E_NOTICE, or E_STRICT (though I do believe that PHP needs a
//  way to add members,  as it is sometimes is useful.  Maybe allow it on stdclass,
//  and not user defined classes?)

// Completely valid code
$foo = new stdClass();
$foo->bar = "abc"

//  You can take this one step further (still valid PHP)
$bar->xyzzy = "abc";
echo $bar->xyzzy;

Scope, wonderful scope

$numbers = array(1,2,3);
foreach($numbers as $number)
{
    echo $number . "\n";
}

//  This should throw a error notice of Undefined variable
//  instead is prints 3
echo $number . "\n";

extract()

extract() works in a similar method to register.globals, while it’s safer (you can make sure it never overwrites existing variables) it still is a really bad idea.

Late static binding

class aParent
{
    static $phrase = "Goodbye";

    public static function SayHello()
    {
        printf("%s %s from class %s\n", self::$phrase, self::GetWorld(), get_class());
    }

    public static function GetWorld()
    {
        return "Universe";
    }
}

class aChild extends aParent
{
    static $phrase = "Hello";

    public static function GetWorld()
    {
        return "World";
    }
}

//  All good here...
//  Displays:       'Goodbye Universe from class aParent'
//  Should display: 'Goodbye Universe from class aParent'
aParent::SayHello();

//  Not so good here though...
//  Displays:       'Goodbye Universe from class aParent'
//  Should display: 'Hello World from class aChild'
aChild::SayHello();

Posted on

WoW Update

Wow, almost two weeks since my last WoW post. In short:

  • Respect to Arcane/Fire, for (hopfully) better mana management
  • Frostsabre mount from Darnassus
  • Picked up Boots of Blasphemy
  • Went to Karazhan with my guild Gankers Inc. Wasn’t a great result, but was fun

Posted on