<?php 
 
namespace JLaso\ToolsLib; 
 
 
/** 
 * Class Starter 
 * 
 * based on the article https://segment.com/blog/how-to-make-async-requests-in-php/ of Calvin French-Owen 
 */ 
 
class Starter extends CommonAbstract 
{ 
    const SUCCESS = 1; 
    const STARTED_ALREADY = 2; 
    const ERROR = 2; 
    const ERROR_ID = 3; 
 
    /** @var  String */ 
    protected $url; 
    /** @var  String */ 
    protected $host; 
    /** @var  int */ 
    protected $port; 
    /** @var  String */ 
    protected $lastError; 
 
    /** 
     * Starter constructor. 
     * @param string $url 
     * @param string $task 
     * @param bool $debug 
     * @throws Exception 
     * @internal param mixed $data 
     */ 
    public function __construct($url, $task, $debug = false) 
    { 
        parent::__construct($task, $debug); 
        if (strpos($url, "http://") !== 0) { 
            $url = "http://" . $_SERVER["SERVER_NAME"] . "/" . $url; 
        } 
        if (!preg_match("~(?<host>http[s]?:\/\/[^\/|^:]+)(?<port>:\d+)?(?<url>\/.*)$~i", $url, $matches)) { 
            throw new Exception("The url passed doesn't match http://host:port/url"); 
        }; 
        $this->host = isset($matches["host"]) ? $matches["host"] : "http://localhost"; 
        $this->url = isset($matches["url"]) ? $matches["url"] : "/"; 
        $this->port = isset($matches["port"]) && !empty($matches["port"]) ? $matches["port"] : (stripos($this->host, "https") === 0 ? "443" : "80"); 
        $this->host = preg_replace("~^http[s]?://~", "", $this->host); 
    } 
 
    /** 
     * invoke the task though an http request in order to end quickly and return the control 
     * to the requester, then call periodically to status script in order to know how is going 
     * 
     * @param array $data payload to the request 
     * @return integer 
     */ 
    public function invoke($data = array()) 
    { 
        if (!isset($data['id'])) { 
            return self::ERROR_ID; 
        } 
        $data["_task"] = $this->task; 
        $unique = ((strstr($this->url, "?") === false) ? "?" : "&") . "_nc=" . date("U"); 
 
        $payload = http_build_query($data); 
        $fp = fsockopen($this->host, $this->port, $errno, $errstr, 30); 
 
        if (!$fp) { 
 
            $this->lastError = "$errstr ($errno)"; 
 
            return self::ERROR; 
 
        } else { 
 
            $out  = "POST " . $this->url . $unique . " HTTP/1.1\r\n"; 
            $out .= "Host: {$this->host}\r\n"; 
            $out .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
            $out .= "Content-Length: " . strlen($payload) . "\r\n"; 
            $out .= "Connection: Close\r\n"; 
            $out .= "\r\n"; 
            fwrite($fp, $out); 
            fwrite($fp, $payload); 
            fclose($fp); 
 
        } 
 
        return self::SUCCESS; 
    } 
 
    /** 
     * @return String 
     */ 
    public function getLastError() 
    { 
        return $this->lastError; 
    } 
 
 
 
}
 
 |