Book HomePHP CookbookSearch this book

17.5. Posting Messages to Usenet Newsgroups

17.5.1. Problem

You want to post a message to a Usenet newsgroup, such as comp.lang.php.

17.5.2. Solution

Use imap_mail_compose( ) to format the message, then write the message to the server using sockets:

$headers['from'] = 'adam@example.com';
$headers['subject'] = 'New Version of PHP Released!';
$headers['custom_headers'][] = 'Newsgroups: comp.lang.php';

$body[0]['type'] = TYPETEXT;
$body[0]['subtype'] = 'plain';
$body[0]['contents.data'] = 'Go to http://www.php.net and download it today!';

$post = imap_mail_compose($headers, $body);

$server = 'nntp.example.com';
$port = 119;

$sh = fsockopen($server, $port) or die ("Can't connect to $server.");
fputs($sh, "POST\r\n");
fputs($sh, $post);
fputs($sh, ".\r\n");
fclose($sh);

17.5.3. Discussion

No built-in PHP functions can post a message to a newsgroup. Therefore, you must open a direct socket connection to the news server and send the commands to post the message. However, you can use imap_mail_compose( ) to format a post and create the headers and body for the message. Every message must have three headers: the From: address, the message Subject:, and the name of the newsgroup:

$headers['from'] = 'adam@example.com';
$headers['subject'] = 'New Version of PHP Released!';
$headers['custom_headers'][  ] = 'Newsgroups: comp.lang.php';

Create an array, $headers, to hold the message headers. You can directly assign the values for the From: and Subject: headers, but you can't do so for the Newsgroups: header. Because imap_mail_compose( ) is most frequently used to create email messages, the Newsgroups: header is not a predefined header. To work around this, you must instead add it with the custom_headers array element.

There is a different syntax for the custom_headers. Instead of placing the lowercase header name as the element name and the header value as the array value, place the entire header as an array value. Between the header name and value, add a colon followed by a space. Be sure to correctly spell Newsgroups: with a capital N and final s.

The message body can contain multiple parts. As a result, the body parameter passed to imap_mail_compose( ) is an array of arrays. In the Solution, there was only one part, so we directly assign values to $body[0]:

$body[0]['type'] = TYPETEXT;
$body[0]['subtype'] = 'plain';
$body[0]['contents.data'] = 'Go to http://www.php.net and download it today!';

Each message part needs a MIME type and subtype. This message is ASCII, so the type is TYPETEXT, and the subtype is plain. Refer back to Table 17-1 in Section 17.4 for a listing of IMAP MIME type constants and what they represent. The contents.data field holds the message body.

To convert these arrays into a formatted string call imap_mail_compose($body, $headers). It returns a post that looks like this:

From: adam@example.com
Subject: New Version of PHP Released!
MIME-Version: 1.0
Content-Type: TEXT/plain; CHARSET=US-ASCII
Newsgroups: comp.lang.php

Go to http://www.php.net and download it today!

Armed with a post the news server will accept, call fsockopen( ) to open a connection:

$server = 'nntp.example.com';
$port = 119;

$sh = fsockopen($server, $port) or die ("Can't connect to $server.");

The first parameter to fsockopen( ) is the hostname of the server, and the second is the port to use. If you don't know the name of your news server, try the hostnames news, nntp, or news-server in your domain: for example, news.example.com, nntp.example.com, or news-server.example.com. If none of these work, ask your system administrator. Traditionally, all news servers use port 119.

Once connected, you send the message:

fputs($sh, "POST\r\n");
fputs($sh, imap_mail_compose($headers, $body));
fputs($sh, ".\r\n");

The first line tells the news server that you want to post a message. The second is the message itself. To signal the end of the message, place a period on a line by itself. Every line must have both a carriage return and a newline at the end. Close the connection by calling fclose($sh).

Every message on the server is given a unique name, known as a Message-ID. If you want to reply to a message, take the Message-ID of the original message and use it as the value for a References header:

// retrieved when reading original message
$message_id = '<20030410020818.33915.php@news.example.com>';

$headers['custom_headers'][] = "References: $message_id";

17.5.4. See Also

Section 17.6 for more on reading newsgroups; documentation on imap_mail_compose( ) at http://www.php.net/imap-mail-compose, fsockopen( ) at http://www.php.net/fsockopen, fputs( ) at http://www.php.net/fputs, and fclose( ) at http://www.php.net/fclose; RFC 977 at http://www.faqs.org/rfcs/rfc977.html.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.