*/ class Status { private $address = ''; private $port = 0; private $protocol = ''; public $state = null; public $history = []; public const OK = 2; public const ERROR = 1; public const FAIL = 0; public function __construct(string $address, int $port, string $protocol = '', bool $populate = true, bool $history = true) { $this->address = $address; $this->port = $port; $this->protocol = $protocol; if ($populate) { $this->populate($history); } } public function populate(bool $history = true): void { $this->history = DB::table('status_history') ->where('history_name', $this->address) ->where('history_port', $this->port) ->where('history_protocol', $this->protocol) ->orderBy('history_date', 'desc') ->limit($history ? 10 : 1) ->get(); $this->state = isset($this->history[0]) ? intval($this->history[0]->history_state) : null; } public function check(): int { $this->state = static::FAIL; try { $sock = Net::detectIPVersion( $this->address[0] === '[' && $this->address[strlen($this->address) - 1] === ']' ? substr($this->address, 1, -1) : $this->address ) !== 0 || dns_get_record($this->address, DNS_A | DNS_A6 | DNS_MX) ? fsockopen($this->address, $this->port, $errno, $errstr, 1) : false; } catch (\ErrorException $e) { $sock = false; } if ($sock !== false) { fclose($sock); $this->state = static::OK; if ($this->protocol === 'http' || $this->protocol === 'https') { $header = strstr( Net::request("{$this->protocol}://{$this->address}:{$this->port}/", 'head', null, 1), "\r\n", true ); if ($header !== false && strtolower(substr($header, 0, 4)) == 'http') { [$protocol, $response, $text] = explode(' ', $header, 3); if ($response >= 400 && $response < 500) { $this->state = static::ERROR; } if ($response >= 500 && $response < 600) { $this->state = static::FAIL; } } } } return $this->state; } public function save(): void { DB::table('status_history') ->insert([ 'history_name' => $this->address, 'history_port' => $this->port, 'history_protocol' => $this->protocol, 'history_state' => $this->state ]); $this->history = array_merge(DB::table('status_history') ->where('history_name', $this->address) ->where('history_port', $this->port) ->where('history_protocol', $this->protocol) ->orderBy('history_date', 'desc') ->limit(1) ->get(), $this->history); } }