Сниппеты:
Подраздел:
Языки:

Roman Zhuravlev
  • Репутация: 2
  • Сниппеты: 2
  • Ревизии: 0
/**
 * Вычисляет расстояние между двумя точками по 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);
Gravatar image
c3037
  • Репутация: 42
  • Сниппеты: 11
  • Ревизии: 0
kill -15 `ps -ef | grep {mask} | grep -v grep | awk '{print $2}'`

kill -15 `pgrep {mask}  | awk '{print $1}'`

pgrep {mask} | xargs kill

pkill -f {mask}
Gravatar image
Tutik Alexsandr
  • Репутация: 1
  • Сниппеты: 6
  • Ревизии: 0

Функция вырезает все что находит от between_start до between_end и возвращает в виде результат. пригодится для ненормализованных данных в виде строки

CREATE FUNCTION `find_between_text`(`raw_data` TEXT, `between_start` TEXT, `between_end` TEXT)
	RETURNS text CHARSET utf8
	LANGUAGE SQL
	NOT DETERMINISTIC
	CONTAINS SQL
	SQL SECURITY DEFINER
	COMMENT ''
BEGIN
  RETURN SUBSTRING( raw_data, 
	 LOCATE(between_start, raw_data) + CHAR_LENGTH(between_start),
    LOCATE(between_end, raw_data, LOCATE(between_start, raw_data) + CHAR_LENGTH(between_start))-(LOCATE(between_start, raw_data) + CHAR_LENGTH(between_start))
	);
END

Пример использования

select find_between_text(raw_data_str,'<tag>','</tag>') as found_text from table_test
Gravatar image
wartur
  • Репутация: 1
  • Сниппеты: 1
  • Ревизии: 0

Очень часто возникает ситуация, когда требуется несколько раз дергать один и тот же метод, но хочется что бы объект этого метода оперативно кешровал данные у себя. Достичь этого можно например создав приватную переменную для кеширования.

А можно написать трейт и все будет работать так, же, но без шаблонного кода

/**
 * Кешер данных модели
 * Позволяет сократить количество шаблонного кода с добавлением приватных
 * переменых кеша
 */
trait ModelCacheTrait
{

    private $_cache = [];

    /**
     * Получить данные с кешированием
     * @param string $key ключ кеша
     * @param callable $callback коллбэк с кодом получения данных
     * @return mixed данные
     */
    protected function cachedGet($key, $callback)
    {
        // Через isset и null не получится!!! нужно знать есть ли ключ в массиве
        if (!array_key_exists($key, $this->_cache)) {
            $this->_cache[$key] = call_user_func($callback);
        }
        return $this->_cache[$key];
    }
}

// Использование
class BusinessModel
{
    use \app\ModelCacheTrait;

    public function makeRandomPrecurrentDate()
    {
        $currentTime = strtotime($this->makeCurrentDate());
// БИЗНЕС ЛОГИКА
    }

    public function makeCurrentDate()
    {
        return $this->cachedGet(__METHOD__, function(){
            $lastHalf = time(); // БИЗНЕС ЛОГИКА, возможно придется дергать БД, упростил...
            return date('c', $lastHalf);
        });
    }
}
samdark
  • Репутация: 294
  • Сниппеты: 55
  • Ревизии: 5
function isAssociativeArray($array)
{
    if (!is_array($array) || empty($array)) {
        return false;
    }
    
    return array_keys($array) !== range(0, count($array) - 1);
}
dfatt
  • Репутация: 206
  • Сниппеты: 40
  • Ревизии: 7
<?php
$twitterParams = [
    'hashtags' => 'yii',
    'original_referer' => 'http://yiiframework.ru/',
    'text' => 'Я участвую в yiiframework.ru: ',
    'url' => 'http://yiiframework.ru/',
];
?>

<a href="https://twitter.com/intent/tweet?<?= http_build_query($twitterParams) ?>" target="_blank" rel="noopener noreferrer">Tweet</a>

Я убрал echo, более чисто выглядит так.

samdark
  • Репутация: 294
  • Сниппеты: 55
  • Ревизии: 5
<?php
$facebookParams = array(
    'app_id' => 12345,
    'u' => 'http://yiiframework.ru/',
);
?>

<a href="https://www.facebook.com/sharer/sharer.php?<?php echo http_build_query($facebookParams) ?>" target="_blank" rel="noopener noreferrer">Facebook</a>
samdark
  • Репутация: 294
  • Сниппеты: 55
  • Ревизии: 5
<?php
$twitterParams = [
    'hashtags' => 'yii',
    'original_referer' => 'http://yiiframework.ru/',
    'text' => 'Я участвую в yiiframework.ru: ',
    'url' => 'http://yiiframework.ru/',
];
?>

<a href="https://twitter.com/intent/tweet?<?php echo http_build_query($twitterParams) ?>" target="_blank" rel="noopener noreferrer">Tweet</a>
Gravatar image
Tutik Alexsandr
  • Репутация: 1
  • Сниппеты: 6
  • Ревизии: 0

Я надеюсь, это кому-то пригодиться =)

Класс Base62 упаковывает число в хеш засчет 62 символьного словаря, на самом деле его можно назвать смело base64 строка символов содержит уже 64 символа (чем больше словарь тем больше число можно упаковать, главное не упереться в максимальное число на php )

MongoIdShort использует base62 для распарсинга id на составляющие и упаковывает их по отдельности в мини хеши Данный код можно улучшить, есть получится убрать и воссоздать $identifier на тойже машине в теории это выполнимо.

$identifier = substr(md5(gethostname()), 0, 3);

но у меня не получилось, мало времени было, мои новаторские идеи были отклонены печалька и боль.

Ну собственно код с моего gits

<?php
class  Base62  {
    const CHARS_SYMBOLS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
    /**
     * @param $id
     * @return string
     */
    public static function encode($id){
        $l = strlen(self::CHARS_SYMBOLS);
        $chars = self::CHARS_SYMBOLS;
        $hash='';
        while($id > 0) {
            $i = fmod($id,$l);
            $hash= ($chars[intval($i)]) . $hash;
            $id=floor($id/$l);
        }
        return $hash;
    }
    /**
     * @param $code
     * @return string
     */
    public static function decode($code)
    {
        $l = strlen(self::CHARS_SYMBOLS);
        $id=0;
        $arr = array_flip(str_split(self::CHARS_SYMBOLS));
        for($i=0,$len = strlen($code); $i < $len; ++$i) {
            $id += $arr[$code[$i]] * pow($l, $len-$i-1);
        }
        return (string)$id;
    }
}

class MongoIdShort
{
    /*
        a 4-byte timestamp,
        a 3-byte machine identifier,
        a 2-byte process id, and
        a 3-byte counter.
     */
    public static function encode($id)
    {
        $timestamp = hexdec(substr($id,0,8));
        $identifier = hexdec(substr($id,8,6));
        $pid = hexdec(substr($id,14,4));
        $counter = hexdec(substr($id,18,6));
        $hashsource = Base62::encode($timestamp) .   Base62::encode($identifier)  . '\\' . Base62::encode($pid) . '\\' . Base62::encode($counter);
        return $hashsource;
    }

    public static function decode($id)
    {
        $part = explode('\\',$id);
        $timestamp =  Base62::decode(substr($part[0],0,6));
        $identifier = Base62::decode(substr($part[0],6));
        $pid = Base62::decode($part[1]);
        $counter =  Base62::decode($part[2]);
        $len_identifier = strlen($identifier)-6;
        $len_pid = strlen($pid)-4;
        $len_counter = strlen($counter)-6;
        return $hash = dechex($timestamp)
            . ($len_identifier < 0 ? str_repeat('0',$len_identifier*-1) : '')
            . dechex($identifier)
            . ($len_pid < 0 ? str_repeat('0',$len_pid*-1) : '')
            . dechex($pid)
            . ($len_counter < 0 ? str_repeat('0',$len_counter*-1) : '')
            . dechex($counter);
    }
}

Тесты как же без них

$ids  = [
    '5824736fcaec5460bbfdc489',
    '58357bf59d1f9d381a000029',
    '58357bf59d1f9d381a000030',
    '58357bf59d1f9d381a005031',
    '58357bf59d1f9d381a200033',
    '58357bf59d1f9d381a001034',
    strval( new MongoId()),
    strval( new MongoId()),
    strval( new MongoId()),
    strval( new MongoId()),
    strval( new MongoId()),
    strval( new MongoId()),
    strval( new MongoId()),
    strval( new MongoId()),
    strval( new MongoId()),
];
foreach($ids as $id){
    echo "mongoId_source {$id} \n";
    $encodeId = MongoIdShort::encode($id);
    $decodeId = MongoIdShort::decode($encodeId);
    $isTrue = $id == $decodeId;
    echo "$id\n$encodeId\n{$isTrue}\n$decodeId\n========\n\n";
}
swimmwatch
  • Репутация: 5
  • Сниппеты: 2
  • Ревизии: 0
/*  Created: 24.11.2016
    Author: Dmitry Vasiliev
    Text editor: Sublime Text
    GitHub: swimmwatch  */

/**
 * @class Timer
 * @classdesc Wrapper for setTimeout.
 * @author Dmitry Vasiliev <mushckin.igor2011@yandex.ru>
 */
export default class Timer {
  private callback: Function;
  private beginnigTime: number;
  private duration: number;
  private timer: number;
  private running: boolean;

  constructor() {
    this.callback = null;
    this.beginnigTime = null;
    this.duration = null;
    this.timer = null;
    this.running = false;
  }

  /**
   * Start the timer
   * @param duration - Duration of timer
   * @param callback - Callback function
   * @example
   * ``` typescript
   * Timer.start(3000, () => console.log('Timer is done!'));
   * // if call method start again then timer will be reset.
   * Timer.start(5000, () => console.log('Timer will not done!'));
   * // ...
   * Timer.start(5000, () => console.log("It's call will reset timer."));
   * ```
   */
  start(duration: number, callback: Function) {
    if (this.running) this.reset();
    this.callback = callback || function(){};
    this.duration = duration < 0 ? -duration : duration;
    this.timer = setTimeout(() => {
      this.callback();
      this.reset();
    }, this.duration);
    this.running = true;
    this.beginnigTime = +(new Date());
  }

  /**
   * Reset the timer
   */
  reset() {
    clearTimeout(this.timer);
    this.running = false;
    this.callback = null;
    this.duration = null;
  }

  /**
   * Pause the timer
   * @param delay - Delay on pause
   */
  pause(delay: number = undefined) {
    if (!this.running) return;
    if (!delay) {
      this.duration -= +(new Date()) - this.beginnigTime;
      clearTimeout(this.timer);
      this.running = false;
    } else {
      this.duration -= +(new Date()) - this.beginnigTime;
      this.pause();
      setTimeout(() => {
        this.continue();
      }, delay);
    }
  }

  /**
   * Continue the timer
   */
  continue() {
    if (this.running) return;
    else {
      this.timer = setTimeout(() => {
        this.callback();
        this.reset();
      }, this.duration);
      this.running = true;
      this.beginnigTime = +(new Date());
    }
  }
}