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

Раздел:
Подраздел:
Языки:


Roman Zhuravlev
  • Репутация: 7
  • Сниппеты: 3
  • Ревизии: 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
wartur
  • Репутация: 2
  • Сниппеты: 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
  • Репутация: 349
  • Сниппеты: 57
  • Ревизии: 5
function isAssociativeArray($array)
{
    if (!is_array($array) || empty($array)) {
        return false;
    }
    
    return array_keys($array) !== range(0, count($array) - 1);
}
dfatt
  • Репутация: 260
  • Сниппеты: 53
  • Ревизии: 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
  • Репутация: 349
  • Сниппеты: 57
  • Ревизии: 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
  • Репутация: 349
  • Сниппеты: 57
  • Ревизии: 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
  • Репутация: 2
  • Сниппеты: 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";
}
Gravatar image
blacksmoke26
  • Репутация: 13
  • Сниппеты: 11
  • Ревизии: 0
/**
 * Check that given file is an image file.
 * @param string $filename The file path to be checked
 * @return bool TRUE when image file | FALSE when none
 */
function isImageFile ( string $filename ) {
	if ( !is_file ( $filename) || !is_readable ( $filename) ) {
		return false;
	} else if ( class_exists('\finfo') ) {
		$mime = (new \finfo(FILEINFO_MIME))->file ( $filename);
		return strpos((string)$mime, 'image') !== false;
	} else if ( function_exists('getimagesize') ) {
		$size = @getimagesize ( $filename);
		return !@is_array($size) ? false : true;
	} else if ( function_exists('exif_imagetype') && exif_imagetype ( $filename) === false ) {
		return false;
	} else if ( function_exists('mime_content_type') ) {
		$mime = @mime_content_type ($filename);
		return strpos((string)$mime, 'image') !== false;
	} else {
		return true;
	}
}

/************
 * EXAMPLE
 ***********/
// Can validate all sort of images
var_dump ( isImageFile('image.jpg') );

/***********
 * OUTPUT
 **********/
# (bool) true
Gravatar image
blacksmoke26
  • Репутация: 13
  • Сниппеты: 11
  • Ревизии: 0
/**
 * Create image file from base64 image data
 * @param string $filename Path to the file where to write the data.
 * @param string $data The base64 image data
 * @return bool True when created | False anyway
 */
function imgBase64ToFile ( string $filename, string $data ) {
	list(, $data) = explode(';', $data);
	list(, $data) = explode(',', $data);
	$data = base64_decode($data);
	return file_put_contents($filename, $data) !== false;
}

/************
 * EXAMPLE
 ***********/
$base64Data = <<<BASE64
data:image/png;base64,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
BASE64;

imgBase64ToFile('image.png', $base64Data);
Сниппет,  PHP

Generate a GUID string

Gravatar image
blacksmoke26
  • Репутация: 13
  • Сниппеты: 11
  • Ревизии: 0
/**
 * Generate a GUID string
 * @link http://php.net/manual/en/function.random-int.php#118636
 * @return string
 */
function guid () {
	/** @var string $uid */
	return sprintf ( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',

		// 32 bits for "time_low"
		random_int ( 0, 0xffff ), random_int ( 0, 0xffff ),

		// 16 bits for "time_mid"
		random_int ( 0, 0xffff ),

		// 16 bits for "time_hi_and_version",
		// four most significant bits holds version number 4
		random_int ( 0, 0x0fff ) | 0x4000,

		// 16 bits, 8 bits for "clk_seq_hi_res",
		// 8 bits for "clk_seq_low",
		// two most significant bits holds zero and one for variant DCE1.1
		random_int ( 0, 0x3fff ) | 0x8000,

		// 48 bits for "node"
		random_int ( 0, 0xffff ), random_int ( 0, 0xffff ), random_int ( 0, 0xffff ) );
}

/*************
 * EXAMPLE
 ************/
 var_dump ( guid () );

 /*************
 * OUTPUT
 ************/
 # (string) '35cf783a-e866-4956-871c-6af2ef6f7bc9'