Поддержите проект сделав пожертвование.

Илья Чубаров

Активный Laravel участник ✨
Илья Чубаров (Переводчик)

Активный Laravel участник ✨

Новый фасад Context

Не так давно в Laravel был смержен PR на добавления нового Facade с названием Context. Для чего он и что он дает пользователям фреймворка бы попробуем разобрать в этой статье. По заявлению автора этого фасада, он позволит отслеживать текущий и исторический “контекст” приложения сквозь request, очереди и команды. Со слов автора Context больше всего будет полезен для логгирования.

По сути основные точки входа в приложение, CLI (командная строка), HTTP и jobs.

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

Talk is cheap. Show me the code.

Логирование

В данном примере мы добавляем в context метаданные.

trace_id используется в различных системах чтобы отследить flow или жизнь пользователя в приложении. Например вы можете передавать trace_id в другой сервис(если он ваш) где trace_id будет тоже логироваться. В результате вы можете по логам восстановить “жизненный цикл” пользователя из различных сис-м по этой метке.

// где-то в middleware...

Context::add('hostname', gethostname());
Context::add('trace_id', (string) Str::uuid());

//  где-то в controller...

Log::info('Retrieving commit messages for repository [{repository}].', [
    'repository' => $repo,
]);

Http::get('https://laravel.su');

Теперь это информация добавлена в лог в качестве мета данных. 👇

[2024-01-19 04:20:06] production.INFO: Retrieving commit messages for repository [laravel/framework]. {"repository":"laravel/framework"} {"hostname":"prod-web-1","trace_id":"a158c456-d277-4214-badd-0f4c8e84df79"}

Как данные контекста проносятся через request до jоbs

Фасад Context может проносить содержимое через request запрос до очередей.

Например мы добавили в контекст информацию.

// Request::url() === 'https://laravel.su'

Context::add('initiating_url', Request::url());

Далее вы отправляете job в очереди как обычно.

CalculateStats::dispatch();

Теперь когда отложенная job выполниться, она имеет доступ к контексту из запроса.

class CalculateStats
{
    public function handle()
    {
        Log::info('Hello from the queue.');
    }
}

И результат в логе.

[2024-01-19 04:20:06] production.INFO: Hello from the queue.  {"initiating_url":"https://laravel.su"}

Данные которые мы добавили во время запроса, будут доступны в очередях – даже если он выполниться на другой машине!

Пример с передачей в сторонней сервис

Как я писал выше, иногда необходимо передать trace_id в другой сервис для связывания логической цепочки запросов в разных местах. Например в middleware мы может добавить этот trace_id а потом его просто извлекать и вставлять в http запрос.

Context::add('trace_id', (string) Str::uuid());

// ...

Http::globalOptions([
    'headers' => [
        'X-Trace-Id' => Context::get('trace_id'),
    ],
]);

Более подробно вы можете ознакомиться с возможностями в этом PR

Телеграм канал где у нас свой контекст и своя атмосфера 😅

4
Илья Чубаров (Переводчик)

Активный Laravel участник ✨

Разбираемся как удалить emoji символы из текста пользователя

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

При поиске способов удаления эмодзи из строки на PHP часто можно натолкнуться на подобное решение:

function remove_emoji($string)
{
    // Match Enclosed Alphanumeric Supplement
    $regex_alphanumeric = '/[\x{1F100}-\x{1F1FF}]/u';
    $clear_string = preg_replace($regex_alphanumeric, '', $string);

    // Match Miscellaneous Symbols and Pictographs
    $regex_symbols = '/[\x{1F300}-\x{1F5FF}]/u';
    $clear_string = preg_replace($regex_symbols, '', $clear_string);

    // Match Emoticons
    $regex_emoticons = '/[\x{1F600}-\x{1F64F}]/u';
    $clear_string = preg_replace($regex_emoticons, '', $clear_string);

    // Match Transport And Map Symbols
    $regex_transport = '/[\x{1F680}-\x{1F6FF}]/u';
    $clear_string = preg_replace($regex_transport, '', $clear_string);
    
    // Match Supplemental Symbols and Pictographs
    $regex_supplemental = '/[\x{1F900}-\x{1F9FF}]/u';
    $clear_string = preg_replace($regex_supplemental, '', $clear_string);

    // Match Miscellaneous Symbols
    $regex_misc = '/[\x{2600}-\x{26FF}]/u';
    $clear_string = preg_replace($regex_misc, '', $clear_string);

    // Match Dingbats
    $regex_dingbats = '/[\x{2700}-\x{27BF}]/u';
    $clear_string = preg_replace($regex_dingbats, '', $clear_string);

    return $clear_string;
}

Хотя этот метод работает, он требует постоянного обновления диапазонов символов Unicode и может быть неэффективным в долгосрочной перспективе.

Однако существует более простое и элегантное решение, основанное на использовании регулярных выражений:

use Illuminate\Support\Str;

$text = Str::of("Сегодняшний ужин был просто восхитителен! 🍕🍣🍰")
    ->replaceMatches('/[^\p{L}\p{N}\p{Z}\p{P}]/u', '');

Давайте разберем, что делает это регулярное выражение по частям:

  • \p{L}: Unicode-класс символов, соответствующий любой букве.
  • \p{N}: Unicode-класс символов, соответствующий любой цифре.
  • \p{Z}: Unicode-класс символов, соответствующий любому разделителю (пробел, табуляция и т.д.).
  • \p{P}: Unicode-класс символов, соответствующий любому знаку пунктуации.

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

Телеграм канал где я публикую все самое интересное из разработки и там куча emoji 😎

1