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

Tutik Alexsandr    2   9 044


Видимо, пользователь решил о себе ничего не говорить.
  • Зарегистрирован 5 лет назад
Профиль завершён на 0 %
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

Полезная функция, когда нужно добавить к существующей ссылке дополнительные параметры. В фреймворках к сожалению нет такого...

/**
  * @param $url
  * @param array $data
  * @return string
*/
function buildUrl($url, $data = array())
{
    $parsed = parse_url($url);
    isset($parsed['query']) ? parse_str($parsed['query'], $parsed['query']) : $parsed['query'] = [];
    $params = isset($parsed['query']) ? array_merge($parsed['query'], $data) : $data;
    $parsed['query'] = ($params) ? '?' . http_build_query($params) : '';
    if (!isset($parsed['path']))
    $parsed['path'] = '/';

    $scheme = isset($parsed['scheme']) ? $parsed['scheme']: 'http';
    return $scheme. '://' . $parsed['host'] . (!empty($parsed['port']) ? ':'.$parsed['port']:'') . 	$parsed['path'] . $parsed['query'];
}

Есть реалзиция и для nodejs правда придется ставить npm пакет locutus

exports.url = require('locutus/php/url/index');
exports.str = require('locutus/php/strings/index');
exports.array = require('locutus/php/array/index');

exports.buildUrl = function(str, data){
    var parsed = this.url.parse_url(str);
    var params = [];
    if(parsed['query']!=undefined)
        this.str.parse_str(parsed['query'],params);

    params = this.array.array_merge_recursive(params, data);
    parsed['query'] = !this.empty(parsed['query']) ? '?' + this.url.http_build_query(params) : '';
    if(!this.isset(parsed['path'])){
        parsed['path'] = '/';
    }
    var scheme = !this.empty(parsed['scheme']) ? parsed['scheme']: 'http';
    return scheme + '://' + parsed['host']+ parsed['path'] + parsed['query']
};

Пример

	echo buildUrl('http://yandex.ru?q=hi',['q' => 'hello world', 'oldparam' => 'test_value']);
	// http://yandex.ru/?q=hello+world&oldparam=test_value

online test

Бывают такие задачи, когда нужно сделать запуск скрипта один раз в минуту и чтобы повторный скрипт не выполнялся до тех пор, пока первый скрипт не отработает полностью. Решений много (можно помечать запись(и) в БД и не брать их при след запуске, можно блокироваь фаил для процесса и это самый примитивный способ. На самом деле кода тут под Yii2 совсем мало 1 функция.. Как это работает: создаем файл и делаем на этот файл LOCK, пока процесс работает файл будет заблокирован стоит процессу умереть LOCK с файла спадет сам.

Создаем BaseController для всех наших бедующих контроллеров

<?php

namespace app\commands\base;

use yii\console\Controller;
use Yii;

class BaseController extends Controller
{
    public $lockHandle;
    protected function lockProcess($pid)
    {
        $path = Yii::getAlias('@app/runtime/logs/'.$pid.'.txt');
        
        if(!flock($this->lockHandle = fopen($path, 'w'), LOCK_EX | LOCK_NB)){
            echo "Already runninng\n";
            exit;
        }
        fwrite($this->lockHandle,'run');
    }

    protected function unlockProcess()
    {
        flock($this->lockHandle, LOCK_UN);
        fclose($this->lockHandle);
    }
}

Как пользоватся? наследуем свой класс от BaseController и используем методы

$this->lockProcess('test-pid1');
// тут какой-то тяжелоый код, который любит долго работать
$this->unlockProcess()

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

Класс 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";
}

Вершины узлов категорий в БД построены на основе MaterializedPath

<?=$form->field($offer, 'categories_list')->dropDownList(
	ArrayHelper::map($categories,'id',function($value){ return str_repeat('-',count(explode('.',$value->path) )) . $value->name ;} ), 
	['multiple' => true]);
?>


Сниппет,  JavaScript

Workpiece modules JS

usage

(function(){
    ConstructName();
})();
(function(window){
	function ConstructName(){
		"use strict";
		var $selectorsClass = {
			dragHandle: '.drag-handler'
		};
		function handleModuleSortable(){ }
		function handleModuleGridView(){ }	
		function init(){
			handleModuleSortable();
			handleModuleGridView();
		}
		init();
	}
window.ConstructName = ConstructName;
})(window);