Туннель в локальную сеть с SSL без внешнего IP.

Туннель в локальную сеть с SSL без внешнего IP.

Для разработки бота Telegram мне нужно, чтобы мой проект был доступен через интернет.

Конечно, можно открыть порты на роутере, если есть белый IP-адрес. Но если его нет или нет желания возиться с настройками роутера, можно воспользоваться Tuna.

Tuna позволяет без лишних сложностей создать туннель на локальный компьютер, который будет доступен из интернета и иметь SSL-сертификат, что важно при создании бота Telegram.

У Tuna есть различные тарифные планы, но меня вполне устраивает бесплатный вариант.

Тарифы Tuna

Для начала работы необходимо зарегистрироваться в Tuna и получить токен. После регистрации устанавливаем Tuna, используя PowerShell, с помощью следующей команды:

winget install --id yuccastream.tuna

После установки не забудьте перезапустить PowerShell. Без перезапуска PowerShell может не распознать команду «tuna».Чтобы установить токен, введите следующую команду:

tuna config save-token <ТОКЕН>

Теперь можно поднять наш туннель:

tuna http 8000

Подробнее о параметрах можно почитать в официальной документации.

Запущенный туннель

Теперь можно перейти по домену, который нам предоставил Tuna. На этом домене у меня будет доступен Laravel.

Доступный Laravel по выданному нам адресу.

Также можно обратиться по адресу http://127.0.0.1:4040. Там будут доступны все запросы со статусами ответов и настройками.

Web интерфейс Tuna

Вот и всё. Надеюсь, эта статья была для вас полезной.

Моя реализация обхода блокировки hub.docker.com

Моя реализация обхода блокировки hub.docker.com

Обход блокировки hub.docker.org

Так как hub.docker.com стал не доступен для России, то у меня соответственно появились проблемы с обновление Home Assistant.

Заблокированный hub.docker.com

Уже написано куча статей как можно решить эту проблему: использовать VPN, использовать зеркала, AlexxIT предложил простой вариант обхода для Home Assistant через аддон AdGuard. Я же просто хочу показать как я реализовал обход блокировки hub.docker.org

Дано:
Частный VPN сервер в амстердаме.
Роутер Keenetic Giga

Что делаю:

1. Поднимаю VPN интерфейс

    VPN интерфейс

    2. На 2ip.ru смотрю ip для hub.docker.org. Это будут 54.156.140.159, 44.221.37.199, 52.44.227.212.

    Ищу ip адреса для hub.docker.org

    3. Создаю в роутере маршруты для этих ip.

    • Тип маршрута -> Маршрут до узла
    • Описание -> Любое. Я указал hub.docker.org
    • Адрес узла назначения -> IP адрес полученный в предыдущем шаге.
    • Адрес шлюза -> Оставляем поле пустым.
    • Интерфейс -> Выбираем интерфейс поднятого VPN.
    • Добавлять автоматически -> Отмечаем
    • Эксклюзивный маршрут -> Отмечаем
    Настраиваю маршруты для hub.docker.org

    4. Проверяю сайт hub.docker.org. Он открывается, а вот контейнеры в Home Assistant не обновляются. Проверил на десктопе запулить контейнер — тоже нет.

    hub.docker.org открылся

    5. Ищу куда обращается Docker через Wireshark. Контейнеры он тянет с registry-1.docker.io. IP адреса: 54.236.113.205, 54.227.20.253, 54.198.86.24.

    Ищу ip адреса для registry-1.docker.io через wireshark

    6. Добавляю маршруты в роутере для registry-1.docker.io.

    Список всех маршрутов

    После всех манипуляций у меня стал нормально обновляться Home Assistant и открываться hub.docker.org, а значит обход блокировки hub.docker.org работает. На этом все, спасибо за внимание! 🙂

    Гибернация компьютера в Home Assistant

    Гибернация компьютера в Home Assistant

    Гибернация компьютера в Home Assistant

    Поскольку я часто использую гибернацией, я решил сделать гибернацию своего ПК через Home Assistant.

    Если с выключением компьютера через RPC Shutdown всё понятно, то с переходом в режим гибернации возник вопрос, так как RPC Shutdown не может отправить ПК в этот режим.

    Я начал искать варианты и наткнулся на программу под названием Airytec Switch Off. Эта программа позволяет автоматически или удаленно выключать компьютер с любого компьютера или мобильного телефона. Что для меня важно, так это то, что она имеет веб-интерфейс с ссылками на команды, из которых я и получил URL которые я использовал в Home Assistant.

    Теперь я расскажу, как я реализовал это у себя. Для начала, нужно скачать и установить саму программу. После установки и запуска, в трее появится иконка. Чтобы получить доступ к настройкам программы, нужно кликнуть правой клавишей мыши по иконке и выбрать пункт Options.

    Выбираем пункт Options

    Далее переходим во вкладку Remote и ставим галочку Enable web interface. После кликаем по View web interface.

    Включаем web интерфейс

    Мы попадаем в веб-интерфейс программы, откуда и будем извлекать адрес ссылки для удаленного выключения/перезагрузки/сна/гибернации.

    Web интерфейс Airytec Switch Off.

    Чтобы получить адрес ссылки для выключения/перезагрузки/сна/гибернации, щелкните правой кнопкой мыши по ссылке и выберите Копировать адрес ссылки. В моем случае, если я хочу перейти в режим гибернации, ссылка будет выглядеть так:

    http://localhost:700/?action=System.Hibernate

    Чтобы использовать этот адрес, необходимо заменить localhost на локальный IP-адрес вашего компьютера. В моем случае это будет так:

    http://192.168.30.68:700/?action=System.Hibernate

    Обратите внимание, что эти адреса могут отличаться в зависимости от вашей конфигурации и настроек системы.

    В Home Assistant необходимо создать команды Shell. Я сделал это сразу для всех вариантов.

    shell_command:
      shutdown_mypc: "curl -k http://192.168.30.68:700/?action=System.Shutdown"
      restart_mypc: "curl -k http://192.168.30.68:700/?action=System.Restart"
      sleep_mypc: "curl -k http://192.168.30.68:700/?action=System.Sleep"
      hibernate_mypc: "curl -k http://192.168.30.68:700/?action=System.Hibernate"

    Для включения или гибернации своего ПК я использую переключатель. Вот пример моего переключателя:

    switch:
      - platform: wake_on_lan
        name: "Мой ПК"
        mac: XX:XX:XX:XX:XX:XX
        turn_off:
          service: shell_command.hibernate_mypc
          
    

    На этом все. Надеюсь, моя статья кому-то поможет.

    Не работает метод map() с методом paginate() в Laravel Eloquent.

    Не работает метод map() с методом paginate() в Laravel Eloquent.

    Не работает метод map() с методом paginate() в Laravel Eloquent.

    Столкнулся с проблемой, не работает метод map() с методом paginate() в Laravel Eloquent. Метод map() создает новую коллекцию. Соответственно при попытке использовать его с методом paginate() ничего не получится. Используя map() мы получим коллекцию без пагинации.

    $users = User::paginate($request->per_page ?? 10)->map(function ($user) {
                $user->confirm_email = $user->email_verified_at ? true : false;
                $user->role_name = $user->roles()->first() ? $user->roles()->first()->name : null;
                return $user;
            });

    Для того, чтобы изменить значения в полученной коллекции, нужно использовать метод through().

     $users = User::paginate($request->per_page ?? 10)->through(function ($user) {
                $user->confirm_email = $user->email_verified_at ? true : false;
                $user->role_name = $user->roles()->first() ? $user->roles()->first()->name : null;
                return $user;
            });

    В результате мы получим измененную коллекцию с пагинацией. Я написал это для себя в качестве шпаргалки, но вдруг кому-то это также будет полезно.


    Скрипты для кофеварки Redmond(RedSolution) SkyCoffee M1509S/M1519S в Home Assistant

    Скрипты для кофеварки Redmond(RedSolution) SkyCoffee M1509S/M1519S в Home Assistant

    Скрипты для кофеварки Redmond(RedSolution) SkyCoffee M1509S/M1519S в Home Assistant

    Просили показать как у меня реализована дозирование кофе в кофеварке Redmond M1509S/M1519S. В двух словах:

    В роли шлюза использую ESP32 с прошивкой https://github.com/alutov/ESP32-R4sGate-for-Redmond.

    Устройства прилетают в Home Assistant через MQTT.

    Кофеварка в MQTT

    Скрипты:

    01_coffee:
      alias: Кофеварка - Одна чашка кофе
      sequence:
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_strength
        - delay: 0:00:02
        - service: switch.turn_on
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:02:00
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:0:10
        - service: media_player.play_media
          entity_id: media_player.yandex_station_m00scgg00cx7cg
          data:
            media_content_id: Ваш кофе готов
            media_content_type: text
    
    02_coffee:
      alias: Кофеварка - Две чашки кофе
      sequence:
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_strength
        - delay: 0:00:02
        - service: switch.turn_on
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:04:00
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:0:10
        - service: media_player.play_media
          entity_id: media_player.yandex_station_m00scgg00cx7cg
          data:
            media_content_id: Ваш кофе готов
            media_content_type: text
    03_coffee:
      alias: Кофеварка - Три чашки кофе
      sequence:
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_strength
        - delay: 0:00:02
        - service: switch.turn_on
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:06:00
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:0:10
        - service: media_player.play_media
          entity_id: media_player.yandex_station_m00scgg00cx7cg
          data:
            media_content_id: Ваш кофе готов
            media_content_type: text
    
    01_coffee_strength:
      alias: Кофеварка - Одна чашка крепкого кофе
      sequence:
        - service: switch.turn_on
          data:
            entity_id: switch.r4s01_coffee_strength
        - delay: 0:00:02
        - service: switch.turn_on
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:02:30
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:00:02
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_strength
        - delay: 0:0:10
        - service: media_player.play_media
          entity_id: media_player.yandex_station_m00scgg00cx7cg
          data:
            media_content_id: Ваш кофе готов
            media_content_type: text
    
    02_coffee_strength:
      alias: Кофеварка - Две чашки крепкого кофе
      sequence:
        - service: switch.turn_on
          data:
            entity_id: switch.r4s01_coffee_strength
        - delay: 0:00:02
        - service: switch.turn_on
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:05:00
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:00:02
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_strength
        - delay: 0:0:10
        - service: media_player.play_media
          entity_id: media_player.yandex_station_m00scgg00cx7cg
          data:
            media_content_id: Ваш кофе готов
            media_content_type: text
    
    03_coffee_strength:
      alias: Кофеварка - Три чашки крепкого кофе
      sequence:
        - service: switch.turn_on
          data:
            entity_id: switch.r4s01_coffee_strength
        - delay: 0:00:02
        - service: switch.turn_on
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:07:30
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:00:02
        - service: switch.turn_off
          data:
            entity_id: switch.r4s01_coffee_strength
        - delay: 0:0:10
        - service: media_player.play_media
          entity_id: media_player.yandex_station_m00scgg00cx7cg
          data:
            media_content_id: Ваш кофе готов
            media_content_type: text
    
    00_coffee_stop:
      alias: Кофеварка - Стоп
      sequence:
        - service: script.turn_off
          target:
            entity_id:
              - script.01_coffee_strength
              - script.02_coffee_strength
              - script.03_coffee_strength
              - script.01_coffee
              - script.02_coffee
              - script.03_coffee
        - delay: 0:00:01
        - service: switch.turn_off
          target:
            entity_id: switch.r4s01_coffee_switch
        - delay: 0:00:01
        - service: switch.turn_off
          target:
            entity_id: switch.r4s01_coffee_strength
    
    
    

    Активирую скрипты через команды колонке. Использую компонент https://github.com/dext0r/ha-yandex-station-intents.

    Intents:

    yandex_station_intents:
      intents:
        Сделай кофе: Заказ принят, делаю чашечку кофе #1
        Сделай чашку кофе: Заказ принят, делаю чашечку кофе #2
        Сделай две чашки кофе: Заказ принят, делаю две чашки кофе #3
        Сделай три чашки кофе: Заказ принят, делаю три чашки кофе #4
        Сделай чашку крепкого кофе: Заказ принят, делаю чашечку крепкого кофе #5
        Сделай две чашки крепкого кофе: Заказ принят, делаю две чашки крепкого кофе #6
        Сделай три чашки крепкого кофе: Заказ принят, делаю три чашки крепкого кофе #7
        Сделай крепкий кофе: Заказ принят, делаю чашечку крепкого кофе #8
        Отмени кофе: Отменяю заказ #9

    Автоматизации:

    - alias: Кофеварка - Одна чашка кофе
      trigger:
        platform: event
        event_type: yandex_intent
        event_data:
          text: Сделай кофе
      action:
        - service: script.01_coffee
    
    - alias: Кофеварка - Одна чашка кофе2
      trigger:
        platform: event
        event_type: yandex_intent
        event_data:
          text: Сделай чашку кофе
      action:
        - service: script.01_coffee
    
    - alias: Кофеварка - Две чашки кофе
      trigger:
        platform: event
        event_type: yandex_intent
        event_data:
          text: Сделай две чашки кофе
      action:
        - service: script.02_coffee
    
    - alias: Кофеварка - Три чашки кофе
      trigger:
        platform: event
        event_type: yandex_intent
        event_data:
          text: Сделай три чашки кофе
      action:
        - service: script.03_coffee
    
    - alias: Кофеварка - Одна чашка крепкого кофе
      trigger:
        platform: event
        event_type: yandex_intent
        event_data:
          text: Сделай крепкий кофе
      action:
        - service: script.01_coffee_strength
    
    - alias: Кофеварка - Одна чашка крепкого кофе2
      trigger:
        platform: event
        event_type: yandex_intent
        event_data:
          text: Сделай чашку крепкого кофе
      action:
        - service: script.01_coffee_strength
    
    - alias: Кофеварка - Две чашки крепкого кофе
      trigger:
        platform: event
        event_type: yandex_intent
        event_data:
          text: Сделай две чашки крепкого кофе
      action:
        - service: script.02_coffee_strength
    
    - alias: Кофеварка - Три чашки крепкого кофе
      trigger:
        platform: event
        event_type: yandex_intent
        event_data:
          text: Сделай три чашки крепкого кофе
      action:
        - service: script.03_coffee_strength
    
    - alias: Кофеварка - Стоп
      trigger:
        platform: event
        event_type: yandex_intent
        event_data:
          text: Отмени кофе
      action:
        - service: script.00_coffee_stop
    
    Перестал обновляться проводник в Windows

    Перестал обновляться проводник в Windows

    Перестал обновляться проводник в Windows

    Столкнулся с проблемой, что перестал обновляться проводник в Windows. Для любого действия, будь-то удаление или создание папки/файла, приходилось вручную обновлять проводник. При скачивании файла браузер подвисал на некоторое время. Также при запуске подвисали на некоторое время Яндекс.Диск и Яндекс.Заметки.

    Перепробовал кучу разных способов решения данной проблемы начиная от восстановления системных файлов Sfc /scannow и заканчивая сканированием антивирусом своей системы. Долгое время не мог решить данную проблему, но решение оказалось очень простым.

    Виновник моей проблемы из за которой перестал обновляться проводник Windows
    Виновник моей проблемы

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

    Если вы столкнулись с подобной проблемой, рекомендую проверить, что у вас в сетевых расположениях.

    DuckDNS.org в Keenetic

    DuckDNS.org в Keenetic

    DuckDNS.org в Keenetic

    Так сложилось, что появилась необходимость использовать именно DuckDNS в роутере Keenetic, хоть у него есть свой собственный. В данной статье я расскажу как настроить DuckDNS в Keenetic на примере Keenetic 4G.

    Keenetic 4G
    Keenetic 4G

    Первым делом нужно установить пакет DDNS. Для этого идем в Управление -> Параметры системы -> Изменить набор компонентов.

    Изменить набор компонентов
    Выбираем Изменить набор компонентов

    Устанавливаем Клиент динамической службы DNS (DDNS).

    После перезагрузки роутера идем в Сетевые правила -> Доменное имя -> DDNS.


    В поле Сервис выбираем Другой.
    Адрес сервиса указываем https://www.duckdns.org/update?domains=mydomen&token=mysecrettoken не забыв указать свой домен и токен.
    Обратите внимание! URL необходимо указывать без параметра &ip=.
    Доменное имя, Имя пользователя, Пароль оставляем пустыми.
    Ставим галочку Определять мой IP-адрес автоматически.

    Вкладка DDNS
    Вкладка DDNS

    Сохраняем настройки и переходим в Системный монитор -> Статус. В Интернет выбираем Подробнее о соединение. В Статус DDNS мы должны увидеть updated successfully.

    Статус DDNS
    Статус DDNS

    На этом настройка DuckDNS в Keenetic завершена.

    Прошивка камеры IPC8232SWC-WE от Ростелеком на оригинальную прошивку

    Прошивка камеры IPC8232SWC-WE от Ростелеком на оригинальную прошивку

    Прошивка камеры IPC8232SWC-WE от Ростелеком на оригинальную прошивку

    Внимание! Автор не несет ответственность за ваши неудачи, и не призывает к действию! Все что вы делаете — вы делаете на свой страх и риск!

    Данный способ прошивки подсмотрен на 4pda, дополнен и немного изменен для лучшего понимания.

    Немного о камере

    Данная камера была приобретена на Avito за копейки. Хотелось избавиться от камер Xiaomi и приложения MiHome. Оригинальная прошивка поддерживает протокол Onvif и RTSP, что собственно мне и было нужно для добавления камер в видеорегистратор и Home Assistant. Так же у камеры на ножке есть магнит, который позволяет крепить камеру на металлических поверхностях, либо на металлическом пятаке, который идет в комплекте и прикручивается на пару саморезов. Еще один из плюсов — наличие Ethernet разъема на камере.

    Наличие Ethernet разъема
    Наличие Ethernet разъема

    Прошивка камеры

    Для прошивки нужно вскрыть камеру поддев чем-нибудь плоским черную часть камеры.

    Поддеваем с краю черную часть камеры
    Поддеваем с краю черную часть камеры

    После того, как отковыряли лицевую часть камеры аккуратной отключаем микрофон и подцветку.

    Отключаем микрофон и подсветку
    Отключаем микрофон и подсветку

    После этого ищем UART рядом с Ethernet разъемом. Нас интересуют только контакты Tx Rx и Gnd.

    UART
    UART

    К UART можно под паяться или же использовать иголки как сделал я. Так же нужно воткнуть LAN кабель.

    Подключаем UART и LAN кабель
    Подключаем UART и LAN кабель

    Теперь качаем TFTP сервер, архив с прошивкой и Pytty.

    Распаковываем файлы прошивки в рядом с TFTP сервером.

    Файлы прошивки рядом с TFTP сервером
    Файлы прошивки рядом с TFTP сервером

    Редактируем файл manuinfo.txt под себя

    DEVICE_SERIAL_NUMBER: серийный номер вашей камеры (12 знаков)
    MAC_ADDRESS: мак-адрес сетевого интерфейса в формате 0123-4567-89AB
    ACTIVE_CODE: регистрационный код для облака EZ (25 знаков). Предлагаю использовать следующий формат: 0SSSSSSSSSSSSMMMMMMMMMMMM (S — серийный номер, M — мак адрес)
    REGION_CODE: код региона IN — голосовые сообщения на английском, NONE — голосовые сообщения на китайском, FF — без голосовых сообщений

    Запускаем TFTP, открываем Pytty выбираем наш COM порт и скорость 115200.

    Настройки Pytty
    Настройки Pytty

    Подаем питание на камеру и жмем в Pytty Ctrl + Enter либо Ctrl + B чтобы остановить загрузку.

    Останавливаем загрузку
    Останавливаем загрузку

    После того, как остановили загрузку нужно указать IP адрес камеры и IP адрес TFTP сервера.

    ipaddr — адрес камеры, serverip — адрес tftp сервера.

    setenv ipaddr 192.168.0.99
    setenv serverip 192.168.0.111
    Указываем IP адреса камеры и TFTP сервера
    Указываем IP адреса камеры и TFTP сервера

    Далее очищаем флеш-память камеры, загружаем новый загрузчик и перезагружаем камеру.

    mw.b 0x42000000 0xff 0x1000000;tftp 0x42000000 u-boot.bin
    nand erase 0 0x8000000;nand write 0x42000000 0 0x100000
    reset

    В TFTP сервере должны увидеть скачивание файла загрузчика.

    Скачивание загрузчика
    Скачивание загрузчика

    После перезагрузки камеры снова выставляем IP адреса камеры и сервера.

    setenv ipaddr 192.168.0.99
    setenv serverip 192.168.0.111

    Обновляем прошивку, загружаем конфигурацию, выставляем свой MAC-адрес и перезагружаемся.

    update all
    manuinfo manuinfo.txt
    config ethaddr 01:23:45:67:89:AB (mac-адрес вашей камеры)
    reset
    Загрузка прошивки
    Загрузка прошивки

    После перезагрузки если все правильно сделали можно перейти в web-интерфейс камеры.

    Страница авторизации
    Страница авторизации

    По умолчанию данные для входа admin/123456.

    Web-интерфейс камеры
    Web-интерфейс камеры

    Итог

    Прошивка камеры на этом закончена. Теперь камеру можно добавить в регистратор через протокол Onvif или RTSP.

    RTSP основного потока rtsp://admin:123456@ipaddress:554/media/video1
    RTSP второго потока rtsp://admin:123456@ipaddress:554/media/video2

    Настройка Xdebug + OpenServer + PhpStorm

    Настройка Xdebug + OpenServer + PhpStorm

    Настройка Xdebug + OpenServer + PhpStorm

    В данной статье я подробно и наглядно расскажу как настроить и использовать связку Xdebug + OpenServer + PhpStorm.

    Первым делом нужно включить расширение Xdebug в конфигурации PHP. Для этого нужно в OpenServer идем в Дополнительно > Конфигурация > PHP_8.1. Версия PHP у вас может отличаться.

    Конфигурация PHP
    Конфигурация PHP

    В файле конфигурации нужно найти и раскомментировать строку:

    zend_extension = xdebug

    После нужно найти секцию [xdebug] и раскомментировать строки:

    xdebug.mode                     = develop,debug
    xdebug.client_host              = "localhost"
    xdebug.client_port              = 9003

    После сохраняем файл и перезапускаем OpenServer.

    Перезапускаем сервер
    Перезапускаем сервер

    Теперь переходим к настройке PhpStorm. Комбинацией Ctrl + Alt + S или через File > Settings открываем настройки. Слева выбираем PHP > Debug. В открывшихся настройках снимаем галочки с Force break at first line when no path mapping specified и Force break at first line when a script is outside the project. Порты должны быть 9000 и 9003.

    Далее в открытом проекте в правом верхнем углу выбираем Current File > Edit Configurations.

    Current File > Edit Configurations
    Current File > Edit Configurations

    В открывшемся окне нажимаем + и выбираем PHP Remote Debug.

    Добавляем конфигурацию для отладки
    Добавляем конфигурацию для отладки

    В этом окне нужно выбрать напротив поля Server.

    Выбираем многоточие напротив поля Server
    Выбираем многоточие напротив поля Server

    В очередном открывшемся окне тыкаем + и в полях Name и Host указываем имя нашего хоста и жмем OK.

    Добавляем хост для отладки
    Добавляем хост для отладки

    В предыдущем окне в поле Name для удобства указываем имя нашего хоста. В поле Server выбираем наш созданный хост, а в IDE key пишем PHPSTORM. Жмет OK.

    Настройка отладки PHP
    Настройка отладки PHP

    Переходим к настройке браузера. Нужно установить расширение Xdebug helper из магазина расширений Google Chrome.

    Xdebug helper в магазине Google Chrome
    Xdebug helper в магазине Google Chrome

    После того, как установили Xdebug helper кликаем по нему правой клавишей и выбираем Параметры.

    Переходим в параметры Xdebug helper
    Переходим в параметры Xdebug helper

    В открывшихся настройках нас интересует параметр IDE key. Выбираем PhpStorm, т.к. его же мы указали при настройке ранее.

    Параметры Xdebug helper
    Параметры Xdebug helper

    Теперь на странице хоста кликаем по иконке Xdebug helper и выбираем Debug. В моем случае хост будет plastpoliefir.lan. Жук должен загореться зеленым цветом.

    В PhpStorm в правом верхнем углу также кликаем по жуку.

    Теперь в проекте можно поставить точку остановки и сделать запрос в браузере.

    Точка остановки в PhpStorm
    Точка остановки в PhpStorm

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

    Приложение остановилось там, где мы и хотели.
    Приложение остановилось там, где мы и хотели.

    Так же можно посмотреть содержимое массивов и объектов.

    Содержимое объекта в PhpStorm.
    Содержимое объекта в PhpStorm.

    Также в панели отладки можно посмотреть глобальные переменные, консоль, ответ нашего HTTP сервера и многое другое.

    Панель отладки
    Панель отладки

    На этом настройка связки Xdebug + OpenServer + PhpStorm закончена. Надеюсь данная вам статья была полезна.

    Пагинация массива в Laravel

    Пагинация массива в Laravel

    Пагинация массива в Laravel

    Пагинация массива в Laravel достаточно делается легко при помощи класса LengthAwarePaginator.

    // Импортируем класс
    use Illuminate\Pagination\LengthAwarePaginator as Paginator;
    
    // Получаем текущую страницу
    $currentPage = Paginator::resolveCurrentPage();
    // Создаем коллекцию
    $collection = collect($categories);
    // Задаем кол-во элементов на страницу
    $perPage = 15;
    // Выбираем элементы для текущей страницы
    $currentPageItems = $collection->slice(($currentPage - 1) * $perPage, $perPage);
    
    // Создаем экземпляр класса Paginator
    $items = new Paginator($currentPageItems, count($collection), $perPage);
    // Указываем URI для генерации ссылок пагинации
    $items->setPath($request->url());
    
    // Возвращаем представление
    return view('pagination', compact('items'));

    В представлении для вывода пагинации используем как и в обычной пагинации $items->links().

    <!doctype html>
    <html lang="ru">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Пагинация массива</title>
    </head>
    <body>
    @foreach($items as $item)
        {{ $item['name'] }} <br>
    @endforeach
    
    {{ $items->links() }}
    
    </body>
    </html>