Archive for February, 2005

New BritBlog Features

BritBlog now has over a thousand members (woohoo!), and I’ve been planning some exciting new features for the service. If anyone has any suggestions or input, I’d be pleased to hear from you. Either use the comments form below, or drop me an email.

The main goal of these features is to maintain the quality of the data in the directory. We need to identify blogs that have been abandoned so that the directory doesn’t just become a collection of broken links.

  • BritBlog Bot - The bot will visit all the member sites and perform the following tasks:
    • Check that the blog is still online
    • Locate the blog’s RSS (or similar) feed (to help keep an eye on the frequency of updates)
    • Look to see if the blog links back to BritBlog (there will be benefits to those who do ;-) )
  • Annual Renewal of Membership - I plan on sending out renewal emails after 11 months of membership with a ‘click me to renew’ link in it. This (along with the first task of the bot) is to ensure that member blogs are still active, and that the owners still wish to be listed. If I don’t do something like this, there is a risk that the directory will get full of junk blogs.
  • Implement a Ping Service - When member blogs are updated, I would like them to be able to ping us so that we can maintain a recently updated blogs list. This could also be used to detect stagnant blogs.
  • Blogs Near Me Widget - I want to have something a bit like the Blog Browser over at London Bloggers that people can put on their site. When clicked, a pop-up list of bloggers based near the current one will appear. (Any DHTML gurus out there?)
  • Improve the Admin Console - I’d like to get more people involved behind the scenes with BritBlog, and one of the first places this will happen will be in the reviewing of new member blogs. We’re starting to get some silly people sign up, and this degrades the overall quality of the service. So if I could get some folk to help out with this process it would be rather handy :-)

That, I think, is about it for the mean time. I’ve no idea when I’ll actually get ’round to implementing any of it though, but it should be good when it’s done. Watch this space for an update!

PHP, Stored Procedures, and SQL Server

While working on ezmp3, I had occasion to use MS SQL Server stored procedures from PHP. A couple of people I know always moan about blogs filling up the internet with useless junk, so here, for the benefit of all mankind, is something I hope some of you may find useful!

The MS SQL/PHP documentation on this was a little sparse at the time, so I’ve decided to put together an example here for other people to see/use.

Getting a database connection is very similar to what you might do with PostgreSQL or MySQL:

<?php
function &get_conn()
{
   global $conn;
   $myServer = "localhost";
   $myUser   = "markuser";
   $myPass   = "markpass";
   $myDB     = "markdb"; 

   if(!$conn)
   {
      $conn = mssql_connect($myServer, $myUser, $myPass)
         or die("Couldn't connect to SQL Server on $myServer");
      mssql_select_db($myDB, $conn)
         or die("Couldn't select database $myDB");
   }
   return $conn;
}

/* get a connection */
$conn =& get_conn();
?>

(Some of you may frown at the use of global $conn. I don’t normally use this, but it was a quick and dirty hack, not for production use….)

So far, all pretty standard stuff.

When executing a stored procedure, you have two choices.

1. (BAD) Execute it as a standard SQL statement:

EXEC myprocedure param1, param2, param3

or

EXEC myprocedure @id=param1, @name=param2, @email=param3

This is great from the command line when using isql, or when using SQL query analyzer (damn the Americans and their Z’s!).

2. (GOOD) A far more robust solution is to use the mssql_init, mssql_bind and mssql_execute methods, and bind named (and typed) parameters to your stored procedure object. The following snippet example gives you an idea of how to do this:

<?php
/* prepare the statement resource */
$stmt=mssql_init("myprocedure", $conn);

/* now bind the parameters to it */
mssql_bind($stmt, "@id",    $id,    SQLINT4,    FALSE);
mssql_bind($stmt, "@name",  $name,  SQLVARCHAR, FALSE);
mssql_bind($stmt, "@email", $email, SQLVARCHAR, FALSE);    

/* now execute the procedure */
$result = mssql_execute($stmt);
?>

There are two great benefits to using this approach:

  1. Security - You don’t have to worry about escaping characters (like apostrophes) in your variable names. This makes nasty things like SQL injection impossible.
  2. Typed variables - If you try and put text in a field that should be an integer you will get an error. While nobody likes errors, it’s much better to get them here than at the database end.

So that’s it in a nutshell! I needed my stored procedure to return stuff to me, but I was having problems getting my output parameters to work. I’ve just seen the following in the online PHP documentation, posted by a chap called Matt, that may help here:

1) you need to pass your php variable by reference. mssql_bind($stmt, "@outParam", &$outParam, true)

2) php-4.3.1-win32 had a binding bug and output parameters do not bind. 4.1 and 4.3.2rc1 do not have the bug. I have not tested other versions.

I was running PHP on Windows, so it may have been this. I may not have passed the output variable by reference either, though I have a feeling I did try this… Anyway, I got around the problem by returning a normal result/record set from my procedure, and getting it in the normal way:

<?php
/* execute the procedure */
$result = mssql_execute($stmt);

/* get the row that is returned */
$row = mssql_fetch_assoc($result);

/* get my value out */
$my_id = $row['album_id'];
?>

Right, that’s about it. I hope some of you find this useful. I’m no guru on this sort of stuff, but it seemed to do the job for me. When I have MS SQL server available I try to use stored procedures whenever possible as they are so quick, they are far more robust, and they are extremely secure. In fact, I normally use the permissions manager to prevent my web user from running SELECT, INSERT, UPDATE and DELETE statements, and just give them EXEC permissions on specified stored procedures. I love SQL server… but that’s another story :-)

a ‘weblogUpdates.ping’ - like interface for BritBlog

OK, I’ve been tinkering with this XML-RPC stuff for BritBlog. Basically, I want an interface the same as the Weblogs.Com XML-RPC weblogUpdates.ping method for BritBlog, as I mentioned earlier.

Acording to the documentation, I need to accept the following parameters:

weblogUpdates.ping (weblogname, weblogurl, changesurl=weblogurl, categoryname=”none”) returns struct

To tell Weblogs.Com that a weblog has changed, call weblogUpdates.ping on rpc.weblogs.com, port 80, path /RPC2.

It takes two required parameters, both strings, and two optional parameters, also strings. The first is the name of the weblog, the second is its URL. The third, changesurl, is the url of a page to be checked for changes. The fourth, categoryname, is the name of a category of pings, allowing the weblogs.com interface to be used to track RSS feeds, European weblogs, or whatever.

So I need a method that can accept two, three or four parameters (all strings).

Using the PEAR XML-RPC package I’ve created a framework that doesn’t actually do anything except tell me how many parameters I’ve sent (assuming they are of the correct type):

Listing 1: server.php

<?php
require_once 'XML/RPC/Server.php';

/*
** The 'update method'. This will do the work.
*/
function weblogUpdatePing($params)
{
   switch ($params->getNumParams())
   {
      case 2:
         $strReturn    = "Two params";
         $weblogname   = $params->getParam(0);
         $weblogurl    = $params->getParam(1);
         break;

      case 3:
         $strReturn    = "Three params";
         $weblogname   = $params->getParam(0);
         $weblogurl    = $params->getParam(1);
         $changeurl    = $params->getParam(2);
         break;

      case 4:
         $strReturn    = "Four params";
         $weblogname   = $params->getParam(0);
         $weblogurl    = $params->getParam(1);
         $changeurl    = $params->getParam(2);
         $categoryname = $params->getParam(3);
         break;

      default:
         /*
         ** Should never get here as the method
         ** signatures will prevent this
         */
         $strReturn = "Invalid parameter count.";
         break;
   }

   $val = new XML_RPC_Value($strReturn, 'string');
   return new XML_RPC_Response($val);
}

/*
** Create a server instance to handle the request.
*/
$server = new XML_RPC_Server(
   array(
      'weblogUpdates.ping' => array(
         'function'  => 'weblogUpdatePing',
         'signature' => array(array($XML_RPC_String,
                                    $XML_RPC_String,
                                    $XML_RPC_String),
                              array($XML_RPC_String,
                                    $XML_RPC_String,
                                    $XML_RPC_String,
                                    $XML_RPC_String),
                              array($XML_RPC_String,
                                    $XML_RPC_String,
                                    $XML_RPC_String,
                                    $XML_RPC_String,
                                    $XML_RPC_String))
      ),
   )
);
?>

To test this I used a simple client.

Listing 2 client.php:

<?php
require_once 'XML/RPC.php';
/*
You can call the method with two, three, or four parameters:

$params = array(new XML_RPC_Value('one', 'string'),
                new XML_RPC_Value('two', 'string'),
               );

$params = array(new XML_RPC_Value('one',   'string'),
                new XML_RPC_Value('two',   'string'),
                new XML_RPC_Value('three', 'string'),
               );
*/
$params = array(new XML_RPC_Value('one',   'string'),
                new XML_RPC_Value('two',   'string'),
                new XML_RPC_Value('three', 'string'),
                new XML_RPC_Value('four',  'string'),
               );

$msg = new XML_RPC_Message('weblogUpdates.ping', $params);

$cli = new XML_RPC_Client('/rpc/server.php', 'localhost');

//$cli->setDebug(1);

$resp = $cli->send($msg);

if (!$resp)
{
    echo 'Communication error: ' . $cli->errstr;
    exit;
}

if (!$resp->faultCode())
{
    $val = $resp->value();
    echo 'return message is ' . $val->scalarval();
}
else
{
    /*
     * Display problems that have been gracefully cought and
     * reported by the xmlrpc.php script.
     */
    echo 'Fault Code: ' . $resp->faultCode() . "n";
    echo 'Fault Reason: ' . $resp->faultString() . "n";
}
?>

So that seems to work as a simple framework. Now I’ve just got to add some logic to:

  • check to see if the pings are from BritBlog members,
  • check that they haven’t updated recently (say withing 24 hours) - we don’t want ping spammers,
  • check that they have really updated their blog by getting their RSS feed,
  • Update the ‘recently modified’ page/database stuff.

OK, that’s enough tonight. Anymore work and I’ll have to start to think, which after some Badger’s Tanglefoot and more Fuller’s Golden Pride is probably not possible. Still, time for another beer before bed, me thinks :-)

Fun with XML-RPC

Got a little XML-RPC project to do, which should be fun. Just not sure that 7.00 PM is a good time to start thinking about it…

So what’s this project? I hear you all cry. Well, I want to add a ‘recently updated blogs’ page to BritBlog, so that when you make a new post on your blog, you can ping BritBlog, and if you are a member (your site is found in our database) your blog will appear on the page.

Should be fairly simple to set up, but it’s a while since I’ve played with XML-RPC so I’ve got to remember how it all works. Got to find the standard spec. for pinging too, and this seems slightly elusive…

Still, I think it was my lucky day today, so perhaps I’ll have more luck on this topic too. I put a £2 coin in the parking meter this morning and it jammed. So I thumped the meter and my coin fell out along with two £1 coins! Don’t worry, I won’t spend it all at once!

Just upgrading…

If everything goes messy, please bear with me! I’m just upgrading the site :)

Update All done… I think!

I’ve been playing around with the theme stuff, and seem to be getting there. Got a few more theme files to do, but am getting a bit bored with it now. Will finish it off another time. The good news is that all you lucky people will be able to download and install this theme very soon ;-)

I was going to go for a standard looking blog that floats in the middle of the screen and has a shadow down each side, but everyone seems to have that, and I find the width is too narrow when I want to add code snippets to my posts. So I have come up with this rather green thing… I kinda like it, but I’ve got to go through my old posts and tidy them up a bit now.

Right, time for a beer and some food. I’ve got some bottles of Fullers Golden Pride in (at 8.5%!), so this should be interesting.

Update Wooh, strong beer!

Canon EOS 350D Announced

Canon have announced the new Canon EOS 350D camera (preview).

Canon EOS 350D

Canon EOS 350D

On paper it looks very good, and I’m looking forward to having a play with it. However, it is even smaller than the 300D that it replaces, and I just wonder how well it’s going to handle. My EOS 20D is bigger than both the 300D and 350D, but I still find it too small to hold comfortably. Anyway, as I say, I’m looking forward to having a play with it.

Canon have also announced a new macro lens, the EF-S 60mm F2.8 macro. I was planning on getting a macro lens in the spring, so I’ll have to keep an eye on the reviews for this one.

WordPress 1.5 “Strayhorn” released

As Gary points out, WordPress 1.5 “Strayhorn” is now released so I’m looking forward to upgrading it when I get a chance. I’ve got a new look coming on too, so I’ll build it all into one of the new templates when I get a chance :)

Hmmm

Well, I think today has been one of the most boring of the year.

However, I had a good weekend. Went to a very nice Japanese restaurant on Saturday for lunch with some friends. Although I’ve had Japanese food before (a friend is married to a Japanese girl), it was my first time in a Japanese restaurant, and I must say it was an enjoyable experience! The food was great, the drink was excellent, and the service was impeccable.

After that I went for a very swift beer with my old housemate from Cambridge, and tried to take photos of blue things. It was raining and getting dark so I came on home and fell asleep on the sofa for a bit.

Sunday involved a good sleep, laundry, and dinner with my parents, so quite a relaxing day.

So why blue things? I’ve started re-working my blog. I’m no designer, but I’m well aware that this site is a bit dull looking. The new design is coming on, but I want some pictures to brighten up the place. My quest for blue things wan’t so good on Saturday, so I’ll take my camera to work with me tomorrow and see if I can find anything blue at lunch time…

Anyway, shagged as always, so must be off to bed.

By the way, BritBlog is growing really well at the moment, but on the flip side I’m getting tonnes of junk submissions. Anyone fancy helping me out with the editing of the submissions? Drop me an email if you do :-)