Roman Zhuravlev 7 6 397
Видимо, пользователь решил о себе ничего не говорить.
Пусковой скрипт для запуска 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)