← The Number 22

How To Implement Pingback

....because it drove me insane when I was writing the new Four Island. There didn't appear to be any information on it anywhere. Or at least, any complete information.

Finally, however, I found the Pingback Specification, which, at the bottom of the page, includes a nice little step-through of Pingback at work.

To summarize, there are two parts of the Pingback process. The server and the client. The client sends Pingbacks and the server receives them.

When writing a blog post, the client should scan it for external links and, if any are found, attempt to read the pages they link to. If they contain a <LINK REL="pingback" HREF="...."> tag, then that means that the page in question supports pingback. So, if one is found, the client uses XML-RPC to connect to the server URL specified in the HREF attribute of the tag mentioned above. Then, it calls the method pingback.ping with two parameters, the first being the URL of the local post, the second being the URL of the post being linked to. From there, it's the server's job.

When the server receives the Pingback, it checks to see the both URLs actually exist and that the linking blog post actually links to the second URL. If it does, the server adds a comment to the blog post in question saying that it's been linked to and providing a link to the linking blog post.

Ok, that probably sounded complicated. It is, a little. So, that's why we're going to do this step by step, starting with the client. Let's examine the specification process again:

  1. First, the client scans the post being submitted for external links.

We can accomplish this with a simple screen scraper which is a script that combs through an HTML page and picks up useful information. We'll be using a simple one to pick up all of the links, and then to sift out the ones that aren't external: (Note that I am assuming that the contents of the post are located in $postText)

preg_match_all('|<a\s[^>]*href="([^"]+)"|i',
        $postText,
        $matches);

foreach ($matches[1] as $link)
{
  if ($all_links[$link])
  {
    continue;
  }

  $all_links[$link] = true;

  if (preg_match('/^https{0,1}:/i', $link))
  {
    // We've got an external link!
  }
}
  1. Then, the client attempts to download any links it finds.

This is easy as well. For this I'll be using cURL. Note that this code goes in place of the comment // We've got an external link!.

$c = curl_init();
curl_setopt($c, CURLOPT_URL, $link);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
$page_data = curl_exec($c);
curl_close($c);
  1. If they contain a <LINK REL="pingback" HREF="...."> tag, then that means that the page in question supports pingback.

Checking for the tag is again, easy. We do it with a simple regular expression:

if (preg_match('/<LINK REL="pingback" HREF="([^"]+)">/i',
        $page_data,
        $server))
{
  // It has the <LINK> tag!
}
  1. Finally, the client sends an XML-RPC request to the server located in the tag.

For this, we need XML-RPC for PHP. It's a very easy to use XML-RPC library. Somewhere in your page, you need to include it's client libraries (in lib/xmlrpc.inc). When that's done, we have our client-side Pingback code:

$client = new xmlrpc_client($server[1]);
$msg = new xmlrpcmsg("pingback.ping", array(
        new xmlrpcval(PERMALINK, 'string'),
        new xmlrpcval($link, 'string')));
$client->send($msg);

Make sure to replace PERMALINK with some method of generating the URL of the current post.

That's the client-side part of Pingback, the sending side. Now for the server side.

Before we begin, we have to remember that the client finds the server by looking for a tag in the blog post's page header. You should include this now into your global header file:

<LINK REL="pingback" HREF="http://yourdomain.com/xmlrpc.php">

Now it's time to make that xmlrpc.php.

  1. The server has to be able to receive XML-RPC requests. Because of this, it needs to include XML-RPC for PHP's server-side library (lib/xmlrpcs.inc) as well as the client-side. Then, it needs to define the pingback.ping method.
$s = new xmlrpc_server(array(
        "pingback.ping" => array("function" => "ping")));

function ping($xmlrpcmsg)
{

}
  1. The server then needs to verify that both URLs actually exist.

How to implement this part is up to you as I'm not writing your entire blog, but the code to extract the URLs passed as arguments to the pingback.ping method is as follows:

$from = $xmlrpcmsg->getParam(0)->scalarVal();
$to = $xmlrpcmsg->getParam(1)->scalarVal();
  1. Finally, the server posts a comment to the blog post in question notifying people that someone has sent it a pingback.

Once again, this is mostly up to you as I don't know the specifics of your blog. However, when the comment has been successfully added, the XML-RPC server needs to return with a response to the client:

return new xmlrpcresp(new xmlrpcval(
        "YAY! Your Pingback has been registered!", "string"));

YAY! You're Pingback implementation is nearly done! There's only a little bit left now. With the server, it has to response with an appropriate error if there's some problem such as the source URL not existing. Here's a list of them:

  • From doesn't actually link to To:
return new xmlrpcresp(0, 17,
        "Source uri does have link to target uri");
  • To URL doesn't exist:
return new xmlrpcresp(0, 32,
        "Target uri does not exist");
  • To URL doesn't support pingback:
return new xmlrpcresp(0, 33,
        "Target uri cannot be used as target");

I really hope someone finds this tutorial useful because when I wanted to implement Pingback support on my blog, as I said before, it was very difficult to find any good information about it.

EDIT: Wow. One of the most popular posts on the site and it was posted, of all days, June 17th. Very strange.

Hatkirby on June 16th, 2008 at 10:30:02pm
👍 5 👎

Comments

I still don't get pingbacks... On the topic of code, this is interesting/cool: Horizontal Javascript Accordion Menu

tamasys on June 17th, 2008 at 12:59:06am

As you can probably see, I've fixed your above comment. For future reference, see the wiki page entitled BBCode for more information on the Four Island BBCode system.

If you don't quite understand Pingback, see this Four Island post: Pingback Support.

Oh! That is quite interesting, and pretty as well. Do you use it anywhere?

Hatkirby on June 17th, 2008 at 2:53:10am

i shall reply in a list (because there are 3 unrelated things and coz i can now use BBCode.

  1. I had not realised that BBCode was in effect over the entire island, but now i do, so... YAYZ!

  2. I shall look at the article, but being the oh so dumb me i probably still wont get it :)

  3. I whould use it if i had somewhere to, but i am not quite smart enough to actually have something to put it ON. grr. must learn... something webby

  4. although i only said 3 points up there, this fourth one is to say 'i hope this works' and to make HK (hatkirby, not Hong Kong) happy.

tamasys on June 17th, 2008 at 6:27:19am

YAY for four! Thanks.

Also, Pingbacking someone is easy. Simply post a link to the blog post you want to Pingback onto your blog. Then, your blog will Pingback mine, and my blog will add a link to the post on your blog in the comments section. That's a Pingback. Not that difficult.

If you wish to try it out, feel free to Pingback The New Four Island, as it's our test Pingback post. I already have Pingbacks from Smiley and Gryphic there.

Hatkirby on June 17th, 2008 at 6:46:23am

Thanks for this. I succesfully implemented pingbacks on my custom blog. Your tutorial was very useful. I wrote a tutorial too (in finnish) about pingbacks :)

o-p on December 1st, 2010 at 11:59:46am
Replying to comment by :
Feel free to post a comment! You may use Markdown.