Skip to content

Instantly share code, notes, and snippets.

@TechZi
Created July 7, 2010 16:55
Show Gist options
  • Save TechZi/466944 to your computer and use it in GitHub Desktop.
Save TechZi/466944 to your computer and use it in GitHub Desktop.
<?php
class Socket {
private $_host = 'www.google.com.hk';
private $_port = '80';
private $_socket = null;
private $_timeout = 30;
private $_method = '';
private $_protocol = 'tcp';
public function __construct() {
}
public function connect() {
//可以用stream_context_create的参数构造http请求
$context = stream_context_create();
$host = $this->_protocol.'://'.$this->_host;
$this->_socket = stream_socket_client($host.':'.$this->_port,
$errno,
$errstr,
$this->_timeout,
STREAM_CLIENT_CONNECT || STREAM_CLIENT_PERSISTENT,
$context
);
if (!$this->_socket) {
echo 'connect '.$this->_socket.' error: '.$errno.' '.$errstr;
return ;
}
if (!stream_set_timeout($this->_socket, (int)$this->_timeout)) {
echo 'Unable to set the connection timeout';
return ;
}
}
public function write($method = 'GET', $headers = array(), $body = '') {
$httpVersion = '1.1';
//此处需要加上对url的处理
$path = '/';
$request = "{$method} {$path} HTTP/{$httpVersion}\r\n";
foreach ($headers as $key => $value) {
if (is_string($key)) {
$header = ucfirst($key).": {$value}";
} else {
$header = $value;
}
$request .= "{$header}\r\n";
}
if (!empty($body)) {
$request .= "\r\n{$body}";
}
//var_dump($request);return ;
if (!fwrite($this->_socket, $request)) {
echo 'Error writing request to server';
return ;
}
return $request;
}
public function read() {
$response = '';
while (($line = fgets($this->_socket)) !== false && !feof($this->_socket)) {
if (strpos($line, 'HTTP') !== false) {
$response .= $line;
if (rtrim($line) === '') {
break;
}
}
}
//首先处理http状态码
$httpStatusCode = $this->_extractHttpStatusCode($response);
//1**用于表示临时响应并需要请求者执行操作才能继续的状态码
if ($httpStatusCode == 100 || $httpStatusCode == 101) {
return $this->read();
}
}
private function _extractHttpStatusCode($response) {
$pattern = '/^HTTP\/[\d\.x]+ (\d+)/';
preg_match($pattren, $response, $matches);
if (isset($matches[1])) {
return (int) $matches[1];
} else {
return null;
}
}
private function _extractHttpResponseHeaders($response) {
$headers = array();
$lastHeader = null;
$parts = preg_grep('/(?:\r?\n){2}/m', $response, 2);
if ($parts[0]) {
return $headers;
}
$lines = explode("\r\n", $parts[0]);
foreach ($lines as $line) {
$line = trim($line, "\r\n");
if (empty($line)) {
break;
}
if (preg_match("/^([\w-]+):\s+(.+)/", $line, $matches)) {
$headerKey = strtolower($matcher[1]);
$headerValue = $matcher[0];
if (isset($headers[$headerKey])) {
if (is_array($headers[$headerKey])) {
$headers[$headerKey] = array($headerValue);
}
$headers[$headerKey][] = $headerValue;
} else {
$headers[$headerKey] = $headerValue;
}
$lastHeader = $headerKey;
} elseif (preg_match('/^\s+(.+)$/', $line, $matches) && $lastHeader !== null) {
if (is_array($headers[$lastHeader])) {
end($headers[$lastHeader]);
$lastHeaderKey = key($headers[$lastHeader]);
$headers[$lastHeader][$lastHeaderKey] .= $matches[1];
} else {
$headers[$lastHeader] .= $matches[1];
}
}
}
return $headers;
}
public function close() {
if (is_resource($this->_socket)) {
fclose($this->_socket);
}
$this->_socket = null;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment