Для получения полного доступа
зарегистрируйтесь.

Roman Zhuravlev    6   5 513


Видимо, пользователь решил о себе ничего не говорить.
  • Зарегистрирован 5 лет назад
Профиль завершён на 0 %
0 %

Пусковой скрипт для запуска cron-команд в docker-контенере. Проверяет cron-выражение и запускает команду. Умеет выход по сигналам SIGTERM и SIGINT. В отличии от стандартного cron-демона следующую команду не запустит пока не выполнит предыдущую. Удобно использовать при разработке c docker-compose. В логах докера показывает что запускалось, когда, и с каким результатом.

#!/usr/bin/env php
<?php
/**
 * Скрипт для запуска команды по расписанию, для замены cron-а в сети из docker-контейнеров.
 *
 * Пример команды, которая будет запускаться каждую минуту:
 * docker/php/cron.php "* * * * *" php yii rate/update
 *
 * Зависимости:
 * "mtdowling/cron-expression": "~1.2.0"
 *
 * @author Roman Zhuravlev <zhuravljov@gmail.com>
 */

require(__DIR__ . '/../../vendor/autoload.php');

// Params
$params = $_SERVER['argv'];
array_shift($params);
$expression = array_shift($params);
$command = implode(' ', $params);
$schedule = \Cron\CronExpression::factory($expression);

// Signal handler
$signal = 0;
$signalHandler = function ($sigNum) use (&$signal) {
    $signal = $sigNum;
};
pcntl_signal(SIGTERM, $signalHandler);
pcntl_signal(SIGINT, $signalHandler);

// Loop
printLog('Cron started');
while (true) {
    sleep(60 - time() % 60);
    pcntl_signal_dispatch();
    if ($signal) {
        printLog("Cron stopped by signal $signal");
        exit(0);
    }
    if (!$schedule->isDue()) {
        continue;
    }
    $startedAt = microtime(true);
    printLog("[started] command: $command", $startedAt);
    passthru($command, $exitCode);
    $finishedAt = microtime(true);
    $totalTime = sprintf('%01.3f', $finishedAt - $startedAt);
    printLog("[finished] duration $totalTime s, exit code $exitCode");
    if ($exitCode) {
        exit($exitCode);
    }
}

function printLog($message, $time = null)
{
    echo date('Y-m-d H:i:s', $time ?? time()), ' ' , $message, PHP_EOL;
}
/**
 * Вычисляет расстояние между двумя точками по gps-координатам
 *
 * @param float $lat1
 * @param float $lng1
 * @param float $lat2
 * @param float $lng2
 * @return int расстояние в метрах
 */
function distance($lat1, $lng1, $lat2, $lng2)
{
    $cosLat1 = cos($lat1 * M_PI / 180);
    $cosLat2 = cos($lat2 * M_PI / 180);
    $sinLat1 = sin($lat1 * M_PI / 180);
    $sinLat2 = sin($lat2 * M_PI / 180);
    $cosDelta = cos(($lng2 - $lng1) * M_PI / 180);
    $sinDelta = sin(($lng2 - $lng1) * M_PI / 180);

    $dist = atan2(
        sqrt(
            pow($cosLat2 * $sinDelta, 2) +
            pow($cosLat1 * $sinLat2 - $sinLat1 * $cosLat2 * $cosDelta, 2)
        ),
        $sinLat1 * $sinLat2 + $cosLat1 * $cosLat2 * $cosDelta
    ) * 6372795;

    return round($dist);
}

assert(distance(77.1539, -139.398, -77.1804, -139.55) == 17166029);
assert(distance(77.1539, 120.398, 77.1804, 129.55) == 225883);
assert(distance(77.1539, -120.398, 77.1804, 129.55) == 2332669);

Недавно разгребал легаси код доставшийся по наследству. Нашел реализацию тайпхинтинга скаляров для PHP5. Долго думал...

Если свести код к минимуму, то:

set_error_handler(function(){});
 
function foo(int $bar)
{
	var_dump($bar);
}
 
foo(1); // int(1)