برای شروع هم روش ارسال پیغام شخصی به یاهو مسنجر توسط php که خیلی ها سوال کرده بودن رو براتون می گذارم.
البته شاید روشای مختلفی باشه ولی به نظرم این روش خیلی جامع و کامل و اختراع اهالی open source هستش.
نکته مهم در مورد این روش اینه که علاوه بر یاهو به msn,icq,aol هم می تونید ارسال کنید (البته من تست نکردم ولی باید بشه).
خوب یه توضیح مختصر درباره این روش اینه که اساسش اسفاده از Jabber هستش.
حتما خیلی هاتون می دونید جابر چیه ؟
جابر یه سرور که بر روی platform های مختلف نصب می شه و به عنوان یک سرور پیغام رسان مثل سرور یاهو عمل می کنه.
حالا transport هایی هم برای Jabber نوشته شده که سرور نصب شده رو به سرورهای پیغام رسان دیگه مثل yahoo یا msn متصل می کنه. (توضیح بیشتر: jabber.org - the original XMPP instant messaging service)
خوب برای اینکه شما بتونید به یک سرور jabber متصل بشید باید اول یه account تو سرور مربوطه باز کنید که این کار رو به راحتی می تونید توسط یک client مخصوص که معمولا تو
سایت مربوطه معرفی میکنه، انجام بدید.(من خودم Trillian رو معرفی می کنم که حتما می شناسیدش) بعد طبق فایل هایی که براتون ارسال کردم بقیه کارو انجام می دید.
فقط دقت کنید که سروری که انتخاب می کنید transport های مربوط رو نصب کرده باشه (مثال: netlab.cz و jaim.at) یعنی اگه می خواهید به یاهو ارسال کنید سرور مربوطه transport یاهو رو نصب کرده باشه.
فکر کنم بقیه ماجرا خیلی واضح و روشن باشه (با دیدن فایلها)
اگه سوالی بود در خدمتم.

اول این کلاس رو به نام فایل class.jabber.php ذخیره کنید :
کد PHP:
کد PHP:
<?php

/***************************************************************************

    Class.Jabber.PHP v0.4
    (c) 2002 Carlo "Gossip" Zottmann
    http://phpjabber.g-blog.net *** gossip@jabber.g-blog.net

    The FULL documentation and examples for this software can be found at
    http://phpjabber.g-blog.net (not many doc comments in here, sorry)

    last modified: 27.04.2003 13:01:53 CET

 ***************************************************************************/

/***************************************************************************
 *

 *
 ***************************************************************************/

/*
    Jabber::Connect()
    Jabber::Disconnect()
    Jabber::SendAuth()
    Jabber::AccountRegistration($reg_email {string}, $reg_name {string})

    Jabber::Listen()
    Jabber::SendPacket($xml {string})

    Jabber::RosterUpdate()
    Jabber::RosterAddUser($jid {string}, $id {string}, $name {string})
    Jabber::RosterRemoveUser($jid {string}, $id {string})
    Jabber::RosterExistsJID($jid {string})

    Jabber::Subscribe($jid {string})
    Jabber::Unsubscribe($jid {string})

    Jabber::CallHandler($message {array})
    Jabber::CruiseControl([$seconds {number}])

    Jabber::SubscriptionApproveRequest($to {string})
    Jabber::SubscriptionDenyRequest($to {string})

    Jabber::GetFirstFromQueue()
    Jabber::GetFromQueueById($packet_type {string}, $id {string})

    Jabber::SendMessage($to {string}, $id {number}, $type {string}, $content {array}[, $payload {array}])
     Jabber::SendIq($to {string}, $type {string}, $id {string}, $xmlns {string}[, $payload {string}])
    Jabber::SendPresence($type {string}[, $to {string}[, $status {string}[, $show {string}[, $priority {number}]]]])

    Jabber::SendError($to {string}, $id {string}, $error_number {number}[, $error_message {string}])

    Jabber::TransportRegistrationDetails($transport {string})
    Jabber::TransportRegistration($transport {string}, $details {array})

    Jabber::GetvCard($jid {string}[, $id {string}])    -- EXPERIMENTAL --

    Jabber::GetInfoFromMessageFrom($packet {array})
    Jabber::GetInfoFromMessageType($packet {array})
    Jabber::GetInfoFromMessageId($packet {array})
    Jabber::GetInfoFromMessageThread($packet {array})
    Jabber::GetInfoFromMessageSubject($packet {array})
    Jabber::GetInfoFromMessageBody($packet {array})
    Jabber::GetInfoFromMessageError($packet {array})

    Jabber::GetInfoFromIqFrom($packet {array})
    Jabber::GetInfoFromIqType($packet {array})
    Jabber::GetInfoFromIqId($packet {array})
    Jabber::GetInfoFromIqKey($packet {array})
     Jabber::GetInfoFromIqError($packet {array})

    Jabber::GetInfoFromPresenceFrom($packet {array})
    Jabber::GetInfoFromPresenceType($packet {array})
    Jabber::GetInfoFromPresenceStatus($packet {array})
    Jabber::GetInfoFromPresenceShow($packet {array})
    Jabber::GetInfoFromPresencePriority($packet {array})

    Jabber::AddToLog($string {string})
    Jabber::PrintLog()

    MakeXML::AddPacketDetails($string {string}[, $value {string/number}])
    MakeXML::BuildPacket([$array {array}])
*/



class Jabber
{
    var 
$server;
    var 
$port;
    var 
$username;
    var 
$password;
    var 
$resource;
    var 
$jid;

    var 
$connection;
    var 
$delay_disconnect;

    var 
$stream_id;
    var 
$roster;

    var 
$enable_logging;
    var 
$log_array;
    var 
$log_filename;
    var 
$log_filehandler;

    var 
$iq_sleep_timer;
    var 
$last_ping_time;

    var 
$packet_queue;
    var 
$subscription_queue;

    var 
$iq_version_name;
    var 
$iq_version_os;
    var 
$iq_version_version;

    var 
$error_codes;

    var 
$connected;
    var 
$keep_alive_id;
    var 
$returned_keep_alive;
    var 
$txnid;

    var 
$CONNECTOR;



    function 
Jabber()
    {
        
$this->server                = "localhost";
        
$this->port                    = "5222";

        
$this->username                = "larry";
        
$this->password                = "curly";
        
$this->resource                = NULL;

        
$this->enable_logging        = FALSE;
        
$this->log_array            = array();
        
$this->log_filename            = '';
        
$this->log_filehandler        = FALSE;

        
$this->packet_queue            = array();
        
$this->subscription_queue    = array();

        
$this->iq_sleep_timer        = 1;
        
$this->delay_disconnect        = 1;

        
$this->returned_keep_alive    = TRUE;
        
$this->txnid                = 0;

        
$this->iq_version_name        = "Class.Jabber.PHP -- http://phpjabber.g-blog.net -- by Carlo 'Gossip' Zottmann, gossip@jabber.g-blog.net";
        
$this->iq_version_version    = "0.4";
        
$this->iq_version_os        = $_SERVER['SERVER_SOFTWARE'];

        
$this->connection_class        = "CJP_StandardConnector";

        
$this->error_codes            = array(400 => "Bad Request",
                                            
401 => "Unauthorized",
                                            
402 => "Payment Required",
                                            
403 => "Forbidden",
                                            
404 => "Not Found",
                                            
405 => "Not Allowed",
                                            
406 => "Not Acceptable",
                                            
407 => "Registration Required",
                                            
408 => "Request Timeout",
                                            
409 => "Conflict",
                                            
500 => "Internal Server Error",
                                            
501 => "Not Implemented",
                                            
502 => "Remove Server Error",
                                            
503 => "Service Unavailable",
                                            
504 => "Remove Server Timeout",
                                            
510 => "Disconnected");
    }



    function 
Connect()
    {
        
$this->_create_logfile();

        
$this->CONNECTOR = new $this->connection_class;

        if (
$this->CONNECTOR->OpenSocket($this->server, $this->port))
        {
            
$this->SendPacket("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
            
$this->SendPacket("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>\n");

            
sleep(2);

            if (
$this->_check_connected())
            {
                
$this->connected = TRUE;    // Nathan Fritz
                
return TRUE;
            }
            else
            {
                
$this->AddToLog("ERROR: Connect() #1");
                return 
FALSE;
            }
        }
        else
        {
            
$this->AddToLog("ERROR: Connect() #2");
            return 
FALSE;
        }
    }



    function 
Disconnect()
    {
        if (
is_int($this->delay_disconnect))
        {
            
sleep($this->delay_disconnect);
        }

        
$this->SendPacket("</stream:stream>");
        
$this->CONNECTOR->CloseSocket();

        
$this->_close_logfile();
        
$this->PrintLog();
    }



    function 
SendAuth()
    {
        
$this->auth_id    = "auth_" . md5(time() . $_SERVER['REMOTE_ADDR']);

        
$this->resource    = ($this->resource != NULL) ? $this->resource : ("Class.Jabber.PHP " . md5($this->auth_id));
        
$this->jid        = "{$this->username}@{$this->server}/{$this->resource}";

        
// request available authentication methods
        
$payload    = "<username>{$this->username}</username>";
        
$packet        = $this->SendIq(NULL, 'get', $this->auth_id, "jabber:iq:auth", $payload);

        
// was a result returned?
        
if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
        {
            
// yes, now check for auth method availability in descending order (best to worst)

            
if (!function_exists(mhash))
            {
                
$this->AddToLog("ATTENTION: SendAuth() - mhash() is not available; screw 0k and digest method, we need to go with plaintext auth");
            }

            
// auth_0k
            
if (function_exists(mhash) && isset($packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]) && isset($packet['iq']['#']['query'][0]['#']['token'][0]["#"]))
            {
                return 
$this->_sendauth_0k($packet['iq']['#']['query'][0]['#']['token'][0]["#"], $packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]);
            }
            
// digest
            
elseif (function_exists(mhash) && isset($packet['iq']['#']['query'][0]['#']['digest']))
            {
                return 
$this->_sendauth_digest();
            }
            
// plain text
            
elseif ($packet['iq']['#']['query'][0]['#']['password'])
            {
                return 
$this->_sendauth_plaintext();
            }
            
// dude, you're ****ed
            
{
                
$this->AddToLog("ERROR: SendAuth() #2 - No auth method available!");
                return 
FALSE;
            }
        }
        else
        {
            
// no result returned
            
$this->AddToLog("ERROR: SendAuth() #1");
            return 
FALSE;
        }
    }



    function 
AccountRegistration($reg_email = NULL, $reg_name = NULL)
    {
        
$packet = $this->SendIq($this->server, 'get', 'reg_01', 'jabber:iq:register');

        if (
$packet)
        {
            
$key = $this->GetInfoFromIqKey($packet);    // just in case a key was passed back from the server
            
unset($packet);

            
$payload = "<username>{$this->username}</username>
                        <password>
{$this->password}</password>
                        <email>
$reg_email</email>
                        <name>
$reg_name</name>\n";

            
$payload .= ($key) ? "<key>$key</key>\n" : '';

            
$packet = $this->SendIq($this->server, 'set', "reg_01", "jabber:iq:register", $payload);

            if (
$this->GetInfoFromIqType($packet) == 'result')
            {
                if (isset(
$packet['iq']['#']['query'][0]['#']['registered'][0]['#']))
                {
                    
$return_code = 1;
                }
                else
                {
                    
$return_code = 2;
                }

                if (
$this->resource)
                {
                    
$this->jid = "{$this->username}@{$this->server}/{$this->resource}";
                }
                else
                {
                    
$this->jid = "{$this->username}@{$this->server}";
                }

            }
            elseif (
$this->GetInfoFromIqType($packet) == 'error' && isset($packet['iq']['#']['error'][0]['#']))
            {
                
// "conflict" error, i.e. already registered
                
if ($packet['iq']['#']['error'][0]['@']['code'] == '409')
                {
                    
$return_code = 1;
                }
                else
                {
                    
$return_code = "Error " . $packet['iq']['#']['error'][0]['@']['code'] . ": " . $packet['iq']['#']['error'][0]['#'];
                }
            }

            return 
$return_code;

        }
        else
        {
            return 
3;
        }
    }



    function 
SendPacket($xml)
    {
        
$xml = trim($xml);

        if (
$this->CONNECTOR->WriteToSocket($xml))
        {
            
$this->AddToLog("SEND: $xml");
            return 
TRUE;
        }
        else
        {
            
$this->AddToLog('ERROR: SendPacket() #1');
            return 
FALSE;
        }
    }



    function 
Listen()
    {
        unset(
$incoming);

        while (
$line = $this->CONNECTOR->ReadFromSocket(4096))
        {
            
$incoming .= $line;
        }

        
$incoming = trim($incoming);

        if (
$incoming != "")
        {
            
$this->AddToLog("RECV: $incoming");
        }

        if (
$incoming != "")
        {
            
$temp = $this->_split_incoming($incoming);

            for (
$a = 0; $a < count($temp); $a++)
            {
                
$this->packet_queue[] = $this->xmlize($temp[$a]);
            }
        }

        return 
TRUE;
    }



    function 
StripJID($jid = NULL)
    {
        
preg_match("/(.*)\/(.*)/Ui", $jid, $temp);
        return (
$temp[1] != "") ? $temp[1] : $jid;
    }



    function 
SendMessage($to, $type = "normal", $id = NULL, $content = NULL, $payload = NULL)
    {
        if (
$to && is_array($content))
        {
            if (!
$id)
            {
                
$id = $type . "_" . time();
            }

            
$content = $this->_array_htmlspecialchars($content);

            
$xml = "<message to='$to' type='$type' id='$id'>\n";

            if (
$content['subject'])
            {
                
$xml .= "<subject>" . $content['subject'] . "</subject>\n";
            }

            if (
$content['thread'])
            {
                
$xml .= "<thread>" . $content['thread'] . "</thread>\n";
            }

            
$xml .= "<body>" . $content['body'] . "</body>\n";
            
$xml .= $payload;
            
$xml .= "</message>\n";


            if (
$this->SendPacket($xml))
            {
                return 
TRUE;
            }
            else
            {
                
$this->AddToLog("ERROR: SendMessage() #1");
                return 
FALSE;
            }
        }
        else
        {
            
$this->AddToLog("ERROR: SendMessage() #2");
            return 
FALSE;
        }
    }



    function 
SendPresence($type = NULL, $to = NULL, $status = NULL, $show = NULL, $priority = NULL)
    {
        
$xml = "<presence";
        
$xml .= ($to) ? " to='$to'" : '';
        
$xml .= ($type) ? " type='$type'" : '';
        
$xml .= ($status || $show || $priority) ? ">\n" : " />\n";

        
$xml .= ($status) ? "    <status>$status</status>\n" : '';
        
$xml .= ($show) ? "    <show>$show</show>\n" : '';
        
$xml .= ($priority) ? "    <priority>$priority</priority>\n" : '';

        
$xml .= ($status || $show || $priority) ? "</presence>\n" : '';

        if (
$this->SendPacket($xml))
        {
            return 
TRUE;
        }
        else
        {
            
$this->AddToLog("ERROR: SendPresence() #1");
            return 
FALSE;
        }
    }



    function 
SendError($to, $id = NULL, $error_number, $error_message = NULL)
    {
        
$xml = "<iq type='error' to='$to'";
        
$xml .= ($id) ? " id='$id'" : '';
        
$xml .= ">\n";
        
$xml .= "    <error code='$error_number'>";
        
$xml .= ($error_message) ? $error_message : $this->error_codes[$error_number];
        
$xml .= "</error>\n";
        
$xml .= "</iq>";

        
$this->SendPacket($xml);
    }



    function 
RosterUpdate()
    {
        
$roster_request_id = "roster_" . time();

        
$incoming_array = $this->SendIq(NULL, 'get', $roster_request_id, "jabber:iq:roster");

        if (
is_array($incoming_array))
        {
            if (
$incoming_array['iq']['@']['type'] == 'result'
                
&& $incoming_array['iq']['@']['id'] == $roster_request_id
                
&& $incoming_array['iq']['#']['query']['0']['@']['xmlns'] == "jabber:iq:roster")
            {
                
$number_of_contacts = count($incoming_array['iq']['#']['query'][0]['#']['item']);
                
$this->roster = array();

                for (
$a = 0; $a < $number_of_contacts; $a++)
                {
                    
$this->roster[$a] = array(    "jid"            => strtolower($incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['jid']),
                                                
"name"            => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['name'],
                                                
"subscription"    => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['subscription'],
                                                
"group"            => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['#']['group'][0]['#']
                                            );
                }

                return 
TRUE;
            }
            else
            {
                
$this->AddToLog("ERROR: RosterUpdate() #1");
                return 
FALSE;
            }
        }
        else
        {
            
$this->AddToLog("ERROR: RosterUpdate() #2");
            return 
FALSE;
        }
    }



    function 
RosterAddUser($jid = NULL, $id = NULL, $name = NULL)
    {
        
$id = ($id) ? $id : "adduser_" . time();

        if (
$jid)
        {
            
$payload = "        <item jid='$jid'";
            
$payload .= ($name) ? " name='" . htmlspecialchars($name) . "'" : '';
            
$payload .= "/>\n";

            
$packet = $this->SendIq(NULL, 'set', $id, "jabber:iq:roster", $payload);

            if (
$this->GetInfoFromIqType($packet) == 'result')
            {
                
$this->RosterUpdate();
                return 
TRUE;
            }
            else
            {
                
$this->AddToLog("ERROR: RosterAddUser() #2");
                return 
FALSE;
            }
        }
        else
        {
            
$this->AddToLog("ERROR: RosterAddUser() #1");
            return 
FALSE;
        }
    }



    function 
RosterRemoveUser($jid = NULL, $id = NULL)
    {
        
$id = ($id) ? $id : 'deluser_' . time();

        if (
$jid && $id)
        {
            
$packet = $this->SendIq(NULL, 'set', $id, "jabber:iq:roster", "<item jid='$jid' subscription='remove'/>");

            if (
$this->GetInfoFromIqType($packet) == 'result')
            {
                
$this->RosterUpdate();
                return 
TRUE;
            }
            else
            {
                
$this->AddToLog("ERROR: RosterRemoveUser() #2");
                return 
FALSE;
            }
        }
        else
        {
            
$this->AddToLog("ERROR: RosterRemoveUser() #1");
            return 
FALSE;
        }
    }



    function 
RosterExistsJID($jid = NULL)
    {
        if (
$jid)
        {
            if (
$this->roster)
            {
                for (
$a = 0; $a < count($this->roster); $a++)
                {
                    if (
$this->roster[$a]['jid'] == strtolower($jid))
                    {
                        return 
$a;
                    }
                }
            }
            else
            {
                
$this->AddToLog("ERROR: RosterExistsJID() #2");
                return 
FALSE;
            }
        }
        else
        {
            
$this->AddToLog("ERROR: RosterExistsJID() #1");
            return 
FALSE;
        }
    }



    function 
GetFirstFromQueue()
    {
        return 
array_shift($this->packet_queue);
    }



    function 
GetFromQueueById($packet_type, $id)
    {
        
$found_message = FALSE;

        foreach (
$this->packet_queue as $key => $value)
        {
            if (
$value[$packet_type]['@']['id'] == $id)
            {
                
$found_message = $value;
                unset(
$this->packet_queue[$key]);

                break;
            }
        }

        return (
is_array($found_message)) ? $found_message : FALSE;
    }



    function 
CallHandler($packet = NULL)
    {
        
$packet_type    = $this->_get_packet_type($packet);

        if (
$packet_type == "message")
        {
            
$type        = $packet['message']['@']['type'];
            
$type        = ($type != "") ? $type : "normal";
            
$funcmeth    = "Handler_message_$type";
        }
        elseif (
$packet_type == "iq")
        {
            
$namespace    = $packet['iq']['#']['query'][0]['@']['xmlns'];
            
$namespace    = str_replace(":", "_", $namespace);
            
$funcmeth    = "Handler_iq_$namespace";
        }
        elseif (
$packet_type == "presence")
        {
            
$type        = $packet['presence']['@']['type'];
            
$type        = ($type != "") ? $type : "available";
            
$funcmeth    = "Handler_presence_$type";
        }


        if (
$funcmeth != '')
        {
            if (
function_exists($funcmeth))
            {
                
call_user_func($funcmeth, $packet);
            }
            elseif (
method_exists($this, $funcmeth))
            {
                
call_user_func(array(&$this, $funcmeth), $packet);
            }
            else
            {
                
$this->Handler_NOT_IMPLEMENTED($packet);
                
$this->AddToLog("ERROR: CallHandler() #1 - neither method nor function $funcmeth() available");
            }
        }
    }



    function 
CruiseControl($seconds = -1)
    {
        
$count = 0;

        while (
$count != $seconds)
        {
            
$this->Listen();

            do {
                
$packet = $this->GetFirstFromQueue();

                if (
$packet) {
                    
$this->CallHandler($packet);
                }

            } while (
count($this->packet_queue) > 1);

            
$count += 0.25;
            
usleep(250000);
            
            if (
$this->last_ping_time != date('H:i'))
            {
                
// Modified by Nathan Fritz
                
if ($this->returned_keep_alive == FALSE)
                {
                    
$this->connected = FALSE;
                    
$this->AddToLog('EVENT: Disconnected');
                }

                
$this->returned_keep_alive = FALSE;
                
$this->keep_alive_id = 'keep_alive_' . time();
                
$this->SendPacket("<iq id='{$this->keep_alive_id}'/>", 'CruiseControl');
                
// **

                
$this->last_ping_time = date("H:i");
            }
        }

        return 
TRUE;
    }



    function 
SubscriptionAcceptRequest($to = NULL)
    {
        return (
$to) ? $this->SendPresence("subscribed", $to) : FALSE;
    }



    function 
SubscriptionDenyRequest($to = NULL)
    {
        return (
$to) ? $this->SendPresence("unsubscribed", $to) : FALSE;
    }



    function 
Subscribe($to = NULL)
    {
        return (
$to) ? $this->SendPresence("subscribe", $to) : FALSE;
    }



    function 
Unsubscribe($to = NULL)
    {
        return (
$to) ? $this->SendPresence("unsubscribe", $to) : FALSE;
    }



    function 
SendIq($to = NULL, $type = 'get', $id = NULL, $xmlns = NULL, $payload = NULL, $from = NULL)
    {
        if (!
preg_match("/^(get|set|result|error)$/", $type))
        {
            unset(
$type);

            
$this->AddToLog("ERROR: SendIq() #2 - type must be 'get', 'set', 'result' or 'error'");
            return 
FALSE;
        }
        elseif (
$id && $xmlns)
        {
            
$xml = "<iq type='$type' id='$id'";
            
$xml .= ($to) ? " to='$to'" : '';
            
$xml .= ($from) ? " from='$from'" : '';
            
$xml .= ">
                        <query xmlns='
$xmlns'>
                            
$payload
                        </query>
                    </iq>"
;

            
$this->SendPacket($xml);
            
sleep($this->iq_sleep_timer);
            
$this->Listen();

            return (
preg_match("/^(get|set)$/", $type)) ? $this->GetFromQueueById("iq", $id) : TRUE;
        }
        else
        {
            
$this->AddToLog("ERROR: SendIq() #1 - to, id and xmlns are mandatory");
            return 
FALSE;
        }
    }



    
// get the transport registration fields
    // method written by Steve Blinch, http://www.blitzaffe.com 
    
function TransportRegistrationDetails($transport)
    {
        
$this->txnid++;
        
$packet = $this->SendIq($transport, 'get', "reg_{$this->txnid}", "jabber:iq:register", NULL, $this->jid);

        if (
$packet)
        {
            
$res = array();

            foreach (
$packet['iq']['#']['query'][0]['#'] as $element => $data)
            {
                if (
$element != 'instructions' && $element != 'key')
                {
                    
$res[] = $element;
                }
            }

            return 
$res;
        }
        else
        {
            return 
3;
        }
    }
    


    
// register with the transport
    // method written by Steve Blinch, http://www.blitzaffe.com 
    
function TransportRegistration($transport, $details)
    {
        
$this->txnid++;
        
$packet = $this->SendIq($transport, 'get', "reg_{$this->txnid}", "jabber:iq:register", NULL, $this->jid);

        if (
$packet)
        {
            
$key = $this->GetInfoFromIqKey($packet);    // just in case a key was passed back from the server
            
unset($packet);
        
            
$payload = ($key) ? "<key>$key</key>\n" : '';
            foreach (
$details as $element => $value)
            {
                
$payload .= "<$element>$value</$element>\n";
            }
        
            
$packet = $this->SendIq($transport, 'set', "reg_{$this->txnid}", "jabber:iq:register", $payload);
        
            if (
$this->GetInfoFromIqType($packet) == 'result')
            {
                if (isset(
$packet['iq']['#']['query'][0]['#']['registered'][0]['#']))
                {
                    
$return_code = 1;
                }
                else
                {
                    
$return_code = 2;
                }
            }
            elseif (
$this->GetInfoFromIqType($packet) == 'error')
            {
                if (isset(
$packet['iq']['#']['error'][0]['#']))
                {
                    
$return_code = "Error " . $packet['iq']['#']['error'][0]['@']['code'] . ": " . $packet['iq']['#']['error'][0]['#'];
                    
$this->AddToLog('ERROR: TransportRegistration()');
                }
            }

            return 
$return_code;
        }
        else
        {
            return 
3;
        }
    }



    function 
GetvCard($jid = NULL, $id = NULL)
    {
        if (!
$id)
        {
            
$id = "vCard_" . md5(time() . $_SERVER['REMOTE_ADDR']);
        }

        if (
$jid)
        {
            
$xml = "<iq type='get' to='$jid' id='$id'>
                        <vCard xmlns='vcard-temp'/>
                    </iq>"
;

            
$this->SendPacket($xml);
            
sleep($this->iq_sleep_timer);
            
$this->Listen();

            return 
$this->GetFromQueueById("iq", $id);
        }
        else
        {
            
$this->AddToLog("ERROR: GetvCard() #1 - to and id are mandatory");
            return 
FALSE;
        }
    }



    function 
PrintLog()
    {
        if (
$this->enable_logging)
        {
            if (
$this->log_filehandler)
            {
                echo 
"<h2>Logging enabled, logged events have been written to the file {$this->log_filename}.</h2>\n";
            }
            else
            {
                echo 
"<h2>Logging enabled, logged events below:</h2>\n";
                echo 
"<pre>\n";
                echo (
count($this->log_array) > 0) ? implode("\n\n\n", $this->log_array) : "No logged events.";
                echo 
"</pre>\n";
            }
        }
    }



    
// ======================================================================
    // private methods
    // ======================================================================



    
function _sendauth_0k($zerok_token, $zerok_sequence)
    {
        
// initial hash of password
        
$zerok_hash = mhash(MHASH_SHA1, $this->password);
        
$zerok_hash = bin2hex($zerok_hash);

        
// sequence 0: hash of hashed-password and token
        
$zerok_hash = mhash(MHASH_SHA1, $zerok_hash . $zerok_token);
        
$zerok_hash = bin2hex($zerok_hash);

        
// repeat as often as needed
        
for ($a = 0; $a < $zerok_sequence; $a++)
        {
            
$zerok_hash = mhash(MHASH_SHA1, $zerok_hash);
            
$zerok_hash = bin2hex($zerok_hash);
        }

        
$payload = "<username>{$this->username}</username>
                    <hash>
$zerok_hash</hash>
                    <resource>
{$this->resource}</resource>";

        
$packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload);

        
// was a result returned?
        
if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
        {
            return 
TRUE;
        }
        else
        {
            
$this->AddToLog("ERROR: _sendauth_0k() #1");
            return 
FALSE;
        }
    }



    function 
_sendauth_digest()
    {
        
$payload = "<username>{$this->username}</username>
                    <resource>
{$this->resource}</resource>
                    <digest>" 
. bin2hex(mhash(MHASH_SHA1, $this->stream_id . $this->password)) . "</digest>";

        
$packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload);

        
// was a result returned?
        
if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
        {
            return 
TRUE;
        }
        else
        {
            
$this->AddToLog("ERROR: _sendauth_digest() #1");
            return 
FALSE;
        }
    }



    function 
_sendauth_plaintext()
    {
        
$payload = "<username>{$this->username}</username>
                    <password>
{$this->password}</password>
                    <resource>
{$this->resource}</resource>";

        
$packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload);

        
// was a result returned?
        
if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
        {
            return 
TRUE;
        }
        else
        {
            
$this->AddToLog("ERROR: _sendauth_plaintext() #1");
            return 
FALSE;
        }
    }



    function 
_listen_incoming()
    {
        unset(
$incoming);

        while (
$line = $this->CONNECTOR->ReadFromSocket(4096))
        {
            
$incoming .= $line;
        }

        
$incoming = trim($incoming);

        if (
$incoming != "")
        {
            
$this->AddToLog("RECV: $incoming");
        }

        return 
$this->xmlize($incoming);
    }



    function 
_check_connected()
    {
        
$incoming_array = $this->_listen_incoming();

        if (
is_array($incoming_array))
        {
            if (
$incoming_array["stream:stream"]['@']['from'] == $this->server
                
&& $incoming_array["stream:stream"]['@']['xmlns'] == "jabber:client"
                
&& $incoming_array["stream:stream"]['@']["xmlns:stream"] == "http://etherx.jabber.org/streams")
            {
                
$this->stream_id = $incoming_array["stream:stream"]['@']['id'];

                return 
TRUE;
            }
            else
            {
                
$this->AddToLog("ERROR: _check_connected() #1");
                return 
FALSE;
            }
        }
        else
        {
            
$this->AddToLog("ERROR: _check_connected() #2");
            return 
FALSE;
        }
    }



    function 
_get_packet_type($packet = NULL)
    {
        if (
is_array($packet))
        {
            
reset($packet);
            
$packet_type = key($packet);
        }

        return (
$packet_type) ? $packet_type : FALSE;
    }



    function 
_split_incoming($incoming)
    {
        
$temp = preg_split("/<(message|iq|presence|stream)/", $incoming, -1, PREG_SPLIT_DELIM_CAPTURE);
        
$array = array();

        for (
$a = 1; $a < count($temp); $a = $a + 2)
        {
            
$array[] = "<" . $temp[$a] . $temp[($a + 1)];
        }

        return 
$array;
    }



    function 
_create_logfile()
    {
        if (
$this->log_filename != '' && $this->enable_logging)
        {
            
$this->log_filehandler = fopen($this->log_filename, 'w');
        }
    }



    function 
AddToLog($string)
    {
        if (
$this->enable_logging)
        {
            if (
$this->log_filehandler)
            {
                
fwrite($this->log_filehandler, $string . "\n\n");
            }
            else
            {
                
$this->log_array[] = htmlspecialchars($string);
            }
        }
    }



    function 
_close_logfile()
    {
        if (
$this->log_filehandler)
        {
            
fclose($this->log_filehandler);
        }
    }



    
// _array_htmlspecialchars()
    // applies htmlspecialchars() to all values in an array

    
function _array_htmlspecialchars($array)
    {
        if (
is_array($array))
        {
            foreach (
$array as $k => $v)
            {
                if (
is_array($v))
                {
                    
$v = $this->_array_htmlspecialchars($v);
                }
                else
                {
                    
$v = htmlspecialchars($v);
                }
            }
        }

        return 
$array;
    }



    
// ======================================================================
    // <message/> parsers
    // ======================================================================



    
function GetInfoFromMessageFrom($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['message']['@']['from'] : FALSE;
    }



    function 
GetInfoFromMessageType($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['message']['@']['type'] : FALSE;
    }



    function 
GetInfoFromMessageId($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['message']['@']['id'] : FALSE;
    }



    function 
GetInfoFromMessageThread($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['message']['#']['thread'][0]['#'] : FALSE;
    }



    function 
GetInfoFromMessageSubject($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['message']['#']['subject'][0]['#'] : FALSE;
    }



    function 
GetInfoFromMessageBody($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['message']['#']['body'][0]['#'] : FALSE;
    }



    function 
GetInfoFromMessageError($packet = NULL)
    {
        
$error = preg_replace("/^\/$/", "", ($packet['message']['#']['error'][0]['@']['code'] . "/" . $packet['message']['#']['error'][0]['#']));
        return (
is_array($packet)) ? $error : FALSE;
    }



    
// ======================================================================
    // <iq/> parsers
    // ======================================================================



    
function GetInfoFromIqFrom($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['iq']['@']['from'] : FALSE;
    }



    function 
GetInfoFromIqType($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['iq']['@']['type'] : FALSE;
    }



    function 
GetInfoFromIqId($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['iq']['@']['id'] : FALSE;
    }



    function 
GetInfoFromIqKey($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['iq']['#']['query'][0]['#']['key'][0]['#'] : FALSE;
    }



    function 
GetInfoFromIqError($packet = NULL)
    {
        
$error = preg_replace("/^\/$/", "", ($packet['iq']['#']['error'][0]['@']['code'] . "/" . $packet['iq']['#']['error'][0]['#']));
        return (
is_array($packet)) ? $error : FALSE;
    }



    
// ======================================================================
    // <presence/> parsers
    // ======================================================================



    
function GetInfoFromPresenceFrom($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['presence']['@']['from'] : FALSE;
    }



    function 
GetInfoFromPresenceType($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['presence']['@']['type'] : FALSE;
    }



    function 
GetInfoFromPresenceStatus($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['presence']['#']['status'][0]['#'] : FALSE;
    }



    function 
GetInfoFromPresenceShow($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['presence']['#']['show'][0]['#'] : FALSE;
    }



    function 
GetInfoFromPresencePriority($packet = NULL)
    {
        return (
is_array($packet)) ? $packet['presence']['#']['priority'][0]['#'] : FALSE;
    }



    
// ======================================================================
    // <message/> handlers
    // ======================================================================



    
function Handler_message_normal($packet)
    {
        
$from = $packet['message']['@']['from'];
        
$this->AddToLog("EVENT: Message (type normal) from $from");
    }



    function 
Handler_message_chat($packet)
    {
        
$from = $packet['message']['@']['from'];
        
$this->AddToLog("EVENT: Message (type chat) from $from");
    }



    function 
Handler_message_groupchat($packet)
    {
        
$from = $packet['message']['@']['from'];
        
$this->AddToLog("EVENT: Message (type groupchat) from $from");
    }



    function 
Handler_message_headline($packet)
    {
        
$from = $packet['message']['@']['from'];
        
$this->AddToLog("EVENT: Message (type headline) from $from");
    }



    function 
Handler_message_error($packet)
    {
        
$from = $packet['message']['@']['from'];
        
$this->AddToLog("EVENT: Message (type error) from $from");
    }



    
// ======================================================================
    // <iq/> handlers
    // ======================================================================



    // application version updates
    
function Handler_iq_jabber_iq_autoupdate($packet)
    {
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: jabber:iq:autoupdate from $from");
    }



    
// interactive server component properties
    
function Handler_iq_jabber_iq_agent($packet)
    {
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: jabber:iq:agent from $from");
    }



    
// method to query interactive server components
    
function Handler_iq_jabber_iq_agents($packet)
    {
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: jabber:iq:agents from $from");
    }



    
// simple client authentication
    
function Handler_iq_jabber_iq_auth($packet)
    {
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: jabber:iq:auth from $from");
    }



    
// out of band data
    
function Handler_iq_jabber_iq_oob($packet)
    {
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: jabber:iq:oob from $from");
    }



    
// method to store private data on the server
    
function Handler_iq_jabber_iq_private($packet)
    {
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: jabber:iq:private from $from");
    }



    
// method for interactive registration
    
function Handler_iq_jabber_iq_register($packet)
    {
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: jabber:iq:register from $from");
    }



    
// client roster management
    
function Handler_iq_jabber_iq_roster($packet)
    {
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: jabber:iq:roster from $from");
    }



    
// method for searching a user database
    
function Handler_iq_jabber_iq_search($packet)
    {
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: jabber:iq:search from $from");
    }



    
// method for requesting the current time
    
function Handler_iq_jabber_iq_time($packet)
    {
        
$type    = $this->GetInfoFromIqType($packet);
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);
        
$id        = ($id != "") ? $id : "time_" . time();

        if (
$type == 'get')
        {
            
$payload = "<utc>" . gmdate("Ydm\TH:i:s") . "</utc>
                        <tz>" 
. date("T") . "</tz>
                        <display>" 
. date("Y/d/m h:i:s A") . "</display>";

            
$this->SendIq($from, 'result', $id, "jabber:iq:time", $payload);
        }

        
$this->AddToLog("EVENT: jabber:iq:time (type $type) from $from");
    }



    
// method for requesting version
    
function Handler_iq_jabber_iq_version($packet)
    {
        
$type    = $this->GetInfoFromIqType($packet);
        
$from    = $this->GetInfoFromIqFrom($packet);
        
$id        = $this->GetInfoFromIqId($packet);
        
$id        = ($id != "") ? $id : "version_" . time();

        if (
$type == 'get')
        {
            
$payload = "<name>{$this->iq_version_name}</name>
                        <os>
{$this->iq_version_os}</os>
                        <version>
{$this->iq_version_version}</version>";

            
$this->SendIq($from, 'result', $id, "jabber:iq:version", $payload);
        }

        
$this->AddToLog("EVENT: jabber:iq:version (type $type) from $from");
    }



    
// keepalive method, added by Nathan Fritz
    
function Handler_iq_($packet)
    {
        if (
$this->keep_alive_id == $this->GetInfoFromIqId($packet))
        {
            
$this->returned_keep_alive = TRUE;
            
$this->AddToLog('EVENT: Keep-Alive returned, connection alive.');
        }
    }
    
    
    
    
// ======================================================================
    // <presence/> handlers
    // ======================================================================



    
function Handler_presence_available($packet)
    {
        
$from = $this->GetInfoFromPresenceFrom($packet);

        
$show_status = $this->GetInfoFromPresenceStatus($packet) . " / " . $this->GetInfoFromPresenceShow($packet);
        
$show_status = ($show_status != " / ") ? " ($addendum)" : '';

        
$this->AddToLog("EVENT: Presence (type: available) - $from is available $show_status");
    }



    function 
Handler_presence_unavailable($packet)
    {
        
$from = $this->GetInfoFromPresenceFrom($packet);

        
$show_status = $this->GetInfoFromPresenceStatus($packet) . " / " . $this->GetInfoFromPresenceShow($packet);
        
$show_status = ($show_status != " / ") ? " ($addendum)" : '';

        
$this->AddToLog("EVENT: Presence (type: unavailable) - $from is unavailable $show_status");
    }



    function 
Handler_presence_subscribe($packet)
    {
        
$from = $this->GetInfoFromPresenceFrom($packet);
        
$this->SubscriptionAcceptRequest($from);
        
$this->RosterUpdate();

        
$this->log_array[] = "<b>Presence:</b> (type: subscribe) - Subscription request from $from, was added to \$this->subscription_queue, roster updated";
    }



    function 
Handler_presence_subscribed($packet)
    {
        
$from = $this->GetInfoFromPresenceFrom($packet);
        
$this->RosterUpdate();

        
$this->AddToLog("EVENT: Presence (type: subscribed) - Subscription allowed by $from, roster updated");
    }



    function 
Handler_presence_unsubscribe($packet)
    {
        
$from = $this->GetInfoFromPresenceFrom($packet);
        
$this->SendPresence("unsubscribed", $from);
        
$this->RosterUpdate();

        
$this->AddToLog("EVENT: Presence (type: unsubscribe) - Request to unsubscribe from $from, was automatically approved, roster updated");
    }



    function 
Handler_presence_unsubscribed($packet)
    {
        
$from = $this->GetInfoFromPresenceFrom($packet);
        
$this->RosterUpdate();

        
$this->AddToLog("EVENT: Presence (type: unsubscribed) - Unsubscribed from $from's presence");
    }



    
// Added By Nathan Fritz
    
function Handler_presence_error($packet)
    {
        
$from = $this->GetInfoFromPresenceFrom($packet);
        
$this->AddToLog("EVENT: Presence (type: error) - Error in $from's presence");
    }
    
    
    
    
// ======================================================================
    // Generic handlers
    // ======================================================================



    // Generic handler for unsupported requests
    
function Handler_NOT_IMPLEMENTED($packet)
    {
        
$packet_type    = $this->_get_packet_type($packet);
        
$from            = call_user_func(array(&$this, "GetInfoFrom" . ucfirst($packet_type) . "From"), $packet);
        
$id                = call_user_func(array(&$this, "GetInfoFrom" . ucfirst($packet_type) . "Id"), $packet);

        
$this->SendError($from, $id, 501);
        
$this->AddToLog("EVENT: Unrecognized <$packet_type/> from $from");
    }



    
// ======================================================================
    // Third party code
    // m@d pr0ps to the coders ;)
    // ======================================================================



    // xmlize()
    // (c) Hans Anderson / http://www.hansanderson.com/php/xml/

    
function xmlize($data)
    {
        
$vals = $index = $array = array();
        
$parser = xml_parser_create();
        
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
        
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
        
xml_parse_into_struct($parser, $data, $vals, $index);
        
xml_parser_free($parser);

        
$i = 0;

        
$tagname = $vals[$i]['tag'];
        
$array[$tagname]['@'] = $vals[$i]['attributes'];
        
$array[$tagname]['#'] = $this->_xml_depth($vals, $i);

        return 
$array;
    }



    
// _xml_depth()
    // (c) Hans Anderson / http://www.hansanderson.com/php/xml/

    
function _xml_depth($vals, &$i)
    {
        
$children = array();

        if (
$vals[$i]['value'])
        {
            
array_push($children, trim($vals[$i]['value']));
        }

        while (++
$i < count($vals))
        {
            switch (
$vals[$i]['type'])
            {
                case 
'cdata':
                    
array_push($children, trim($vals[$i]['value']));
                     break;

                case 
'complete':
                    
$tagname = $vals[$i]['tag'];
                    
$size = sizeof($children[$tagname]);
                    
$children[$tagname][$size]['#'] = trim($vals[$i]['value']);
                    if (
$vals[$i]['attributes'])
                    {
                        
$children[$tagname][$size]['@'] = $vals[$i]['attributes'];
                    }
                    break;

                case 
'open':
                    
$tagname = $vals[$i]['tag'];
                    
$size = sizeof($children[$tagname]);
                    if (
$vals[$i]['attributes'])
                    {
                        
$children[$tagname][$size]['@'] = $vals[$i]['attributes'];
                        
$children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i);
                    }
                    else
                    {
                        
$children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i);
                    }
                    break;

                case 
'close':
                    return 
$children;
                    break;
            }
        }

        return 
$children;
    }



    
// Traver***MLize()
    // (c) acebone@f2s.com, a HUGE help!

    
function Traver***MLize($array, $arrName = "array", $level = 0)
    {
        if (
$level == 0)
        {
            echo 
"<pre>";
        }

        while (list(
$key, $val) = @each($array))
        {
            if (
is_array($val))
            {
                
$this->Traver***MLize($val, $arrName . "[" . $key . "]", $level + 1);
            }
            else
            {
                echo 
'$' . $arrName . '[' . $key . '] = "' . $val . "\"\n";
            }
        }

        if (
$level == 0)
        {
            echo 
"</pre>";
        }
    }
}



class 
MakeXML extends Jabber
{
    var 
$nodes;


    function 
MakeXML()
    {
        
$nodes = array();
    }



    function 
AddPacketDetails($string, $value = NULL)
    {
        if (
preg_match("/\(([0-9]*)\)$/i", $string))
        {
            
$string .= "/[\"#\"]";
        }

        
$temp = @explode("/", $string);

        for (
$a = 0; $a < count($temp); $a++)
        {
            
$temp[$a] = preg_replace("/^[@]{1}([a-z0-9_]*)$/i", "[\"@\"][\"\\1\"]", $temp[$a]);
            
$temp[$a] = preg_replace("/^([a-z0-9_]*)\(([0-9]*)\)$/i", "[\"\\1\"][\\2]", $temp[$a]);
            
$temp[$a] = preg_replace("/^([a-z0-9_]*)$/i", "[\"\\1\"]", $temp[$a]);
        }

        
$node = implode("", $temp);

        
// Yeahyeahyeah, I know it's ugly... get over it. ;)
        
echo "\$this->nodes$node = \"" . htmlspecialchars($value) . "\";<br/>";
        eval(
"\$this->nodes$node = \"" . htmlspecialchars($value) . "\";");
    }



    function 
BuildPacket($array = NULL)
    {

        if (!
$array)
        {
            
$array = $this->nodes;
        }

        if (
is_array($array))
        {
            
array_multisort($array, SORT_ASC, SORT_STRING);

            foreach (
$array as $key => $value)
            {
                if (
is_array($value) && $key == "@")
                {
                    foreach (
$value as $subkey => $subvalue)
                    {
                        
$subvalue = htmlspecialchars($subvalue);
                        
$text .= " $subkey='$subvalue'";
                    }

                    
$text .= ">\n";

                }
                elseif (
$key == "#")
                {
                    
$text .= htmlspecialchars($value);
                }
                elseif (
is_array($value))
                {
                    for (
$a = 0; $a < count($value); $a++)
                    {
                        
$text .= "<$key";

                        if (!
$this->_preg_grep_keys("/^@/", $value[$a]))
                        {
                            
$text .= ">";
                        }

                        
$text .= $this->BuildPacket($value[$a]);

                        
$text .= "</$key>\n";
                    }
                }
                else
                {
                    
$value = htmlspecialchars($value);
                    
$text .= "<$key>$value</$key>\n";
                }
            }

            return 
$text;
        }
    }



    function 
_preg_grep_keys($pattern, $array)
    {
        while (list(
$key, $val) = each($array))
        {
            if (
preg_match($pattern, $key))
            {
                
$newarray[$key] = $val;
            }
        }
        return (
is_array($newarray)) ? $newarray : FALSE;
    }
}



class 
CJP_StandardConnector
{
    var 
$active_socket;

    function 
OpenSocket($server, $port)
    {
        if (
$this->active_socket = fsockopen($server, $port))
        {
            
socket_set_blocking($this->active_socket, 0);
            
socket_set_timeout($this->active_socket, 31536000);

            return 
TRUE;
        }
        else
        {
            return 
FALSE;
        }
    }



    function 
CloseSocket()
    {
        return 
fclose($this->active_socket);
    }



    function 
WriteToSocket($data)
    {
        return 
fwrite($this->active_socket, $data);
    }



    function 
ReadFromSocket($chunksize)
    {
        
set_magic_quotes_runtime(0);
        
$buffer = fread($this->active_socket, $chunksize);
        
set_magic_quotes_runtime(get_magic_quotes_gpc());

        return 
$buffer;
    }
}



?>
بعد هم این یه فایل مثال هستش که طریقه استفاده رو یادتون می ده. به هر نامی دوست دارید ذخیره کنید.
این روش رو خودم در مورد یاهو تست کردم 100 در 100 جواب داد.
بقیه رو هم اگه شما زحمت بکشد که ممنون میشم به همه بگید.

کد PHP:
کد PHP:
<?php

require("class.jabber.php");

$JABBER = new Jabber;

$JABBER->server   = "njs.netlab.cz";
$JABBER->port     = 5222;
$JABBER->username = "";    //jabber username
$JABBER->password = "";   //jabber password
$JABBER->resource = "ClassJabberPHP";

$transport = "yahoo.netlab.cz";

$JABBER->enable_logging = TRUE;
$JABBER->log_filename = "log.txt";


$JABBER->Connect() or die("Couldn't connect!");
$JABBER->SendAuth() or die("Couldn't authenticate!");

$details["username"] = "";     //yahoo username
$details["password"] = "";     //yahoo password
$receiver_id = "";                //receiver yahoo id

$receiver = "$receiver_id@$transport";

$status = $JABBER->TransportRegistration($transport,$details);

$JABBER->SendMessage("$receiver", "normal", NULL, array("body" => "Hi. Are you there ?"));

$JABBER->Disconnect();

?>