| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- <?php
- namespace App\Casts;
- use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
- use Illuminate\Support\Facades\DB;
- /**
- * Class BinaryTextCast
- *
- * Пользовательский класс для приведения типов, который обеспечивает преобразование
- * текстовых данных, хранящихся в бинарном формате (VARBINARY) в базе данных,
- * в строку UTF-8 для использования в приложении, и обратно.
- *
- * Это необходимо для корректной работы с данными, которые хранятся в кодировке (Windows-1251),
- * отличной от используемой в приложении.
- *
- * @package App\Casts
- */
- class BinaryTextCast implements CastsAttributes
- {
- /**
- * Преобразует значение из базы данных для использования в приложении.
- *
- * Этот метод вызывается, когда мы получаем значение атрибута из модели Eloquent.
- * Он обрабатывает бинарные данные, конвертируя их из Windows-1251 в UTF-8.
- *
- * @param \\Illuminate\\Database\\Eloquent\\Model $model
- * @param string $key
- * @param mixed $value
- * @param array $attributes
- * @return string|null
- */
- public function get($model, string $key, $value, array $attributes)
- {
- // Если значение из БД равно null, возвращаем null
- if (is_null($value)) {
- return null;
- }
- // Проверяем, является ли значение шестнадцатеричной строкой (например, '0x...').
- // Некоторые драйверы баз данных могут возвращать бинарные данные в таком формате.
- if (ctype_xdigit($value) && str_starts_with(strtolower($value), '0x')) {
- // Если да, убираем префикс '0x' и конвертируем из hex в бинарные данные.
- $binary_data = hex2bin(substr($value, 2));
- } else {
- // В противном случае, считаем, что значение уже является бинарными данными.
- $binary_data = $value;
- }
- // Конвертируем бинарные данные из кодировки Windows-1251 в UTF-8
- // и удаляем пробельные символы в конце строки.
- return rtrim(mb_convert_encoding($binary_data, 'UTF-8', 'Windows-1251'));
- }
-
- /**
- * Преобразует значение из приложения для сохранения в базу данных.
- *
- * Этот метод вызывается, когда мы устанавливаем значение атрибута в модели Eloquent.
- * Он конвертирует строку из UTF-8 в Windows-1251 и подготавливает ее
- * для сохранения в поле типа VARBINARY.
- *
- * @param \\Illuminate\\Database\\Eloquent\\Model $model
- * @param string $key
- * @param mixed $value
- * @param array $attributes
- * @return array
- */
- public function set($model, string $key, $value, array $attributes)
- {
- // Если устанавливаемое значение равно null, сохраняем null в БД.
- if (is_null($value)) {
- return [$key => null];
- }
- // Конвертируем строку из UTF-8 в Windows-1251.
- $win1251_string = mb_convert_encoding($value, 'Windows-1251', 'UTF-8');
-
- // Преобразуем строку в ее шестнадцатеричное представление.
- $hex_string = bin2hex($win1251_string);
- // Формируем бинарный литерал для SQL-запроса (например, 0x...).
- $binary_literal = '0x' . $hex_string;
- // Возвращаем массив, где ключ - это имя атрибута, а значение -
- // сырое SQL-выражение для преобразования hex-строки в VARBINARY(MAX).
- // Это специфично для MS SQL Server.
- return [
- $key => DB::raw("CONVERT(VARBINARY(MAX), " . $binary_literal . ")")
- ];
- }
- }
|