Skip to content

Instantly share code, notes, and snippets.

@if0rest
Last active December 20, 2021 13:13
Show Gist options
  • Save if0rest/79f067422df6604c23db629e48b474fd to your computer and use it in GitHub Desktop.
Save if0rest/79f067422df6604c23db629e48b474fd to your computer and use it in GitHub Desktop.

generate_salt

function generate_salt($length) {
    // Not 100% unique, not 100% random, but good enough for a salt
    // MD5 returns 32 characters
    $unique_random_string = md5(uniqid(mt_rand(), true));

    // Valid characters for a salt are [a-zA-Z0-9./]
    $base64_string = base64_encode($unique_random_string);

    // But not '+' which is valid in base64 encoding
    $modified_base64_string = str_replace('+', '.', $base64_string);

    // Truncate string to the correct length
    $salt = substr($modified_base64_string, 0, $length);

    return $salt;
}

echo generate_salt(20);   // ZDM5MDdiMjk4N2RiOWNj

printDirSorted

Довольно часто нам приходится сортировать что-то по более сложному критерию, чем просто по алфавиту. Например, пусть в $files хранится список имен файлов и подкаталогов в текущем каталоге. Возможно, мы захотим вывести этот список не только в лексикографическом (алфавитном) порядке, но также и чтобы все каталоги предшествовали файлам. В этом случае нам стоит воспользоваться функцией uksort(), передав в качестве второго параметра предварительно написанную или анонимную функцию сравнения с двумя параметрами, как того требует uksort().

Забегая вперед заметим, что функции opendir() и readdir() предназначены для чтения имен файлов и подкаталогов в некотором каталоге. Мы используем их для заполнения массива $files так, чтобы в его ключах находились имена файлов, а в значениях — их размеры.

Конечно, связи между ключами и значениями функции uksort() сохраняются, т.е. опять же некоторые пары просто "всплывают" наверх, а другие "оседают".

function printDirSorted($path)
{
    $d = opendir($path);

    while (false !== ($e = readdir($d))) {
        $e = "$path/$e";
        $files[$e] = (is_dir($e)) ? 0 : filesize($e);
        // $files[имя папки/файла] => размер в байтах
    }

    // Сравниваем имена файлов и каталогов.
    uksort($files, function($f1, $f2) {
        // Каталог всегда предшествует файлу
        if (is_dir($f1) && !is_dir($f2)) return -1;
        // Файл всегда идет после каталога
        if (!is_dir($f1) && is_dir($f2)) return 1;
        // Иначе сравниваем лексикографически
        return $f1 <=> $f2;
    });

    echo '<pre>'; print_r($files); echo '</pre>';
}

printDirSorted('.');

lesson6_webpImage

uploads/2/11.jpg => uploads/2/11.webp

function lesson6_webpImage($path) {
   $tmp = explode('.', $path);
   $last = count($tmp) - 1;

   // check $tmp[$last] extention
   $tmp[$last] = 'webp';
   $webpPath = implode('.', $tmp);

   if(!file_exists($webpPath)) {
      $image = imagecreatefromstring(file_get_contents($path));
      imagewebp($image, $webpPath);

      $fpr = fopen($webpPath, "a+");
      fwrite($fpr, chr(0x00));  //some fix
      fclose($fpr);
   }

   return "<source type=\"image/webp\" srcset=\"$webpPath\">";
}

convertAttachment2webp

/**
 *
 */
function convertAttachment2webp($path)
{
    $arr = pathinfo($path);

    // Make unique filename.
    $filename = strtolower(md5(uniqid($arr['filename'])));

    // Siteroot storage of uploaded images.
    $webpPath = $_SERVER['DOCUMENT_ROOT'] . "/upload/{$filename}.webp";

    if (!file_exists($webpPath))
    {
        $image = imagecreatefromstring(file_get_contents($path));
        imagewebp($image, $webpPath);

        $fpr = fopen($webpPath, "a+");
        fwrite($fpr, chr(0x00));
        fclose($fpr);
    }

    $relPath = substr($webpPath, strlen($_SERVER['DOCUMENT_ROOT']));

    return "<img src=\"$relPath\">";
}

if (isset($_FILES['file']) && !empty($_FILES['file']))
    echo convert2webp($_FILES['file']['tmp_name']);

convertLocal2webp

/**
 *
 */
function convertLocal2webp(string $path): string
{
    if (!file_exists($path)) die("Указан неверный путь.");

    $arr = pathinfo($path);

    $webpPath = $arr['dirname'] . DIRECTORY_SEPARATOR . $arr['filename'] . '.webp';

    if (!file_exists($webpPath))
    {
        $image = imagecreatefromstring(file_get_contents($path));
        if (!imagewebp($image, $webpPath)) die("Ошибка конвертции.");

        $fpr = fopen($webpPath, "a+");
        fwrite($fpr, chr(0x00));
        fclose($fpr);
    }

    $relPath = substr($webpPath, strlen($_SERVER['DOCUMENT_ROOT']));

    return "<img src=\"$relPath\">";
}

echo convertLocal2webp('C:\www\domains\test\img.png');

clear_dir

function clear_dir($dir, $keepRootFolder = false)
{
    // Handle bad arguments.
    if (empty($dir) || !file_exists($dir)) {
        // No such file/folder exists
        return true;
    } elseif (is_file($dir) || is_link($dir)) {
        // Delete file/link
        return @unlink($dir);
    }

    // Delete all children.
    $files = new \RecursiveIteratorIterator(
        new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
        \RecursiveIteratorIterator::CHILD_FIRST
    );

    foreach ($files as $file) {
        $action = $file->isDir() ? 'rmdir' : 'unlink';

        if (!@$action($file->getRealPath())) {
            // Abort due to the failure
            return false;
        }
    }

    // Delete the root folder itself?
    return (!$keepRootFolder ? @rmdir($dir) : true);
}

clear_dir('folder_name', true);

// Origin: https://gist.github.com/mindplay-dk/a4aad91f5a4f1283a5e2

clearDir

function clearDir(string $path): void
{
    // Get resource descriptor
    if ($desc = @opendir($path))
    {
        // Iterate over dir content
        while($entry = readdir($desc))
        {
            if ($entry != "." && $entry != "..")
            {
                (is_dir($path . DIRECTORY_SEPARATOR . $entry))
                    ? clearDir($path . DIRECTORY_SEPARATOR . $entry)
                    : unlink($path . DIRECTORY_SEPARATOR . $entry);
            }
        }
        closedir($desc);
        rmdir($path);
    }
}

getUniqName

function getUniqName(string $filename): string
{
    $ext = end(explode('.', $filename));

    return strtolower(md5(uniqid($filename)) . '.' . $ext);
}

getFileExtension

function getFileExtension(string $name): string
{
    // return substr($name, strrpos($name, '.'));
    return end(explode('.', $name));
}
function getFileExtension(string $name): string
{
    return strtolower(pathinfo($name)['extension']);
}

check_mobile_device

function check_mobile_device()
{
    $mobile_agent_array = [
        'android', 'blackberry', 'cellphone', 'htc_', 'ipad', 'iphone', 'ipod', 'motorola', 'nokia',
        'opera mini', 'opera mobi', 'palm', 'playstation portable', 'pocket', 'samsung', 'sharp',
        'small', 'smartphone', 'sonyericsson', 'symbian', 'tablet browser', 'windows ce', 'windowsce',
    ];

    $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
    // var_dump($user_agent);exit;
    foreach ($mobile_agent_array as $agent)
    {
        if (strpos($user_agent, $agent) !== false)
            return true;
    }

    return false;
}

$is_mobile_device = check_mobile_device();

if (!$is_mobile_device)
echo <<<'EOT'
    <script type="text/javascript" charset="utf-8" async src="https://api-maps.yandex.ru/services/constructor/1.0/js/></script>
EOT;

DeleteDirFilesEx

/**
 * <p>Удаляет рекурсивно указанный каталог (файл). Возвращает "true" в случае успешного выполнения.</p> <p>Аналог функции вновом ядре: <a href="http://dev.1c-bitrix.ru/api_d7/bitrix/main/io/directory/deletedirectory.php" >Bitrix\Main\IO\Directory::deleteDirectory</a>.</p>
 */
function DeleteDirFilesEx($path)
{
    if(strlen($path) == 0 || $path == '/')
        return false;

    $full_path = $_SERVER["DOCUMENT_ROOT"]."/".$path;
    $full_path = preg_replace("#[\\\\\\/]+#", "/", $full_path);

    $f = true;
    if(is_file($full_path) || is_link($full_path))
    {
        if(@unlink($full_path))
            return true;
        return false;
    }
    elseif(is_dir($full_path))
    {
        if($handle = opendir($full_path))
        {
            while(($file = readdir($handle)) !== false)
            {
                if($file == "." || $file == "..")
                    continue;

                if(!DeleteDirFilesEx($path."/".$file))
                    $f = false;
            }
            closedir($handle);
        }
        if(!@rmdir($full_path))
            return false;
        return $f;
    }
    return false;
}

replaceSpecSym

function replaceSpecSym($text)
{
    $specChars = array(
        '!' => '%21',    '"' => '%22',
        '#' => '%23',    '$' => '%24',    '%' => '%25',
        '&' => '%26',    '\'' => '%27',   '(' => '%28',
        ')' => '%29',    '*' => '%2A',    '+' => '%2B',
        ',' => '%2C',    '-' => '%2D',    '.' => '%2E',
        '/' => '%2F',    ':' => '%3A',    ';' => '%3B',
        '<' => '%3C',    '=' => '%3D',    '>' => '%3E',
        '?' => '%3F',    '@' => '%40',    '[' => '%5B',
        '\\' => '%5C',   ']' => '%5D',    '^' => '%5E',
        '_' => '%5F',    '`' => '%60',    '{' => '%7B',
        '|' => '%7C',    '}' => '%7D',    '~' => '%7E',
        ',' => '%E2%80%9A',  ' ' => '%20'
    );

    foreach ($specChars as $k => $v)
        $text = str_replace($k, $v, $text);

    return $text;
}

parseQueryStringToArray

$str = "name=%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80&email=post%40mail.ru&phone=";

function parseQueryStringToArray(string $str, bool $filtered = false): array
{
    if (empty(trim($str))) return false;

    foreach (explode('&', $str) as $chunk)
    {
        [$name, $value] = explode('=', $chunk);
        $fields[$name] = urldecode($value);
    }

    return ($filtered) ? array_filter($fields) : $fields;
}
function parseQueryStringToArray(string $str, bool $filtered = false): array
{
    if (empty(trim($str))) return false;

    preg_match_all("~(?<name>[a-z]+)=(?<value>[^&]*)~i", $str, $matches, PREG_SET_ORDER);

    foreach ($matches as $field)
        $arFields[$field['name']] = urldecode($field['value']);

    return ($filtered) ? array_filter($arFields) : $arFields;
}

phoneticParsing

/**
 * Counts the total number of vowels and consonants.
 *
 * @param string $text
 * @return array Amount of vowels and consonants.
 */
function phoneticParsing(string $text): array
{
    $vowels     = "аеёиоуыэюяaeiouy";
    $consonants = "бвгджзйклмнпрстфхцчшщbcdfghjklmnpqrstvwxz";
    $pattern    = "~(?<vowels>[{$vowels}])|(?<conson>[{$consonants}])~iu";

    preg_match_all($pattern, $text , $letters);

    return [
        'v' => count(array_filter($letters['vowels'])),
        'c' => count(array_filter($letters['conson'])),
    ];
}

/*====================  Набор букв  ====================*/

$vowels       = "аеёиоуыэюяaeiouy";
$consonants   = "бвгджзйклмнпрстфхцчшщbcdfghjklmnpqrstvwxz";

$ruVowels     = ["а","е","ё","и","о","у","ы","э","ю","я"];
$ruConsonants = ["б","в","г","д","ж","з","й","к","л","м",
                "н","п","р","с","т","ф","х","ц","ч","ш","щ"];

$enVowels     = ["a","e","i","o","u","y"];
$enConsonants = ["b","c","d","f","g","h","j","k","l","m",
                "n","p","q","r","s","t","v","w","x","z"];

$arVowels     = ["а","е","ё","и","о","у","ы","э","ю","я","a","e","i","o","u","y"];
$arConsonants = ["б","в","г","д","ж","з","й","к","л","м","н","п","р","с","т","ф",
                "х","ц","ч","ш","щ","b","c","d","f","g","h","j","k","l","m","n",
                "p","q","r","s","t","v","w","x","z"];

testPerfomance

Замеряем производительность кода.

/*----------- Способ #1 -----------*/

$reps = 1000;

$start = microtime(true);
for ($i=0; $i < $reps; $i++)
{
    testPerfomance();
}
$total   = microtime(true) - $start;
$round   = round($total, 5);
$average = round($total / $reps, 5);

echo <<<HTML
<pre style="background:#eee;padding: 3px 6px; font-size: .9em;">
    Total: <b>{$round} sec</b> for <u>{$reps}</u> iterations [1 ≈ <b>{$average}s</b>]
</pre>
HTML;

function testPerfomance()
{
    # code...
}

/*----------- Способ #2 -----------*/

{
    # code...
}
$time = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
// $_SERVER['REQUEST_TIME_FLOAT'] - время запроса к серверу

echo $time . ' sec.';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment