Skip to content

Instantly share code, notes, and snippets.

@artoodetoo
Created February 12, 2016 17:33
Show Gist options
  • Select an option

  • Save artoodetoo/3f1b1dc8965b744cf15a to your computer and use it in GitHub Desktop.

Select an option

Save artoodetoo/3f1b1dc8965b744cf15a to your computer and use it in GitHub Desktop.

Revisions

  1. artoodetoo created this gist Feb 12, 2016.
    128 changes: 128 additions & 0 deletions loop.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,128 @@
    <?php

    class FileHelper
    {
    public static function openAndLock($filename)
    {
    $fh = fopen($filename, 'r+');
    if (!$fh || !flock($fh, LOCK_EX)) {
    return false;
    }
    return $fh;
    }

    public static function readAll($fh)
    {
    if ($fh) {
    fseek($fh, 0);
    return stream_get_contents($fh);
    }
    }

    public static function overwrite($fh, $content)
    {
    if ($fh) {
    fseek($fh, 0);
    ftruncate($fh, 0);
    fwrite($fh, $content);
    }
    }

    public static function closeAndUnlock($fh)
    {
    if ($fh) {
    flock($fh, LOCK_UN);
    fclose($fh);
    }
    }
    }

    class HttpHelper
    {
    public static function callNoWait($url)
    {
    $parts = parse_url($url);
    $fp = fsockopen(
    $parts['host'],
    isset($parts['port']) ? $parts['port'] : (
    isset($parts['scheme']) && $parts['scheme'] == 'https'
    ? '443'
    : '80'
    ),
    $errno,
    $errstr,
    30
    );
    $uri = $parts['path'];
    if (isset($parts['query'])) {
    $uri .= '?'.$parts['query'];
    }
    $out = "GET {$uri} HTTP/1.1\r\n"
    . "Host: {$parts['host']}\r\n"
    . "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    // did not read anything
    fclose($fp);
    }

    public static function getUri($path = null)
    {
    if (!isset($path)) {
    $path = $_SERVER['REQUEST_URI'];
    }
    $scheme = !empty($_SERVER['HTTPS']) && 'off' !== strtolower($_SERVER['HTTPS'])
    ? 'https'
    : 'http';
    $port = $_SERVER['SERVER_PORT'];
    $host = ('http' === $scheme && $port === '80') ||
    ('https' === $scheme && $port === '443')
    ? $_SERVER['HTTP_HOST']
    : $_SERVER['HTTP_HOST'].':'.$port;
    return $scheme.'://'.$host.$path;
    }
    }

    $countFilename = __DIR__.'/loop.lock';
    $action = isset($_GET['action']) ? $_GET['action'] : '';

    switch ($action) {
    case 'stop':
    for ($i = 100; $i > 0; --$i) {
    if (!file_exists($countFilename) || @unlink($countFilename)) {
    exit('Stopped');
    }
    usleep(2);
    }
    exit('Cannot stop');
    case 'start':
    touch($countFilename);
    default:
    if (!file_exists($countFilename)) {
    exit('Run prohibited');
    }
    if (($fh = FileHelper::openAndLock($countFilename)) === false) {
    exit('Busy');
    }
    $count = intval(FileHelper::readAll($fh)) + 1;
    }

    register_shutdown_function(
    function($fh, $count) {
    // write counter and unlock
    FileHelper::overwrite($fh, (string)$count);
    FileHelper::closeAndUnlock($fh);
    // call itself without get-parameters
    $path = $_SERVER['REQUEST_URI'];
    if (($p = strpos($path, '?')) !== false) {
    $path = substr($path, 0, $p);
    }
    $uri = HttpHelper::getUri($path);
    HttpHelper::callNoWait($uri);
    },
    $fh,
    $count
    );

    // ... do something ...
    echo 'Count: '.$count;
    usleep(100);