Setcookie и POST запрос

Mirt

Новичок
Всем привет!
Задание учебное, я чайник, не кидайтесь тапками, пожалуйста
У меня есть php-код, который выводит форму "Имя", "Пароль", устанавливает куки и выводит "Welcome" страницу, с использованием имени, сохраненного в куки. Там же кнопка "разлогиниться", которая забывает куки и возвращает форму авторизации.
Вопрос в том, что без присвоения в первом if ( $_COOKIE ['user']=$_POST['user']; ), все работает только после второго обновления страницы
С этим костылем все работает

Вопрос оптимизации кода не стоит. Хочется понять в чем логика не срабатывания с первого раза. Почему сеткуки не срабатывает без присвоения ?

Код:
<?php       

//установить куки

if (isset($_POST['LogIn'])) {

        // $_COOKIE ['user']=$_POST['user'];  мой мнимый костыль, без которого не работает 

        setcookie('user', $_COOKIE ['user']);

        }   

// удалить куки

if (isset($_POST['logout'])) {

        unset($_COOKIE['user']);

        setcookie('user',"",time() - 3600);

    }



if (isset($_COOKIE['user'])) {

        echo("Welcome, ".$_COOKIE['user']."!</br>");

        print '

        <form name="logout" method = "POST"> <br>

        <input type="submit" name = "logout" value="It is not me.." id = "out"></p>

        </form>';

    } else {

        print '<form name="login" method = "POST">

        <label>Name: <br>

        <input type="text" name="user" id = "usr" oninput = "checkFields()"></label></p>

        <label>Password: <br>

        <input type="password" name="password" id = "pass" oninput = "checkFields()"></label></p>

        <input type="submit" name = "LogIn" value="Log in" id = "in"></p>

        </form>';

       }

  ?>
1) форма
Посмотреть вложение 1639418807315.png
2) велком страница
Посмотреть вложение 1639418823408.png
 
Последнее редактирование:

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Давай ты спросишь нормально, даш код, который НЕ работает, без мнимых костылей и прочего. Если так хочется дать больше инфы, можешь дать ее как //коммент. И оформи свой код как надо
Посмотреть вложение 1639421852910.png
 

Mirt

Новичок
Давай ты спросишь нормально, даш код, который НЕ работает, без мнимых костылей и прочего. Если так хочется дать больше инфы, можешь дать ее как //коммент. И оформи свой код как надо
Посмотреть вложение 1552
Извиняюсь, теперь все должно быт нормально оформлено
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Вот смотри, первыми строчками в любом dev коде, когда ты разрабатываешь что-то должны быть:
PHP:
error_reporting(E_ALL);
ini_set('display_errors', true);
это включает отображение ошибок, попробуй поставить это в начале файлика и засабмитить пустую форму, увидишь ошибку, то есть Notice

Я бы написал иначе:
PHP:
<?php

error_reporting(E_ALL);
ini_set('display_errors', true);

//установить куки, тут надо проверку делать что есть какие-то данные и они валидны, но я просто добавил проверку на наличие
if (isset($_POST['LogIn']) && !empty($_POST['user']) && !empty($_POST['password'])) {

    // $_COOKIE ['user']=$_POST['user'];  мой мнимый костыль, без которого не работает
    // Это не костыль, как ты выразился, а код который присваивает переменную, которая нужна в setcookie
    // Если не присвоить тут переменную код работать будет неправильно, я поставил просто текст и все ок, смотри ниже

    setcookie('user', 'authenticated');

    header('Location: http://твой-домен/адрес-скрипта/'); //уберет повторную отправку формы при нажатии F5
    exit;
}

// удалить куки
if (isset($_POST['logout'])) {
    unset($_COOKIE['user']);
    setcookie('user',"",time() - 3600);

    header('Location: http://твой-домен/адрес-скрипта/'); //уберет повторную отправку формы при нажатии F5
    exit;
}

if (isset($_COOKIE['user'])) {

    echo("Welcome, ".$_COOKIE['user']."!</br>");

    include_once 'logout.php'; //то что у тебя было в print - форма выхода
    exit;
}

include_once 'login.php'; //то что у тебя было в print - форма логина
Про завершающий тэг ?> - забудь, он в твоем случае не нужен
 
Последнее редактирование:

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Дополню:
https://www.php.net/manual/ru/function.setcookie.php нам говорит:
setcookie() задаёт cookie, которое будет передано клиенту вместе с другими HTTP-заголовками. Как и любой другой заголовок, cookie должны передаваться до того как будут выведены какие-либо другие данные скрипта (это ограничение протокола).
Если ты пишешь код с Notice, он (Notice) сгенерится у тебя как только интерпретатор дойдет до строки с неопределенной переменной (в данном случае ты пытаешься поставить куку, но в массиве нет ключа: setcookie('user', $_COOKIE ['user']); <<< ключа user нет )
и полетит в браузер не давая поставить заголовки с куками, потому как будет "вывод" ошибки
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
ЭТО должно быть написано в настройках сервера. В коде это писать несколько поздновато.
бросай курить) в каких настройках, у тебя может быть одна площадка для дев(стейдж для тестов), другая рядом - прод, ты реально думаешь иметь один конфиг? Это настройка уровня приложения, никак не софта
 
  • Like
Реакции: AmdY

Фанат

oncle terrible
Команда форума
бросай курить) в каких настройках, у тебя может быть одна площадка для дев(стейдж для тестов), другая рядом - прод, ты реально думаешь иметь один конфиг? Это настройка уровня приложения, никак не софта
При чем здесь один конфиг?
Конфиги как раз тут разные. На дев (стейдж) 'display_errors', true, а прод - соответственно - false
и как правильно замечено, лучше это делать на уровне сервера.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Какие конфиги, о чем ты. У тебя есть php.ini и vhost.conf для nginx, где ты собрался это хранить?

Вот ты вообще не понимаешь что ты предлагаешь, у меня один такой падаван был. В итоге чтобы временно сменить параметр - надо рестартить сервак, имея определенные привилегии.

Здесь у тебя это должно лежать в .env который не в гите и куда может зайти кому надо и поменять это за минуту. Так же к примеру - как врубить дебаг консоль или что-то подобное.
 

Фанат

oncle terrible
Команда форума
Здесь у тебя это должно лежать в .env
Дооооооо, на бою в .env :)))

К сведению, .env - это как раз костыль, чтобы писать в удобном файлике те настройки, которые - сюрприз! - в оригинале задаются переменными окружения, hence "env".

И, честно, я не понял, зачем "временно менять настройки" отображения ошибок на боевом сервере.
У меня на факе жестко забито в конфиге php-fpm, php_admin_value[display_errors] = off и идите лесом со своими .env.
Меня не колышет, кто там что с перепою напишет или перепутает. Мне на бою показ ошибок не нужен.
 

AmdY

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

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Дооооооо, на бою в .env :)))

К сведению, .env - это как раз костыль, чтобы писать в удобном файлике те настройки, которые - сюрприз! - в оригинале задаются переменными окружения, hence "env".

И, честно, я не понял, зачем "временно менять настройки" отображения ошибок на боевом сервере.
У меня на факе жестко забито в конфиге php-fpm, php_admin_value[display_errors] = off и идите лесом со своими .env.
Меня не колышет, кто там что с перепою напишет или перепутает. Мне на бою показ ошибок не нужен.
Доооо, представь себе =D
.env костыль? Используется и в симфони и в ларавеле тоже.

Где было сказано, чтобы временно сменить параметр "на проде"? Не было такого, читай внимательнее.

Мне все равно как ты пишешь свой код, но есть же разумное разделение параметров приложения (обработка ошибок, креды доступа к базе, дополнительные настройки того, что приложению может потребоваться, отправка почты к примеру), и параметров сервера (под каким юзером крутится сервак, настройки максимального размера передаваемых данных, сколько ждать/читать ответ от fpm и все такое прочее)

Ситуация: пришел тестировщик на стейдж, на свою площадку, надо поменять параметр, отрубить показ ошибок, но прав на рестарт сервака нет. Фиаско, да? А так бы поправил строчку в .env.local и все.
 

Фанат

oncle terrible
Команда форума
В целом, одно другому не мешает.
файл локальных настроек, будь то .env, .php или .json по-любому нужен (и я, кстати, предпочту пхп)
при этом зажать критические параметры на боевом сервере тоже не помешает.
 

Фанат

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

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
.env уже почти стандарт, используемый даже в велосипедах благодаря библиотечке: https://github.com/vlucas/phpdotenv Да, ты можешь окружение тягать откуда угодно, но вопрос удобства и последующего понимания тебя другими разрабами тут не последний.

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

Фанат

oncle terrible
Команда форума
Ну в общем так и выходит, что мы не спорим :)
На проде меняет админ, а все прочее задаётся в файле конфигурации
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
бросай курить) в каких настройках, у тебя может быть одна площадка для дев(стейдж для тестов), другая рядом - прод, ты реально думаешь иметь один конфиг? Это настройка уровня приложения, никак не софта
не согласен принципиально, это было для веб-хостингов, а сейчас конфиги runtime - это часть приложения, конфиги приложений ушли в переменные среды, а разные окружения - это настройки билдов

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

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Вот ты вообще не понимаешь что ты предлагаешь, у меня один такой падаван был. В итоге чтобы временно сменить параметр - надо рестартить сервак, имея определенные привилегии.
открой для себя докер, а? попробуй деплоить не ручками, не ansible, а пайплайном
выглядит это так: по коммиту в заданную ветку на github автоматически срабатывает action, который собирает образ, кладет его в registry, и твои сервисы деплоятся на сервер вообще целиком - со всеми конфигами, библиотеками, и версиями runtime

я понимаю, что 10 лет для тебя - слишком молодая технология, но попробуй, а вдруг
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Докер имеется и деплойменты через gitlab ci тоже, не переживай) Америку ты мне не откроешь, увы. Ты опять прочитал половину, понял тоже половину, и решил вые..ся, ну молодец)
 
Сверху