views:

315

answers:

1

I've been playing around with PHP Streams and have been experimenting by beginning to write the class shown here. The PHP docs are bit lean in this area to say the least.

I'm having a difficult time with getting my stream context to invoke the callback method specified. If I use a function like file_get_contents or fopen to connect to a socket the callback is invoked, but if I use stream_socket_client it does not.

I assume it should because I'm passing the context to stream_socket_client and if I use stream_socket_recvfrom I get the same string back from the socket as fgets would return.

Relevant PHP docs are linked at the end of the post.

class IMAP {

    // Connection Parameters
    private $host;
    private $port;
    private $timeout;

    // Credentials
    private $email;
    private $password;

    private $client;
    private $transcript;

    function __construct($connection, $credentials) {

     // Set Connection Settings
     $this->host = $connection['host'];
     $this->port = $connection['port'];
     $this->timeout = $connection['timeout'];

     // Set Credentials
     $this->email = $credentials['email'];
     $this->password = $credentials['password'];

     // Connect to the IMAP server
     $params = array('notification'=>array($this, 'getLine'));
     $ctx = stream_context_create();
     stream_context_set_params($ctx, $params);
     $this->client = stream_socket_client("tcp://$this->host:$this->port",$errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $ctx);
     stream_socket_sendto($this->client, "a001 NOOP\r\n");

    }

    function getLine($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {
     $args = func_get_args();
       var_dump($args);
    }
}

$connection =  array(
    'host' => 'somehost',
    'port' => 143,
    'timeout' => 10
);

$credentails = array(
    'email' => 'someemail',
    'password' => 'somepassword'
);

$imap = new IMAP($connection, $credentails);

?>

http://us3.php.net/manual/en/function.stream-context-set-params.php http://us3.php.net/manual/en/context.params.php

I found this somewhat related PHP bug report too, but it looks like the report was pointless:

http://bugs.php.net/bug.php?id=42387&edit=1

+1  A: 

Looks like this isn't supported by the socket streams as of php 5.3.0.

The only function I could find that calls the notifier function (in the C code) is php_stream_notification_notify in main/streams/streams.c. There are also some #defines

#define php_stream_notify_info
#define php_stream_notify_progress
#define php_stream_notify_progress_init
#define php_stream_notify_progress_increment
#define php_stream_notify_file_size
#define php_stream_notify_error

which boil down to a call to php_stream_notification_notify. The ftp wrapper e.g. calls

php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0);

in php_ftp_fopen_connect. Same with curl and the http wrapper. But there's no such call for stream_socket_client() or related functions. And the examples at http://php.net/function.stream-notification-callback don't work if you replace the protocol wrapper by a transport like tcp: (or even file:).

VolkerK
Thanks for the info. Do you think it would make sense for stream_socket_client() to trigger the callback? Maybe I'll file a bug report.
macinjosh
I don't know enough about the notifiers to give you a definitive answer. Maybe they are meant (for some reason) only for the protocol wrappers. But at least php_stream_notify_info and php_stream_notify_error would be nice.
VolkerK