#19421 [Com]: fget* doesn't work when socket resource is stored in class variable

From: Date: Fri, 05 Mar 2004 19:14:10 +0000
Subject: #19421 [Com]: fget* doesn't work when socket resource is stored in class variable
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-55964@lists.php.net to get a copy of this message
 ID:               19421
 Comment by:       cosas at minovela dot com
 Reported By:      taco at osisoft dot nl
 Status:           Bogus
 Bug Type:         Class/Object related
 Operating System: Red Hat 7.1
 PHP Version:      4.2.2
 New Comment:

newer versions of php has a lot of problems with sockets...


Previous Comments:
------------------------------------------------------------------------

[2002-09-19 15:40:32] taco at osisoft dot nl

I deliberatly commented that line. The code should fetch the welcome
messages, but when I uncomment it, the stalling will occure!

I know the POP3 protocol, that's not the issue here ;-). Issue is that
the fgets stalls when using it in a class structure or/and using class
variables.

I've got it all working now, but without using a class. After I
stripped of the TPOP3Mail class it worked immediatly.

------------------------------------------------------------------------

[2002-09-19 04:54:21] wez@php.net

Try uncommenting the "Catching the servers welcome messages" line of
code...
This is not a support forum; you should really read the
POP3 protocol spec.


------------------------------------------------------------------------

[2002-09-19 01:37:50] taco at osisoft dot nl

I can run this example (using my own pop3 account). Unfortunatly you
will see something like this:
>> USER xxxx
<< +OK Welcome to this POP3 server
>> PASS xxxx
<< +OK User is welcome
You have .... message(s)

As you see the returning messages is always one message behind. With
the commented line I wanted to get the welcome message after
connection, before authentication. If I therefor uncomment that line,
it will stall.

I have tried several things, like using a local variable instead of a
class variable. That works better, as the title shows, but it still
works buggy. often it's alright, but sometimes it keeps stalling.

Currently I use this functionality without a class and than it works
fine.

<?

class TPOP3Mail
{
	var $server;
	var $port;
	var $user;
	var $password;
	var $socket;
	var $error;
	
	function TPOP3Mail($server, $port, $user, $pwd)
	{
		$this->server = $server;
		$this->port = $port;
		$this->user = $user;
		$this->password = $pwd;
	}
	
	function Connect()
	{
		$this->socket = fsockopen($this->server, $this->port, $errno,
$errstr, 3);
    if($this->socket <= 0)
		{
			$this->error = "Could not connect to $this->server on port
$this->port. Connection Error $errno. Reason: $errstr";
			return 0;
		}
		$this->error = "";
//		fgets($this->socket, 1024); //Catching server's welcome messages
		print ">>: USER $this->user<BR>\n";
		fwrite($this->socket, "USER $this->user\r\n");	
		$result = fgets($this->socket, 1024); 
		print "<<: $result<BR>\n";
		if (substr($result, 0, 3) == "+OK")
		{
			print ">>: PASS xxxx<BR>\n";
			fwrite ($this->socket, "PASS $this->password\r\n");
			$result = fgets($this->socket, 1024);
			print "<<: $result<BR>\n";
			if (substr($result, 0, 3) != "+OK")
				$this->error = "Error while logging on ($result)";
		}		
		else $this->error = "Error while logging on ($result)";
		if ($this->error != "") return 0;		
		return $this->socket;
	}
	
	function ShowMail($nr)
	{
		fwrite ($this->socket, "RETR $nr\r\n");
		$response = fgets ($this->socket, 1024);
		$i = 4;
		$s = ""; //stores byte size of the message
		while ($response[$i] != " ") $s .= $response[$i++];
		$response = fread($this->socket, $s);
		fgets ($this->socket, 1024);
		return $response;		
	}
	
	function MailCount()
	{
		fwrite ($this->socket, "STAT\r\n");
		$response = fgets ($this->socket, 1024);
		$i = 4;
		$s = "";
		while ($response[$i] != " ") $s .= $response[$i++];
		return $s;
	}
	
}

//Please use an pop3 account in the following line.
$webmail = new TPOP3Mail("server", "110", "user", "pwd");
if (!$webmail->Connect()) print $webmail->error;
print "You have " . $webmail->MailCount() . "
message(s).<BR><BR>\n";
print nl2br($webmail->ShowMail(1));	

?>

------------------------------------------------------------------------

[2002-09-18 19:21:58] sniper@php.net

Please provide a short but complete example script which shows what
you're trying to do.


------------------------------------------------------------------------

[2002-09-15 16:35:22] taco at osisoft dot nl

I made a class which connects to the POP3 server at localhost. I used
fsockopen to connect to the server. When I use a local variable
("$socket") then it works allright. When I store the resource in a
class variable ($this->socket) the script will stall on fget*.

Work around for me: I want to use the socket resource in other member
functions. After the connection is initialized a class variable
references to the local variable ($this->socket =& $socket). In the
member function I first must make a local variable and refer it to the
class variable ($socket =& $this->socket). I can't use $this->socket
directly.

So in short: I can't use a class variable with fwrite and fgets, but
instead I must use local variables.

(Hope may description was clear.)

Greetings from Holland
Taco Jan Osinga

------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=19421&edit=1


Thread (6 messages)

« previous php.bugs (#55964) next »