Задать вопрос
  • Как деплоить php приложение вместе с docker?

    Vamp
    @Vamp
    Это типичный вариант развёртывания приложения в докере. Единственный его минус - некоторое время даунтайма между моментом когда опустился старый контейнер и поднялся новый. Для решения этой проблемы есть разные техники. Например, blue-green deployment. Это когда есть два контейнера, условно называемые green и blue. И трафик льётся только на один. Скажем, на green. В момент деплоя обновляется blue контейнер и после того как он полностью будет готов - переключаем трафик на blue. В следующий раз деплой начнётся с обновления green.

    Переключение трафика делается разными способами. Самый безопасный - переписать конфиг nginx и релоаднуть его. Или менее безопасный, зато без необходимости править конфиг, - добавить оба конейнера в одну upstream группу и опустить green контейнер после обновления blue.

    Довольно муторное дело. Но в оркестраторах типа openshift и kubernetes такой деплоймент процесс уже встроен из коробки. Но вот сами оркестраторы довольно тяжелая штука. Для них нужен отдельный выделенный человек, который будет заниматься только ими. Так что я советую начинать присматриваться к оркестраторам только когда количество серваков перевалит за 50. С меньшим количеством это просто нерентабельно.

    Другой вариант развёртывания - контейнер с пхп поднят постоянно, но код проекта монтируется в контейнер через volume. Далее ci джоба по sftp заливает новый код в соседнюю папку и переключает симлинк. Симлинк переключается атомарно и контейнер сразу начинает работать с новым кодом. Ничего больше делать не надо. Я рекомендую такой подход когда на проекте менее 50 серверов.
    Ответ написан
    4 комментария
  • Почему компилятор выдает ошибку error: expected declaration or statement at end of input?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Пропущена закрывающая фигурная скобка в print_arr
    Ответ написан
    Комментировать
  • Как добавить новый домен на хостинг?

    borisdenis
    @borisdenis
    Ленив и вреден...
    На скриншоте есть запись CNAME, а где запись типа А для nuruddin.dev с ip адресом, на которую этот CNAME должен ссылаться?

    Ну и после смены NS серверов должно пройти пару суток, пока все днс сервера обновят свои записи
    Ответ написан
    Комментировать
  • Как установить старый проект на Windows?

    borisdenis
    @borisdenis
    Ленив и вреден...
    Верстаете в Windows, докер в виртуалке с Linux (или наоборот), всё работает.
    Ответ написан
    2 комментария
  • Как почистить базу sql?

    borisdenis
    @borisdenis
    Ленив и вреден...
    На серваке установлена Microsoft SQL Server 2014 с лимитом в 10гб

    Это у вас установлена бесплатная Express версия. Вам либо удалять старые данные из базы, либо повышать редакцию до платной версии.
    Если в программе нет штатной функции по очистке от старых данных - то вам нужно обращаться в техподдержку, так как это косяк проектировщиков, которые выбрали базу не продумав периодическую очистку, чтоб избежать сложившейся ситуации.
    Ответ написан
    Комментировать
  • Как эффективно перейти на c++ при опыте работе с php?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    Посоветуйте, как можно было бы максимально безболезненно восполнить утраченные знания, а также наверстать упущенные новшества в языке?

    так это...
    Сейчас хочу попробовать реализовать научный проект.
    Собсно практика - лучший учитель, садитесь и пишите. Если базу уже знаете реализация не станет проблемой. По ходу решения текущих задач проекта познакомитесь со всеми нужными изменениями и практиками, сегодня на любой чих есть дока, туториал, видео и чатжпт. Двух зайцев двумя плюсами, так сказать...
    Ответ написан
    Комментировать
  • Как правильно использовать гит, если нужны данные из другой ветки?

    GavriKos
    @GavriKos
    А тут скорее не с гитом траббла, а с процессом.
    Еслиу тебя две задачи, одна залочена на другую - то почему ты взял залоченную задачу? Жди пока разлочится :-)

    Раз уж завезли гитфлоу и тестирование в ветках - то идите с этим до конца ;-)
    Ответ написан
    Комментировать
  • Как разбить многомерный массив на несколько по ключам?

    0xD34F
    @0xD34F
    $grouped = [];
    
    foreach ($arr as [ 'id' => $id, 'name' => $name, 'key' => $key ]) {
      $grouped[$key][$name] ??= [ 'name' => $name, 'ids' => [] ];
      $grouped[$key][$name]['ids'][] = $id;
    }
    
    foreach ($keys as $k) {
      $$k = array_map(fn($n) => [
        'name' => $n['name'],
        'ids' => implode(', ', $n['ids'])
      ], array_values($grouped[$k] ?? []));
    }
    Ответ написан
    1 комментарий
  • Проблемы с ядром от ИСП РАН?

    ky0
    @ky0
    Миллиардер, филантроп, патологический лгун
    Возможно. Но будет:

    1) Высокая нагрузка в простое
    2) Характерный свист дросселей
    3) Не работать Wi-Fi
    Ответ написан
    Комментировать
  • Почему сайт не загружается с DNS over HTTPS?

    Stepashka20
    @Stepashka20 Автор вопроса
    (☞゚ヮ゚)☞
    Решил

    Во всём виноват РКН: https://habr.com/ru/news/856342/

    Отключил TLS1.3 в панели cloudflare и всё заработало
    Ответ написан
    4 комментария
  • Где найти "нормочасы" по работам с сайтом?

    xez
    @xez
    TL Junior Roo
    Вы путаете разработку и эксплуатацию.
    В вашей аналогии должна быть стоимость проектирования и производства автомобиля

    В эксплуатации можно придумать какие-то нормы.
    А в разработке - нет .
    Ответ написан
    Комментировать
  • Как понять что скрипт перестал работать после того как развернули браузер?

    alsolovyev
    @alsolovyev
    ¯\_(ツ)_/¯ Enjoy life, Eat well & Laugh often
    Я запутался в том, что хочу сделать.

    Одному вам известно, что у вас на уме

    но знаю что setTimeout работает криво,

    Современные браузеры снижают частоту таймеров, чтобы сэкономить ресурсы. Поэтому и "криво" работает как вам кажется. Аналогично "криво" будет работать любой требующий ресурсов код - WebSocker и тд.

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

    Это проблемы у вас в коде

    Как мне перезапускать скрипт после развертывания браузера телефона

    0. Вынесите реализацию подключения к websocket'у в отдельную функцию и проверяйте состояние соединения перед каждым действием:
    let socket;
    const url = "ws://your-websocket-server-url";
    
    function connect() {
      socket = new WebSocket(url);
      socket.onopen = () => {};
      socket.onmessage = (event) => {};
      socket.onerror = (error) => {};
      socket.onclose = (event) => {};
    }
    
    function reconnect() {
      if (socket && socket.readyState !== WebSocket.CLOSED) return;
      .....
    }
    
    function send(message) {
      if (socket && socket.readyState === WebSocket.OPEN) {
        socket.send(message);
        return
      }
      console.warn("WebSocket is not open. Message not sent:", message);
      ....
    }

    1. Отправляйте переодически ping сообщение для проверки состояния соединения. Если нет ответа, переподключаемся (и проверяем состояние соединения перед переподключением).
    2. Добавьте слушатель visibilitychange для отслеживания "развертывания" вкладки:
    document.addEventListener('visibilitychange', () => {
        // document.hidden
        if (document.visibilityState === 'visible' && websocket.readyState === WebSocket.CLOSED) {
            reconnect();
        }
    });


    ps забыл упомянуть про PushAPI если необходимо получать сообщения в фоновом режиме (94.65% на caniouse):
    API to allow messages to be pushed from a server to a browser, even when the site isn't focused or even open in the browser.
    Ответ написан
    1 комментарий
  • Как заполнять поля на html-странице из функции на php?

    @Refguser
    Решения для бизнеса: от создания ИМ до...
    Спасибо

    Пожалуйста
    Ответ написан
    Комментировать
  • Сопровождение сайтов на абонентской основе - что это на практике сейчас?

    opium
    @opium
    Просто люблю качественно работать
    Тем же самым что и раньше, поддерживаем сайты, просто раньше хостинг вордпрес и прочее любым было не понятно и были готовы платить чтобы не разобраться, сейчас понятное дело мелким сайтам нафиг поддержка не нужна, а крупным или мелким но денежным нужна, так как лежащий сайт нанесет сотни тысяч убытков когда поддержка будет стоить несколько тысяч в месяц
    Ответ написан
    Комментировать
  • Как обрабатывать данные, сохраняя очередность?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    Создайте отдельную очередь, в обработчике хука кладите туда задание и обрабатывайте её в один поток.
    Т.е. примерно то, что описал Виктор Кожухарь, только готовыми средствами фреймворка.
    Ответ написан
  • Как обрабатывать данные, сохраняя очередность?

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

    Далее по крону или каким-то другим образом совершенно другой скрипт будет выбирать самую старую запись из этой таблицы и обрабатывать её, совершая необходимые действия. Далее эту запись либо удаляем либо помечаем обработанной и берём следующую запись
    Ответ написан
    4 комментария
  • Как изменить набор ключей в массиве?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кого на что меняем, объект вида { 'старый ключ': 'новый ключ' }:

    const keys = {
      x: 'a',
      y: 'b',
      z: 'c',
    };

    Собираем новый массив:

    const renameKeys = (obj, keys) =>
      Object.fromEntries(Object
        .entries(obj)
        .map(([ k, v ]) => [ Object.hasOwn(keys, k) ? keys[k] : k, v ])
      );
    
    // или
    
    const renameKeys = (obj, keys) =>
      Object.keys(obj).reduce((acc, k) => (
        acc[keys[k] ?? k] = obj[k],
        acc
      ), {});
    
    
    const newArr = arr.map(n => renameKeys(n, keys));

    Обновляем существующий:

    function renameKeys(keys, obj) {
      for (const k in keys) {
        if (obj.hasOwnProperty(k)) {
          obj[keys[k]] = obj[k];
          delete obj[k];
        }
      }
    }
    
    
    arr.forEach(renameKeys.bind(null, keys));
    Ответ написан
    Комментировать
  • Как решить Fatal error: Uncaught Error: Call to undefined function pll_register_string()?

    402d
    @402d
    начинал с бейсика на УКНЦ в 1988
    в подобных случаях помогает гугл.
    pll_register_string - и в выдаче видим, что это плагин вордпресса.
    Раз плагин, то проверяем он стоит ли вообще ?
    Дальше от гуглим запросы его название (Polylang) и что там не работает
    Ответ написан
    7 комментариев
  • Как сохранять клики и их время в кликере?

    @rPman
    вместо условных 100 кликов людям засчитывало ~40
    судя по sql у тебя количество сохраняемых кликов считается как сначала запросом получить текущее значение, затем сохранить его увеличенным... что естественно неправильно обсчитывается, если одновременно на бакэнд идут несколько запросов, и завершаются в разном порядке (т.е. первый, получил значение 1, затем его обогнал второй, получил то же значение 1, оба отправляют +1 значение, т.е. 2, вместо ожидаемого 3.

    Правильно: одним обновлением в базе нужно - проверять допустимость клика (проверить время последнего клика), обновить время последнего клика и увеличить количество кликов на 1... после чего бакэнд проверяет, сколько записей было обновлено, если 0 - значить выход за лимиты, если 1 - все ок.
    update set clicks=clicks+1, last_click_time=now() where last_click_time+:ALLOWED_CLICK_INTERVAL<now() and id=:current_id


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

    Можно больше, но тогда понадобится разнести таблицу аналитики и таблицу событий, в таблицу событий записывают события, но она без индексов, а в аналитику зааливать данные из всех собранных событий, в цикле
    Ответ написан
    Комментировать
  • Почему метод pop удаляет не все елементы массива?

    Wispik
    @Wispik
    1. Нельзя итерироваться по объекту и одновременно изменять его
    2. pop удаляет с конца, а for of идет по массиву сначала

    Первая итерация цикла number=3, pop удаляет с конца, то есть 5
    вторая итерация number=8, pop удаляет 9
    и так далее
    когда number=6(четвертая итерация), 6 - это последний элемент массива, так как остальные удалил pop
    Ответ написан
    2 комментария