Skip to content

Instantly share code, notes, and snippets.

@patelnwd
Last active August 12, 2020 05:41
Show Gist options
  • Save patelnwd/d6ae0fcb3a0855499d78708721e1f25a to your computer and use it in GitHub Desktop.
Save patelnwd/d6ae0fcb3a0855499d78708721e1f25a to your computer and use it in GitHub Desktop.
A PHP background processing class to execure an process in background.
<?php
/**
* -------------------------------------------------------------------------------------
* Written on - 13-June-2018 14:30:00
* Wtirren By - Mukesh Patel (http://patelworld.in) | (http://facebook.com/patelnwd)
* =====================================================================================
*
* This Class is written for Process Background Process.
* Most of cases we saw we need to execute some process without user interaction,
* why not do it in background.
* -----------------------------------------------------------------------------------------
* USES:
* $backProcessObj = new BackgroundProcess($arg1, $arg2, $arg3, $arg4);
* $request_json['request'] = [
* [
* 'type' => 'GET',
* 'url' => BASE_URL . 'reports/triggerBackgroundMail',
* 'function_data' => []
* ]
* ];
* $backProcessObj->request(json_encode($request_json))->run();
* -------------------------------------------------------------------------------------
*/
class BackgroundProcess{
private $pid;
private $pid_file;
private $ext;
private $req_path;
private $php_exe_path;
private $port;
protected $time_out;
protected $request;
/**
* Constructor need to atleast first two parameter
* @param [type] $php_exe_path [path where your server php.exe exist]
* @param [type] $request_path [path where your background process file is going to prepare, same file will be read from background process handler]
* @param [type] $port [pass server port ignore it, if it is 80]
* @param string $ext [background Process file extension]
*/
public function __construct($php_exe_path = null, $request_path = null, $port = null, $ext = '.pid.json'){
$this->ext = (false === preg_match('/(\.[a-z]+)$/i', $ext)) ? '.pid' : $ext;
$this->req_path = $this->validateReqPath($request_path);
$this->php_exe_path = $php_exe_path;
$this->port = (null === $port && !is_numeric($port)) ? $this->getPort() : $port;
$this->time_out = 30;
$this->request = [];
}
private function validateReqPath($request_path = null){
if($request_path !== null)
return $request_path;
}
private function log_error($exception_obj){
// TODO: write exteption message in a common file
}
/**
* Get created process id
* @return [type] [description]
*/
public function getPid(){
return $this->pid;
}
/**
* Get Process file with full path
* @return [type] [description]
*/
public function getPidFile(){
return $this->pid_file;
}
/**
* logic to create pid
* @return [type] [description]
*/
private function createPid(){
$this->pid = str_replace(["."," "],'_', microtime(true));
// $this->pid = str_replace(["."," "],'_', date('d_m_y'));
return $this->pid;
}
/**
* set server Port no
*/
public function setPort(){
return $_SERVER['SERVER_PORT'];
}
/**
* get port number
* @return [type] [description]
*/
public function getPort(){
return $this->setPort();
}
/**
* get process file extention name
* @return [type] [description]
*/
public function getExt(){
return $this->ext;
}
/**
* Get Requested process Json
* @return [type] [description]
*/
public function getRequestJson(){
return file_get_contents($this->pid_file);
}
/**
* Get requested Process JSON as array
* @return [type] [description]
*/
public function getRequest(){
return json_decode($this->getRequestJson(), true);
}
/**
* Delete Background Process
* @return [type] [description]
*/
private function deleteRequest(){
if(file_exists($this->pid_file)){
unlink($this->pid_file);
}
return $this;
}
/**
* Create/Write Main request file
* @param [type] $request_json [description]
* @return [type] [description]
*/
public function request($request_json = null){
try{
$this->pid_file = $this->req_path.$this->createPid().$this->ext;
if(file_exists($this->pid_file)){
unlink($this->pid_file);
}
if(!is_dir($this->req_path)){
mkdir($this->req_path, 0777, true);
}
file_put_contents($this->pid_file, $request_json, FILE_APPEND | LOCK_EX);
return $this;
}
catch(Exception $e){
return null;
}
}
/**
* Background Process Execution
* @param [type] $type [description]
* @param [type] $url [description]
* @param [type] $params [description]
* @return [type] [description]
*/
private function exec($type = null, $url = null, $params = null){
$errno = null;
$errstr = null;
$parts=parse_url($url);
// GET
if($type === 'GET'){
$parts['path'] .= isset($parts['query']) ? '?'. $parts['query'] : '';
$request = "GET ".$parts['path']." HTTP/1.1\r\n";
$request .= "Host: ". $parts['host'] ."\r\n";
$request .= "Connection: Close\r\n\r\n";
}
// POST
if($type === 'POST'){
foreach ($params as $key => &$val) {
if (is_array($val)) $val = implode(',', $val);
$post_params[] = $key.'='.urlencode($val);
}
$post_string = implode('&', $post_params);
$request = "POST ".$parts['path']." HTTP/1.1\r\n";
$request.= "Host: ".$parts['host']."\r\n";
$request.= "Content-Type: application/x-www-form-urlencoded\r\n";
$request.= "Content-Length: ".strlen($post_string)."\r\n";
}
$request.= "Connection: Close\r\n\r\n";
$fp = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : $this->port, $errno, $errstr, $this->time_out);
if (!$fp) {
return null;
}
fputs($fp,$request);
fclose($fp);
return true;
}
/**
* Get background process as array and process it one by one on behalf of GET/POST
* @return [type] [description]
*/
public function run(){
if(isset($this->pid_file)){
if(file_exists($this->pid_file)){
$request_json = $this->getRequest();
foreach($request_json['request'] as $req){
if($req['type'] === 'POST' || $req['type'] === 'GET'){
$req_params = (!isset($req['params'])) ? null : $req['params'];
$req['status'] = $this->exec($req['type'], $req['url'].'?f='.$this->pid_file, $req_params);
}
else{
$req['status'] = 'unknown request type';
}
$this->request[] = $req;
}
// $this->deleteRequest();
}
}
return $this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment