Tải bản đầy đủ (.pdf) (5 trang)

Plug in PHP 100 POWER SOLUTIONS- P45 docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (240.69 KB, 5 trang )


186
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s

186
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s
returns a value of 0 or greater if a match is found, or FALSE if not. The string being
checked for is |$to|$from|$message\n, which will ensure that only repeated posts
from the same poster, to the same recipient, with the same message will be ignored.
If the post is a duplicate and flood control is on, then the file lock is released, the file is
closed, and a value of 0 is returned. Otherwise, the posts in the string variable $text are
extracted into the array $lines using the explode() function to split them all out at \n
newlines.
Next, the counter at the start of the last line of chat is extracted into the array $temp.
This is done by referencing the correct element of $lines and then using explode() to pull
all the parts into $temp. The plug-in is only interested in the first element of $temp, so that
value is looked up and the number 1 is added to increment it. This gives the value to use for
the message number of the new post being appended—the next in sequence. Therefore,
$text (which contains the remaining chat posts, after ignoring the first one) has the message
number appended to it, followed by the contents of $to, $from, and $message, separated by
| symbols, and terminated with a \n newline character.
To update the file’s contents, the fseek() command is called to move the read and write
pointer into $datafile to the very start. You remember that the first post was discarded?
Well, now all the following posts must be moved back accordingly, so after seeking, the
contents of $text are then written to the file starting at position 0.
Lastly, because the file is readable and writeable and we have been treating it like random
access memory, if the size of the new set of posts is smaller than the previous set, then the file
will have some spurious text remaining at its end. This has to be discarded by issuing a call to
the truncate() function, passing it the exact size of $text. The file lock is then released, the
file closed, and a value of 1, representing success, is returned.
How to Use It


Generally, you will use this plug-in as part of an HTML form submission and processing
program. To allow the chat to be viewed without interruption, you will also probably place
the program within an <iframe> tag so it takes up just a portion of the screen and works
independently from the rest of the chat.
A good way to do this is to create a simple web form like the following, but embedded
within your PHP code:
echo <<<_END
<form method=post action="$_SERVER[PHP_SELF]"><pre>
From: <input type=text name='from' />
To: <input type=text name='to' />
Message: <input type=text name='message' />
<input type=submit value='Post Message' />
</pre></form>
_END;
Instead of using a program name for the action of the form, this script uses the PHP
system variable $_SERVER[PHP_SELF], which simply refers to the program currently
running, whatever name it may have. This means you can call the program anything you like.
For simplicity of layout, I have used a <pre> tag here to force a monospaced font. You
will probably want a much more interesting layout for your own program. Also, you will
C h a p t e r 8 : C h a t a n d M e s s a g i n g
187
C h a p t e r 8 : C h a t a n d M e s s a g i n g
187
most likely have already asked for the user’s name and, if so, could use the following From:
input line instead:
<input type=hidden name='from' value='$from' />
This means that the only two items you will ask your users for are the recipient’s name
and the message to post. To simplify things even further for your users, you might even
replace the To: input line with a <select> tag and a drop-down list of all current users—
but with the default name being blank for public posts.

In other words, you should think about how your users will initially enter their usernames,
which you will then store if you are going to offer pull-down lists of names for private
messaging. So, when about to call this plug-in, your program should be armed with three
pieces of information:
1. The poster’s username
2. The recipient’s name (or blank if a post is public)
3. The message to post
If these have been posted to your program, they will appear in the $_POST array and
can be referenced like this (not forgetting that you may wish to also use some other plug-ins
in this book to sanitize user input):
$from = $_POST['from'];
$to = $_POST['to'];
$message = $_POST['message'];
You can then add the post to the chat by calling the plug-in like this:
$result = PIPHP_PostToChat('chatroom.txt', 20, 1000, $from, $to,
$message, 'off');
Here the chatroom datafile is chatroom.txt, the maximum number of posts to keep stored
is 20, the maximum length allowed for each post is 1000 characters, and flood control is set
to “off”.
If $result contains the value 1, then the message has been successfully posted. Otherwise,
see the preceding section, About the Plug-in, for the list of error codes and their meanings.
Bringing this all together, a program to display a single line input, residing in an iframe,
that continually allows posting of public messages to the chat might look like this:
<?php
if (isset($_POST['message']))
{
$from = $_POST['from'];
$to = $_POST['to'];
$message = $_POST['message'];
PIPHP_PostToChat('chatroom.txt', 20, 1000, $from, $to,

$message, 'off');
}
else $from = 'username'; // Enter the poster's username here


188
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s

188
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s
echo <<<_END
<form method=post action="$_SERVER[PHP_SELF]">
<input type=hidden name='from' value='$from' />
<input type=hidden name='to' value='' />
Message: <input type=text name='message' />
<input type=submit value='Post Message' />
</form>
_END;
?>
This code will keep displaying a prompt similar to the following, and whenever a
message is entered it will post it to the chat datafile and redisplay the prompt:
Message: _______________________________________ [Post Message]
As discussed previously, posting private messages to other users is a little more
complicated, but only a little, in that you simply have to set $to to the recipient’s username.
To do this, you would probably change the input form display to look something like the
following, in which the first entry of a drop-down list is *ALL*, and then, if the variable $to
ever has the value *ALL*, you would simply set it to the empty string before calling the
plug-in.
Message: ___________________________ To: [*All*] [Post Message]
Or you may wish to offer other ways of sending private messages such as listing all

current users in a side panel and making them clickable to pull up a private messaging
input prompt. That’s why I have left the plug-in fully flexible, so you can choose exactly
how your chat should look and work.
The following plug-in, View Chat, will be used to display the messages in real time with
auto scrolling.
The Plug-in
function PIPHP_PostToChat($datafile, $maxposts, $maxlength,
$from, $to, $message, $floodctrl)
{
if (!file_exists($datafile))
{
$data = "";
for ($j = 0 ; $j < $maxposts ; ++$j) $data .= "$j|||\n";
file_put_contents($datafile, $data);
}

if ($message == "" || strpos($from, '|') ||
strpos($to, '|')) return -2;

$message = str_replace('|', '&#124;', $message);
$message = substr($message, 0, $maxlength);
$fh = fopen($datafile, 'r+');
if (!$fh) return -1;

C h a p t e r 8 : C h a t a n d M e s s a g i n g
189
C h a p t e r 8 : C h a t a n d M e s s a g i n g
189
flock($fh, LOCK_EX);
fgets($fh);

$text = fread($fh, 100000);

if (strtolower($floodctrl) == 'on' &&
strpos($text, "|$to|$from|$message\n"))
{
flock($fh, LOCK_UN);
fclose($fh);
return 0;
}

$lines = explode("\n", $text);
$temp = explode('|', $lines[$maxposts - 2]);
$text .= ($temp[0] + 1) . "|$to|$from|$message\n";
fseek($fh, 0);
fwrite($fh, $text);
ftruncate($fh, strlen($text));
flock($fh, LOCK_UN);
fclose($fh);
return 1;
}
View Chat
This plug-in is surprisingly small considering the power it packs, providing a continuously
open connection to a chat server using just HTML, so that new messages appear as posted,
without having to refresh the page. With some nifty JavaScript, it also auto scrolls the page
when new messages display at the page bottom, and it can distinguish between a private
and a public message, displaying each to the correct people.
Figure 8-5 shows four users chatting, as viewed from the user fredsmith’s perspective.
You can see all the public messages in regular typeface, while the private ones from and to
fredsmith are shown in italic font and prefaced by the string (PM to username).
FIGURE 8-5 This plug-in handles viewing of public and private messages and includes auto scrolling.


55

190
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s

190
P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s
About the Plug-in
This plug-in takes a chatroom datafile and displays all the messages the current user is
allowed to see: either public or private ones to or from that user. It takes these arguments:
• $datafile A string containing the location of a chatroom datafile
• $username The username of the current user viewing the chat
• $maxtime The maximum time in seconds a connection will stay open to the
server. This needs to be a large value to prevent the chat reloading too often.
About 300 seconds (5 minutes) is a good start point.
Variables, Arrays, and Functions
$tn
String containing the current time as a timestamp
$tstart
String containing the HTML table start tags
$tmiddle
String containing the HTML table middle tags
$tend
String containing the HTML table end tags
$oldpnum
Integer containing the value of the highest read post number
$lines Array containing the posts extracted from $datafile
$line String containing a single line of data from $lines
$thisline Array containing all the elements extracted from $line

$postnum
Integer containing the number of the current post being read
$to
String containing the recipient name of the current post being read
$from
String containing the sender name of the current post being read
$message
String containing the message of the current post being read
How It Works
This plug-in is really one big loop that goes round and round checking the contents of
$datafile and displaying any new posts it finds that the user is authorized to view.
It starts by trying to load in the chatroom datafile $datafile, and returns FALSE if it
can’t be read. Otherwise, the time the program is allowed to run (in seconds) is set using the
set_time_limit() function and the argument $maxtime + 5. The extra 5 seconds are
added to ensure the plug-in will return gracefully, without displaying any warning message
about the program having timed out.
Tables are used to isolate the messages from each other so the next three string variables
are initialized: $tstart, $tmiddle, and $tend. These contain HTML tags suitable for
building a table in which to place each displayed message. This is a particularly useful trick,
for example, when you offer the use of BB Code or Pound Code (plug-ins 39 and 40) and the
user doesn’t properly close tags. By placing the strings in a table, all tags will be fully closed
regardless of which ones are left open and the formatting from any one message won’t
affect any other.
The final variable to initialize is $oldpnum. This is set to 0 to start with but will be increased
to the value of the highest numbered post read so far. This way the program can tell when
a new post comes in by noting whether it has a higher post number.

×