Портрет 4X_Pro
Был в Сети 5 дек. 2025 г., 19:55
4X_Pro
Идеалист Интернета
  • Программист
  • Блоггер
  • Фотограф
Кратко о себе: Web-разработчик. Пишу на PHP, Python, JavaScript. Знаю Ruby и Go, со студенческих времён более-менее помню C и asm. Специализируюсь на ускорении загрузки сайтов и разработке ботов для Telegram. Linuxоид (использую Debian+Cinnamon). Сторонник IndieWeb, slow lifer.

Социальные сети


Новости сайта в Telegram

t.me/4x_pro

Компьютерное

Особенности работы с HTML в PHP 8.4

4X_Pro
В версиях PHP до 8.4 для выборочной очистки HTML использовался класс DOMDocument, который изначально был предназначен для работы с XML. Однако в версии 8.4 его использование приводит к тому, что возвращается пустая строка. Стал искать решение, и выяснилось, что с этой версии именно для HTML появился новый класс: Dom\HTMLDocument, а для выборки с помощью XPath вместе с ним теперь следует использовать Dom\XPath.

В итоге код для обработки HTML приобретает примерно такой вид:

[php]
Читать далее…

Немного о юзабилити обычных ссылок

4X_Pro
Казалось бы, что может быть проще, чем вывести ссылку в HTML? Однако если создавать сайт, наполнением которого будут заниматься сами пользователи, обнаруживается множество тонкостей в плане юзабилити, которые нужно учитывать. Во-первых, ссылки, вставленные пользователями, могут быть слишком длинными из-за большого «хвоста» параметров (типичный пример — ссылка на страницы Интернет-магазинов с настроенными фильтрами) и переноситься на несколько строк, и в таких случаях их нужно визуально сокращать. Во-вторых, если в ссылке есть кириллица, она при копировании через буфер обмена преобразуется либо в punycode, либо в url encoding и становится нечитаемой. Пример подобного — ссылки на Wikipedia, глядя на которые, нельзя сказать до перехода, на какую статью они ведут. В-третьих, если ссылка ведёт на корневую страницу сайта, желательно показывать только доменное имя, без http или https в начале и / в конце.
Читать далее…

Некоторые тонкости использования образов qcow2 на desktop

4X_Pro
Сегодня узнал, что для Debian (равно как и многих других дистрибутивов) можно скачать готовый образ в формате qcow2 для libvirt-qemu вместо установки из ISO-образа. Но, как выяснилось, есть некоторые нюансы. Во-первых, для виртуализации на обычном desktopе нужно качать образы nocloud, а не genericcloud. В запущенную машину на genericcloud просто не получится зайти из-за того, что пароли пользователей в ней не заданы, а предполагается, что ключ для входа под SSH будет загружен средствами openstack. Во-вторых, образ по умолчанию имеет размер всего 3 Гб, и нужно его увеличивать в два этапа.

Первый — на хосте изменить размер образа с помощью команды qemu-img:

Размер можно указать либо желаемый итоговый (например, 20G), либо на сколько увеличить (например, +17G).

Второй этап — в виртуальной машине сделать apt update (без чего apt просто не найдёт никакие пакеты), установить cloud-guest-utils и выполнить команду growpart:
Читать далее…

Автоматическая очистка почты при использовании Dovecot

4X_Pro
Если есть необходимость регулярно удалять старые письма, и на сервере в качестве почтового сервера используется Dovecot, то можно прописать в cron такую команду:

Например, так

Типичные значения для ящика: Inbox (Входящие), Outbox (Исходящие), Trash (Корзина), Spam.

Так же есть возможность выполнить команду для всех пользователей, использовав вместо -u пользователь аргумент -A.
Читать далее…

Как удалить alias для одного из доменов Let's Encrypt

4X_Pro
Недавно столкнулся, что на одном сервере certbot перестал обновлять сертификаты. Стал разбираться, в чём дело, и обнаружил, что происходит это из-за того, что все домены, которые обслуживает сервер, были прописаны в одном сертификате как aliasы, а потом один из поддоменов перенесли на другой сервер. В результате не проходила проверка владением домена (request challenge).

Возник вопрос, как удалить этот alias, чтобы сертификат продолжал обновляться для всех остальных доменов. Как выяснилось, готовой команды «перегенирировать сертификат для всех aliasов, кроме указанного» нет. Нужно вручную указывать все домены, кроме ненужного. Делается это так:

Там смотрим имя сертификата после строки Certificate Name: далее — список доменов для него после Domains.

Копируем этот список, заменяем пробелы на запятые, убираем ненужный домен. После этого запускаем команду

После этого certbot отработал нормально, новый сертификат сгенерировался без проблем.
Читать далее…

Как починить повреждённый GRUB

4X_Pro
Пару раз сталкивался с тем, что GRUB переставал работать, проваливаясь в выдавая ошибки вроде grub error symbol grub_disk_native_sectors not found. Чаще всего такое случается при некорректном обновлении, когда основная часть загрузчика (установленная в загрузочный сектор) обновилась, а модули в /boot/grub — нет, или наоборот, но могут быть и другие причины.

Что делать в таких случаях. Во-первых, можно попытаться загрузить Linux вручную с помощью команд:
Читать далее…

Переключение по CapsLock в Windows 10 с помощью Switchy

4X_Pro
Наконец-то нашёл приемлемое решение для переключения по CapsLock под Windows 10, которое может заменить ReCaps или CapsLang — приложение Switchy с открытым исходным кодом (скачивать надо на странице Releases). Написано на чистом WinAPI с EXE-файлом всего в 12 Kb. Запускать нужно с параметром nopopup, иначе при каждом переключении будет мелькать раздражающее окно с индикацией раскладки. Корректно работает даже в WSL и современных Windows-приложениях. В общем, именно таким и должен быть софт!
Читать далее…

Заголовки Sec-CH-UA-Mobile и HTTP_SEC_CH_UA_PLATFORM

4X_Pro
Несколько лет назад я писал заметку о том, как определить мобильный броузер с помощью регулярного выражения для User Agent. Однако в современных броузерах на основе Chrome появился дополнительный и более простой механизм: при обращении к сайту эти броузеры передают специальные заголовки Sec-CH-UA-Mobile и Sec-CH-UA-Platform. В первом приходит значение ?0 для desktop-версии и ?1 для мобильной, во втором — платформа в виде одной из строк: "Android", "Chrome OS", "Chromium OS", "iOS", "Linux", "macOS", "Windows" или "Unknown".

В PHP эти заголовки можно получить как $_SERVER['HTTP_SEC_CH_UA_MOBILE'] и $_SERVER['HTTP_SEC_CH_UA_PLATFORM'] соответственно. (Буквы должны быть именно заглавными.)

Данный механизм поддерживается с 89 версии Chrome, но всё ещё имеет статус экспериментального. В Firefox и Safari поддержка на данный момент, по данным CanIUse, отсутствует.
Читать далее…

Выделение хештегов из текста

4X_Pro
С помощью уже упоминавшегося класса IntlBreakIterator можно легко выделить из текста хеш-теги. Для этого создадим итератор не по предложениям, а по словам с помощью: createWordInstance. Итерация с помощью IntlBreakIterator выдаёт смещения границ слов, что в данном случае не очень удобно. Поэтому воспользуемся методом IntlBreakIterator::getPartsIterator. Он создаёт ещё один итератор, который возвращает уже непосредственно сами слова. Далее, когда встретится символ # (он в режиме WordInstance считается отдельным словом), запоминаем этот факт и следующее слово обрабатываем как хеш-тег.

Вот пример кода:

Проверка mb_strlen($item)>1 нужна для отработки случаев вида #! #;,так как в этом случае знаки препинания рассматриваются как отдельные слова. Кроме того, хештеги из одной буквы обычно не имеют смысла.
Читать далее…

Автоматическое создание анонса текста на PHP

4X_Pro
При создании скриптов для новостей или блогов часто требуется автоматически сформировать анонс из нескольких первых предложений полного текста, не превышающий определённой длины. Типичный подход для этих целей — это выделить с помощью mb_substr начальную часть текста нужной длины, а потом обрезать получившуюся часть до последней точки.

Но не все знают, что с версии 5.5 в PHP в модуле intl предусмотрен специальный класс IntlBreakIterator, который позволяет решать эту задачу более эффективно. У него есть несколько статических методов для создания итераторов, позволяющих выделять границы отдельных символов (createCharacterInstance), слов (createTitleInstance и createWordInstance, первый выделяет слова с включением пробелов и знаков препинания после них, второй — рассматривает пробелы и знаки препинания как отдельные слова) и целых предложений (createSentenceInstance). Для нашей задачи потребуется последний.
Читать далее…


Страницы: