If the timeout fails, because the server remains completely silent, one may have to add stream_select() to make the timeout work. This may be much more efficient that a non-blocking reading operation.
<?php
stream_set_timeout($c, $timeout);
$data = '';
$stR = array($this->smtp_conn);
$stW = null;
while (is_resource($c) && !feof($c)) {
if (!stream_select($stR, $stW, $stW, $timeout)) {
trigger_error('Timeout');
break;
}
$str = fgets($c, 515);
$data.= $str;
// Handling of "traditional" timeout
$info = stream_get_meta_data($c);
if ($info['timed_out']) {
trigger_error('Timeout');
break;
}
}
?>
Background: We had issues with a SMTP server that was addresses unencrypted while expecting TLS encryption. The stream_set_timeout() alone did not work as expected and the script hung for an hour or more.