• Как верстать сайты на двух языках?

    vabka
    @vabka
    Токсичный шарпист
    Обычно это разруливается на уровне шаблонизатора.
    Ты верстаешь как обычно, но в местах, где тебе нужно вставить текст, ты будешь вставлять плейсхолдер.
    Потом, в отдельном файле, в зависимости от шаблонизатора, будут перечислены сопоставления плейсхолдер->текст

    Шаблонизатор потом уже либо сгенерирует тебе N файлов для разных языков, и тебе нужно будет на стороне веб-сервера разрулить, какие файлы отдавать, либо этим будет заниматься бэкенд, либо фронтовый фреймворк.

    Код в итоге будет что-то типа:

    index.html:
    <div>
      <p>{{text}}</p>
    </div>


    i8n/ru.json:
    {
      "text": "Привет мир!"
    }


    i18n/en.json:
    {
      "text": "Hello world!"
    }


    i18n/es.json
    {
      "text": "Hola mundo!"
    }


    Но если у тебя появляются динамические данные, нужна поддержка right-to-left языков, и вообще нужна адаптация под разные регионы (типа чтобы условный Американец и условный Китаец получали разный UX), то всё будет немного сложнее. Гугли дальше по словам "Интернационализация" и "Локализация"
    Ответ написан
    5 комментариев
  • Не могу найти ошибку почему не приходят письма?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Проверьте свои письма здесь: https://www.mail-tester.com/
    Скорее всего, получите 1/10
    А дальше исправляйте каждый пункт. Начать, скорее всего, придётся с отказа от штатного mail и перехода на PHPMailer с отправкой через SMTP-сервер яндекса.
    Ответ написан
    Комментировать
  • Как лучше сделать добавление корзины/избранного?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Все очень просто.
    Надо всего лишь различать зарегистрированных и незарегистрированных пользователей.
    Для первых ничего не пишется на клиента, а только в базу.
    Для вторых ровно наоборот - в базу писать нечего, поэтому все сохраняется локально.
    Плюс нужна процедура мержа с клиента в базу, когда в момент авторизации что-то есть локальное. По уму надо у пользователя спросить, "вот такие-то товары были в корзине, добавить их к вашей?" Но многие магазины не заморочиваются и просто сливают локальную корзину с той что лежит в базе.
    Ответ написан
    9 комментариев
  • Как отключить авторизацию от google?

    ramzis
    @ramzis
    FullStackOverflow
    Здесь Google Account

    6464684c83664928973466.png
    Ответ написан
    Комментировать
  • Как отрисовать страницу при асинхронном POST запросе?

    Stalker_RED
    @Stalker_RED
    Если страница с формой и главная - это одна и та-же страница, то достаточно location.reload()
    Если разные страницы - редирект.

    Если у вас SPA - то можете и в самом деле body заменить, но однажды вам захочется бросить самодельный SPA и перейти на какой-то из SPA-фреймворков.
    Ответ написан
    Комментировать
  • Два IP на одном домене. Как настроить переадресацию?

    vabka
    @vabka
    Токсичный шарпист
    Это разруливается не через DNS, а через балансировщик.
    У тебя будет, получается, три узла: Основной, Резервный, и Балансер.
    В DNS ты прописываешь балансер (через A/AAA или CNAME - не важно).
    Все запросы от клиентов идут на Балансер и он их пересылает на основной.
    В случае сбоя, Балансер каким-то образом выясняет состояние основного узла (может прямо запрашивать периодически какой-нибудь GET /health или смотреть на ответы, которые он даёт клиентам), и перераспределяет запросы на Резервный в случае, когда был выявлен сбой, и наоборот - в случае сбоя Резервного можно попробовать перенаправить запросы снова на Основной (тут уже как настроишь).

    Попытаться обойтись без балансера можно, но тогда ты столкнёшся с той ситуацией, с которой ты столкнулся:

    При коннекте к www.site1.ru провайдеры через раз подключаются к правильному айпи, то к основному, то к резервному.
    Соответственно где то на сайт заходит, где то нет так как конектится ко 2 айпи который в текущий момент сервер не использует.

    И уйти от этого не получиться, тк это не баг, а фича - DNS сервер провайдера будет кэшировть информацию о записях в твоём домене, чтобы не нагружать твой сервер лишними запросами и быстрее отдавать ответ своим абонентам, при этом при кэшировании может учитываться тот TTL, который ты сам указал.
    + Кэширование может, и скорее всего будет в том числе и на стороне конечного клиента.

    Придирки к терминологии

    Не существует "DNS регистраторов". Есть просто регистраторы, которые говорят что домен принадлежит тебе и позволяют назначить dns-сервера, которые будут этот домен обслуживать.
    И есть отдельно dns-хостинги, где ты можешь прописать различие записи в рамках домена.
    Ответ написан
    5 комментариев
  • Как добавить запись на json файл?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Что я делаю не так?
    Пытаетесь решить проблему сервера на клиенте, да ещё и не анализируя логи.
    Ответ написан
    Комментировать
  • Что делать если не задаётся бэкграунд на nav?

    MrDecoy
    @MrDecoy Куратор тега CSS
    Верставший фронтендер
    Что значит "не задаётся бэкграунд"? Всё накидывается и работает в соответствии с тем, что указано в css.
    У nav белый фон, у списка внутри - серый, согласно универсальному селектору
    * {
        box-sizing: border-box;
        background: #E5E5E5;
    }
    (без чёткого понимания всех нюансов этого селектора использовать его не рекомендуется).
    Ответ написан
    3 комментария
  • Почему это условие не работает?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    Условие срабатывает как и положено.

    Писать что-то в массив $_POST не имеет смысла, он будет всегда создан новым при следующем запросе.
    Точно так же между запросами не сохраняются переменные. И получается, что вы каждый раз сбрасываете счетчик в ноль, а тут же увеличиваете его до единички.

    Данные между запросами можно хранить в сессии.

    session_start();
    $num = $_SESSION['num'] ?? 0;
    $num++;
    
    $_SESSION['num'] = $num;

    Или передавать через ту же форму

    $num = (int)($_POST['num'] ?? 0));
    $num++;
    
    <input type="hidden" name="num" value="<?=$num?>">
    Ответ написан
    Комментировать
  • Как исправить кракозябры вместо кириллических символов при записи переменной в сессию?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    При соединении с БД надо указывать кодировку.
    Поскольку на сайте используется юникод, то соответственно указывать надо utf8mb4

    А сессии тут вообще не при чем.
    Ответ написан
    1 комментарий
  • Как грамотно сделать обработку ислючений в php?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Структура проекта какая-то странная, в нем, судя по всему, контроллером называется роутер, но на этом я останавливаться не буду, обработка исключений от этого не зависит.

    Основных правил при обработке исключений три:
    1. Не использовать исключения там, где они не нужны. Например, при проверке пользовательских данных.
    Собственно, эмпирическое правило звучит так: функция должна бросать исключение, если она не может выполнить ту работу, для которой она предназначена.

    Отсюда сразу становится понятно, что для функции, которая должна проверять введенные данные, наличие ошибок в них не является исключительной ситуацией. А совершенно штатной. И обеспечивается штатными же средствами. По результатам проверки пользователю просто отправляется ответ, что данные неверны, безо всяких исключений. В нормальной структуре проекта этим занимается контроллер.

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

    2. Системные ошибки обрабатывает глобальный обработчик исключений, логируя саму ошибку, а на клиент отправляя статус 500 и какое-нибудь абстрактное сообщение о проблеме на сервере. Это самое важное в системных исключениях - текст ошибки никогда, не при каких обстоятельствах не уходит наружу.

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

    3. Пользовательские исключения, там где они нужны, обычно обрабатываются по месту, но есть нюансы.
    Собственно, под обработкой исключений часто понимают два разных действия:
    - собственно обработку, когда программа совершает какие-то действия, чтобы нивелировать негативный эффект. Например, если не удалось подключение к какому-то сервису, то либо попробовать подключиться к другому, либо просто подождать и попробовать снова.
    - простое информирование пользователя

    Для информирования можно действительно ловить исключение через try..catch и писать какое-то свое сообщение.
    Но можно и автоматизировать этот процесс, вот две статьи, которые показывают примеры, как это можно сделать:
    https://angelovdejan.me/2022/11/24/centralized-exc...
    https://habr.com/ru/articles/688202/
    Ответ написан
    Комментировать
  • Как сделать что бы в одно модальное окно выводился разный контент?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    ну элементарно вроде:
    Клик по кнопке -> Запрос данных -> Вставка данных в модалку -> Отображение модалки.
    Ответ написан
    4 комментария
  • Вопрос с собеседования: Есть ли в PHP нативная возможность инициализировать переменную как в функции preg_match()?

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

    С помощью амперсанда & мы можем заставить передавать ссылку на эту же переменную в памяти. И тогда манипуляции с ней внутри функции будут равны манипуляциям вне.

    С объектами не большая путаница происходит, но только из-за того что многие не думают/забывают что хранится в переменной когда создаётся объект. При создании объекта в саму переменную помещается его идентификатор, по которому php и обращается к этому объекту.
    Ну и соответственно при передаче такой переменной в функцию, мы копируем этот идентификатор в новую переменную. Переменная уже другая, независимая от той что была, но идентификатор объекта тот же. Поэтому манипуляции с объектом в функции(обращение к свойствам/методам) отразятся на объекте с этим идентификатором. И со стороны выглядит словно переменная с объектом всегда передаётся по ссылке(словно стоит амперсанд), но это не так. Например внутри функции вы перезапишете переменную(к примеру присвоите null) то оригинальная переменная с объектом не поменяется.

    А вот есть если передать её по ссылке, те с амперсандом, то внутри функции будет переменная со ссылкой на переменную вне, и поэтому не только манипуляции с объектом, но и перетирание переменной в целом повлияет.

    class A {
        public $foo = 1;
    }
    
    //создали переменную
    //в ней хранится id объекта, сам объект где-то в памяти оптимизированно лежит
    $newObj = new A;
    
    //Вывод 1
    echo $newObj->foo;
    
    function foo($obj) {
    	//в obj скопирован id объекта
    	//тк он тот же, то меняется и оригинальный объект
    	$obj->foo = 2;
    	//локальная переменная перетёрся, больше id объекта не хранит
    	//на внешнюю не повлияло
    	$obj = null;
    	
    }
    
    foo($newObj);
    // получили 2
    echo $newObj->foo;
    
    
    function bar(&$obj) {
    	//obj ссылается на тоже место в памяти, что и внешняя переменная с id объета
    	//тк он тот же, то меняется и оригинальный объект (тут логично, тк по ссылке)
    	$obj->foo = 2;
    	//локальная переменная перетёрся, больше id объекта не хранит
    	//внешняя тоже перетрётся
    	$obj = null;
    }
    
    
    bar($newObj);
    //ошибка предупреждение, нельзя читать свойства на null
    echo $newObj->foo;


    Ну и зная всё это, вы можете написать свою простую функцию, по типа прегматча.
    function mySum($a, $b, &$result) {
    	$result = $a + $b;
    }
    //первые два параметра по значению, в третий передаём переменную
    //она тут же инициализируется (как если бы её до этого написать просто $res;)
    // и передаётся её ссылка внутрь функции
    mySum(1,2, $res);
    
    //3
    echo $res;
    Ответ написан
    Комментировать
  • Зачем для кеширования использовать Redis, если можно сделать файловое кеширование?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Вы очень узко понимаете понятие кэширования.
    И забываете о том, что из кэша не только читают, но в него еще и пишут.
    в .php файлах эффективнее хранить не кэш, а какую-то статичную информацию, которая редко изменяется (скажем, только при деплое), и при этом общую для всех пользователей. При соблюдении этих условий кэширование в .php файлах вполне себе используется.

    Но понятие кэша гораздо шире. Кэшироваться может и специфичная для конкретного пользователя или запроса информация. В этом случае никаких .php файлов не напасешься.

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

    Еще одна причина, не главная, но все равно важная - масштабирование. Один сервис редиса можно использовать с несколькими инстансами РНР. Плюс сам редис можно масштабировать на несколько физических инстансов.
    Ответ написан
    Комментировать
  • Используется ли шаблонизатор в проде?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    И так и так.
    Чаще всего используется традиционный рендеринг на бэке, но если кто хочет помоднявее, или чтобы не тратиться на отдельные версии для мобильного приложения, то делают рендеринг на фронте.

    Как пользователь, я ненавижу рендеринг на фронте, на практике он ВСЕГДА тормозит.
    За примером далеко ходить не надо, это новый дизайн Хабра.

    Вы, кстати, неправильно понимаете термин "прод".
    Продакшен окружение относится не к коду, а к тому, где он выполняется
    В локальном окружении разработчик пишет и отлаживает программу
    Тестовое (стейдж) окружение полностью имитирует боевой сервер, но доступно только разрабочикам/тестировщикам/заказчикам
    И, наконец, продакшен - собственно рабочий сервер, который находится под реальной нагрузкой
    А код везде один и тот же.
    Ответ написан
    3 комментария
  • Чей ip адрес адрес будет приходить?

    @AUser0
    Чем больше знаю, тем лучше понимаю, как мало знаю.
    Конечно IP-адрес удалённого сервера, с которого создалось соединение. Посетитель удалённого сервера к такому соединению имеет отношение только в том, что соединение создаётся для получения данных для этого посетителя.
    Ответ написан
    Комментировать
  • Как превратить текст в исполняемый код?

    Stalker_RED
    @Stalker_RED
    Если это задание с курсов, то скорее всего они хотели вас научить использовать eval().

    Но стоит отметить, что использование eval() очень часто приводит к образованию дыры в безопасности, т.к. если пользователь впишет вместо A = 1 какю-нибудь строчку повеселее, типа A = 1; exec(rm -rf /)*, то можно огрести проблем.

    * - код намеренно неработающий.
    Ответ написан
    1 комментарий
  • Как сделать уведомление о завершении работы скрипта?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Этот вопрос не имеет отношения к РНР.
    А только к базовым навыкам работы с операционной системой.
    В простейшем случае можно написать бат файл, в котором под своей командой пишете любую другую, от проигрывания звукового файла до запуска любой программы. Которая выполнится по завершении первой
    Можно то же самое написать в одну строчку php my.php & echo ^G
    После амперсанда опять же, пишется все что угодно.

    писать set_time_limit(0) в консольоных скриптах кстати не нужно. Там лимита нет по умолчанию
    Ответ написан
    Комментировать
  • Как почистить кеш редиректов у пользователей сайта?

    YBB
    @YBB
    Боюсь, что никак не очистить. Тут свой браузер порой чуть ли не ногами бить приходится, чтобы забыл об уже неактуальном редиректе.
    Попробуйте использовать не 301 (постоянный), а 302 (временный) редирект — он не должен вообще кэшироваться. В теории.
    Ответ написан
    1 комментарий
  • Почему PHP не исполняется построчно, хотя он интерпретируемый?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Изначально интерпретируемые языки преобразовывались в машинный код построчно, то есть каждая логическая строка компилировалась непосредственно перед выполнением. В результате каждая инструкция, заключенная в тело цикла и исполняемая несколько раз, столько же раз обрабатывалась транслятором. В настоящее время такие эффекты редки. Большинство интерпретируемых языков предварительно транслируются в промежуточное представление. Оно представляет собой байт-код. Это набор инструкций по вызову небольших фрагментов более низкоуровневого кода, эквивалентный нескольким командам ассемблера или командам виртуальной машины соответственно. Уже этот код исполняется интерпретатором или виртуальной машиной.
    Ответ написан
    5 комментариев