<?php
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE);
ini_set('display_errors', 1);
$hosts = array("www.baidu.com");
$timeout = 15;
$status = array();
$sockets = array();
foreach ($hosts as $id => $host) {
$s = stream_socket_client("tcp://$host:80", $errno, $errstr, $timeout,
STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
// $s = fsockopen($host, 80);
if ($s) {
//fwrite($s, "GET /s?wd=stream_select HTTP/1.0\r\nHost: $host\r\nAccept: */*\r\n\r\n");
$sockets[$id] = $s;
$status[$id] = "in progress";
} else {
$status[$id] = "failed, $errno $errstr";
}
}
/* Now, wait for the results to come back in */
while (count($sockets)) {
$read = $write = $sockets;
$e=null;
//不论在php5.6还是php7.4版本,测试发现只触发$write事件,$read返回一直为空,这个需要从stream_select源码去研究原因。
//目前今天还没有时间去看源码。
$n = stream_select($read, $write, $e,0);
if ($n > 0) {
/* writeable sockets can accept an HTTP request */
foreach ($write as $w) {
if(!is_resource($w))continue;
$id = array_search($w, $sockets);
$host = $hosts[$id];
$path = "/";
$req .= "GET $path HTTP/1.1\r\n";
$req .= "Host: $host\r\n";
$req .= "\r\n";
fwrite($w, $req);
$status[$id] = "waiting for response";
}
/* readable sockets either have data for us, or are failed connection attempts */
foreach ($read as $key=>$r) {
$id = array_search($r, $sockets);
$data = fread($r, 8192);
if (strlen($data) == 0) {
if ($status[$id] == "in progress") {
$status[$id] = "failed to connect";
}
fclose($r);
unset($sockets[$id]);
} else {
$status[$id] .= $data;
}
}
} else {
/* timed out waiting; assume that all hosts associated
* with $sockets are faulty */
foreach ($sockets as $id => $s) {
$status[$id] = "timed out " . $status[$id];
}
break;
}
}
foreach ($hosts as $id => $host) {
echo "Host: $host";
echo "Status: " . $status[$id] . "nn";
}