|
<?php |
|
class Background { |
|
// (A) CONSTRUCTOR - CONNECT TO DATABASE |
|
private $pdo = null; |
|
private $stmt = null; |
|
public $error = ""; |
|
function __construct () { |
|
$this->pdo = new PDO( |
|
"mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, |
|
DB_USER, DB_PASSWORD, [ |
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, |
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC |
|
]); |
|
} |
|
|
|
// (B) DESTRUCTOR - CLOSE DATABASE CONNECTION |
|
function __destruct () { |
|
if ($this->stmt!==null) { $this->stmt = null; } |
|
if ($this->pdo!==null) { $this->pdo = null; } |
|
} |
|
|
|
// (C) HELPER FUNCTION - EXECUTE SQL QUERY |
|
function query ($sql, $data=null) : void { |
|
$this->stmt = $this->pdo->prepare($sql); |
|
$this->stmt->execute($data); |
|
} |
|
|
|
// (D) RUN A SCRIPT IN BACKGROUND - TESTED ON WINDOWS ONLY |
|
function start ($uid, $script) { |
|
// (D1) CHECK IF USER ALREADY HAS A RUNNING PROCESS |
|
$this->query("SELECT * FROM `tasks` WHERE `user_id`=?", [$uid]); |
|
if (is_array($this->stmt->fetch())) { |
|
$this->error = "User already has a running process."; |
|
return false; |
|
} |
|
|
|
// (D2) RUN SCRIPT & GET PROCESS ID |
|
// start /B wmic process call create "PATH/PHP.EXE -f PATH/SCRIPT.PHP USER-ID | find ProcessId" |
|
$processID = 0; |
|
$fp = popen(sprintf('start /B wmic process call create "%s -f %s %u | find ProcessId"', PHP_PATH, $script, $uid), "r"); |
|
while (!feof($fp)) { |
|
$line = fread($fp, 1024); |
|
if (strpos($line, "ProcessId") !== false) { |
|
preg_match('/\d+/', $line, $processID); |
|
$processID = $processID[0]; |
|
} |
|
} |
|
pclose($fp); |
|
|
|
// (D3) REGISTER ENTRY & DONE |
|
$this->query("INSERT INTO `tasks` (`user_id`, `process_id`) VALUES (?,?)", [$uid, $processID]); |
|
return true; |
|
} |
|
|
|
// (E) BACKGROUND SCRIPT HAS ENDED |
|
function end ($uid) { |
|
$this->query("DELETE FROM `tasks` WHERE `user_id`=?", [$uid]); |
|
return true; |
|
} |
|
|
|
// (F) KILL TASK |
|
function kill ($uid) { |
|
// (F1) CHECK IF USER HAS PENDING TASK |
|
$this->query("SELECT * FROM `tasks` WHERE `user_id`=?", [$uid]); |
|
$task = $this->stmt->fetch(); |
|
if (!is_array($task)) { |
|
$this->error = "User does not have any pending tasks."; |
|
return false; |
|
} |
|
|
|
// (F2) WINDOWS KILL TASK & CLOSE ENTRY |
|
pclose(popen("taskkill /PID ".$task["process_id"]." /F", "r")); |
|
$this->end($uid); |
|
return true; |
|
} |
|
} |
|
|
|
// (G) SETTINGS - CHANGE TO YOUR OWN! |
|
define("DB_HOST", "localhost"); |
|
define("DB_NAME", "test"); |
|
define("DB_CHARSET", "utf8mb4"); |
|
define("DB_USER", "root"); |
|
define("DB_PASSWORD", ""); |
|
define("PHP_PATH", "c:/xampp/php/php.exe"); |
|
|
|
// (H) NEW BACKGROUND OBJECT |
|
$_BG = new Background(); |