• Как в PHP поймать ошибки?

    @Barrakuda74 Автор вопроса
    В данный момент речь не об исключениях, об ошибках.
    Про set_error_handler знаю, но не вижу смысла писать свой обработчик, когда мне нужно отловить ошибки только при выполнении одной единственной функции, хоть и большой. Хочу засунуть просто функцию в try catch, и если что-то пойдёт в ней не так, я об этом узнал.

    Да, у меня php 7.2.
    А что, у вас работает?
    Здесь - phptester.net- тоже не работает. Там 7.0 (т.е. должно якобы работать).
    try {
    	$y = $x;
    } catch(Throwable $t) {
    	echo 'Ошибка';
    }
  • Как в PHP поймать ошибки?

    @Barrakuda74 Автор вопроса
    а если вместо
    Throwable $t
    поставить
    \Exception $e


    sidni, так только исключения будут пойманы. С ошибками не работает.
    Здесь можно потестить.
    try {
    	$y = $x->parameters;
    } catch(Exception $e) {
    	echo 'Ошибка';
    }
  • Как в PHP поймать ошибки?

    @Barrakuda74 Автор вопроса
    Что, аналога исключениям с try-catch для ошибок нет?
  • Чем отличается date от MailDate в заголовках писем imap?

    @Barrakuda74 Автор вопроса
    date (udate) может прийти с неправильным временем я так понимаю, т.к. эту строку напрямую прописывает сервер отправителя, т.е. трудно ориентироваться на это значение, время может быть выставлено неправильно. MailDate вообще хрен пойми чего, RFC составляли какие-то инвалиды-склерозники... Где-то вообще пишут, "The two date values in there (Date and MailDate) are not really reliable, and should be avoided", а на чё, _лять, тогда ориентироваться, по рунам чтоли гадать
  • Как наименее затратно мониторить в цикле наличие новой информации?

    @Barrakuda74 Автор вопроса
    Хотя... я вот теперь так подумал, может записывать в mysql не такая уж и плохая затея)))
  • Как наименее затратно мониторить в цикле наличие новой информации?

    @Barrakuda74 Автор вопроса
    (в таком случае правда непонятно, зачем вообще куда-то писать, где отлавливается факт звонка - оттуда и слать сразу пуш)

    Как это непонятно, один маленький скрипт отлавливает события телефонии и пишет их в БД, другой общается с SSE. Из первого не передать сообщение клиенту, он не прослушивается SSE.

    Но ваш посыл да, немного стал понятен. При работе с файлами нужно лочить файл на некоторое время. Быстренько нагуглил, реализовать можно примерно так:
    $fp = fopen ("path_to_file","a");//открытие 
    flock ($fp,LOCK_EX);//блокировка файла 
    ftruncate ($fp,0);//УДАЛЯЕМ СОДЕРЖИМОЕ ФАЙЛА 
    fputs($fp ,"$data\r\n");//работа с файлом 
    fflush ($fp);//очищение файлового буфера и запись в файл 
    flock ($fp,LOCK_UN);//снятие блокировки 
    fclose ($fp);//закрытие


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

    @Barrakuda74 Автор вопроса
    RabbitMq, memecache, Redis, Laravel...

    Неужели больше никак не сохранить одну строку с названием клиента?
    Сразу почему-то вспомнился один комментарий из свежей статьи на хабре.
    Объясните лучше чем так плоха простая запись в файл? Может я просто чего-то не знаю такого страшного про файлы, что все от них так шарахаются? Экзотики никакой нет на сервере, стоит стандартная связка apache, mysql и php.
  • Как наименее затратно мониторить в цикле наличие новой информации?

    @Barrakuda74 Автор вопроса
    > есть цикл в server sent events, он проверяет каждые 500мс
    Почему сами лезете к апи ? Калбаки есть ?

    Неправильно выразился. цикл конечно на сервере, не в sse.
    > Ясно что не в БД,
    Нет файлы хуже .

    А БД разве не тот же файл, только большой?

    используем WebPush https://fcm.googleapis.com/fcm/send

    Зачем здесь сторонний сервис? Нам своего сервера чтоли мало для хранения одной строки с названием клиента?
  • Как наименее затратно мониторить в цикле наличие новой информации?

    @Barrakuda74 Автор вопроса
    Хотелось бы чего-то нейтивного. Задача-то простая, не вижу смысла раздувать стек технологий.
  • Как корректно распознать timestamp формата YYYYmmddTHHMMSSZ?

    @Barrakuda74 Автор вопроса
    Спасибо. Почему-то думал что сразу вот так в лоб не распознает такой формат, оказывается распознаёт :)
  • Как перевести utc время в локальное для каждого пользователя (на js)?

    @Barrakuda74 Автор вопроса
    Может быть есть пример как из строки вида "2018-07-31 14:50:45" получить "2018-07-31 17:50:45"? После того как выяснили смещение всмысле.
  • Как вывести юзеру одноразово сообщение после редиректа/submit в PHP?

    @Barrakuda74 Автор вопроса
    Ясно, знач всё-таки просто складируем сообщения в сессию.
  • Как выглядит логика простой системы авторизации с "выходом на всех устройствах"?

    @Barrakuda74 Автор вопроса
    xmoonlight, отправил свой емейл через форму заказа рекламы на googledocs, а на сайте что-то лазил-лазил, но емейл так нигде и не нашёл))
  • Как выглядит логика простой системы авторизации с "выходом на всех устройствах"?

    @Barrakuda74 Автор вопроса
    xmoonlight, до меня дошло наконец-то:)))) У вас просто так много переменных, они сбили меня с толку) Там видите у нас просто две рандомные строки (у AHTUxPK). Плюс user_id у него скорее всего то же имеется в виду, что и у меня (а у меня это обычно простые числа по порядку 1,2,3,4 и т.д. [которые в таблице "users" идут первой автоинкрементной колонкой с названием ID]), т.е. номер, по которому мы потом получаем данные юзера из другой таблицы ("users"). А у вас userID это сложный алгоритм из хэша(логин+пасс), я если честно не вижу просто дальнейшего применения получившейся строке, вроде как обычная рандомная строку получается. Что касается идентификатора устройства, то тоже почему-то не вижу применения. Подскажите если что почему лучше их использовать чем просто рандомные строки.
    Итак. Извиняюсь что немного упросил вашу схему, хочу просто понять как работает. В БД у нас что-то вроде такого:
    users, напр столбики.:
    id   email       login       hash_pass(bcrypt от пароля)
    1    ll@i.ru     vasya       s2rg22eg
    2    ii@i.ru     petya       de45uymn

    ---
    sessions, напр столбики.:
    id  userid(=id из табл users)       type(0-session,1-account)           token                                            timestamp
    1   1                               0                                   sessionToken	
    2   1                               1                                   password_hash(accountToken)

    ---
    Пояснение к формированию token для БД:
    function randomStr(length) {...}; // форм. случ. строки
    $sessionToken = random(30); // В БД попадает в чистом виде
    $accountToken = random(30); // В БД попадает password_hash($accountToken)

    При первой авторизации в БД пишем то что выше только что написал, а в куку пишем:
    setcookie('token', $userID . ":" . $accountToken) // $userID здесь и далее просто порядковый номер из таблицы users (колонка ID)

    В сессию пишем 3 переменные:
    $_SESSION['userID'] = $userID;
    $_SESSION['session_token'] = $userID . ":" . $sessionToken . ":" . $accountToken;
    $_SESSION['ip'] = $userIP; // текущий IP
    $_SESSION['UA'] = $userUA; // текущий UserAgent


    При след. запросе проверяем:
    if (isset($_SESSION['session_token'])) {
        // делим составной токен на 3 части (через двоеточие) и раскидываем по переменным
        // $userIDfromSession, $sessionTokenFromSession, $accountTokenFromSession;
        if ($_SESSION['ip'] != $userIP && $_SESSION['UA'] != $userUA) {
            // заставляем авторизоваться (т.е. если сменился одновременно IP и UserAgent)
        }
        // достаём токены из БД через $userIDfromSession, получаем переменные: $sessionTokenFromBD, $accountTokenHashFromBD
        if ($sessionTokenFromSession == sessionTokenFromBD) { // проверка сессионного токена
            if (password_verify($accountTokenFromSession, $accountTokenHashFromBD)) { // проверка аккаунтского токена
                // успешно авторизован (тут правда ещё проверка на срок login_time)
            } else {
                // заставляем авторизоваться (если сменился аккаунтский токен: logout, сброс пароля и т.д.)
            }
        } else { // если сессионный не подходит
            // вот здесь я не знаю нужно ли пытаться восстановить авторизацию по аккаунтскому токену из той же сессии или
            // из куки, если он не подходит или просрочен, или вообще сразу заставить авторизоваться...
        }
    } elseif(isset($_COOKIE['token'])) {
       if (password_verify($_COOKIE['token'], $accountTokenHashFromBD)) {
           // успешно авторизован (тут правда ещё проверка на срок login_time)
           // и заполняем сессионные данные
       }
    } else {
        // заставлям авторизоваться
    }


    При logout, сбросе пароля, блоке пользователя и т.д. генерируем новый accountToken, получаем его хэш через password_hash и получившийся результат засовываем в БД (таблицу sessions) через:
    UPDATE `sessions` SET token=$NewHashaccountToken WHERE userid=$userID and type=1;


    Сильно ли промахнулся?)
  • Как нынче защищают/валидируют сессии (useragent, ip) и нужно ли это вообще?

    @Barrakuda74 Автор вопроса
    Вряд ли внутри одной сессии поменяется и браузер, и IP одновременно.
    Поэтому, при ОДНОВРЕМЕННОЙ смене: IP и User-Agent (всё - относительно текущей сессии) - можно смело обрывать все сессии пользователя и заставить его перелогиниться.

    А вот это мне в голову не пришло, гениально!
    Кстати на удивление нигде не видел описания такого способа!
  • Как выглядит логика простой системы авторизации с "выходом на всех устройствах"?

    @Barrakuda74 Автор вопроса
    xmoonlight, Прочитал, спасибо. Тоже интересно. Немного другой я так понял там подход. В основном всё на клиенте генерится, что больше для клиентский приложений годится. В моём случае у меня обычный сайтец в основном где кликать надо по страницам, выберу всё таки тот вариант (в выбранном ответе), он мне как-то более лёгким показался.
  • Как выглядит логика простой системы авторизации с "выходом на всех устройствах"?

    @Barrakuda74 Автор вопроса
    Всё понятно, благодарствую :)
    Пойду таким же путём.
  • Как выглядит логика простой системы авторизации с "выходом на всех устройствах"?

    @Barrakuda74 Автор вопроса
    Вот вроде как раз что-то очень такое близкое и понятное мне.
    Хотелось бы ещё уточнить некоторые нюансы в данной реализации.
    1. Если пользователь авторизуется ещё раз где-то с другого устройства, вы не перезаписываете current_session с тем же user_id, а создаёте новую запись в БД? (т.е. таким образом реализуется сохранение всех сессий одного и того же пользователя). В итоге я так понимаю в БД хранятся все сессии в течение 3х месяцев (или меньше, сколько указано) от посл. login_time.
    2. Login_time если я правильно понял, он каждый раз при восстановлении авторизации обновляется (если да, то каждый раз при очередном любом запросе авторизованного пользователя, или только по восстановлении авторизации по кукам)? Ну и CRON'ом я так понимаю мы каждый день потом просто очищаем таблицу sessions от сессий где login_time больше 3х месяцев.
    3.
    При успешном логине генерируются две случайные строки. Первая записывается в стандартную PHP сессию и будет current_session. Вторая записывается пользователю в куку session, а хеш этой строки будет long_session.

    Можно ли здесь поподробнее. Так, одну строку записываем напр в сессию как x="qw34tben...", и сверяем полю current_session в БД, другую строку записываем в куку как y="m4jhseweg2", т.к. она у нас будет долгоживучей (сколько кстати у неё срок действия ставите, и обновляете ли вручную её срок действия при восстановлении авторизации?), и сверяем её с хэшем в БД (long_session) от этой же строки. А почему первую строку храним в открытом виде, а long_session храним только хэш от случайной строки и сверка по хэшу? На ум вроде приходит что злоумышленнику недостаточно будет узнать current_session для получения доступа, т.к. нужно ещё знать сессионный идентификатор (PHPSESSID), чтобы зайти на сайт и пользователь его вспомнил, а во втором случае злоумышленнику достаточно узнать исходник строки long_session для входа, поэтому его кодируем, верно?

    В целом реализация выглядит очень простой и крутой, то что надо, и вроде как без изъянов, ещё вот нюансы разобрать, и практически пошаговое руководство :)