Доступ до $ _COOKIE відразу після setcookie ()


80

Я намагаюся отримати доступ до значення файлу cookie (використовуючи $_COOKIE) відразу після виклику setcookie()функції в PHP. Коли я це роблю, $_COOKIE['uname']не встановлюється. Чому?

Однак зверніть увагу, що $_COOKIE['uname']це встановлено, як очікується, при наступному виконанні сценарію, наприклад після оновлення сторінки.

setcookie('uname', $uname, time() + 60 * 30);
echo "Cookie value: " . $_COOKIE['uname'];

На жаль, відповіді тут не пропонують рішення або пропонують погані обхідні шляхи навіть прийнятих, див. Stackoverflow.com/questions/3230133#34465594 .
вітрін

@witrin ваше надане посилання, схоже, переспрямовує на те саме запитання.
trainoasis 11.03.16

Це неможливо. Ви повинні "підробити" це, або встановивши відповідні записи в $_COOKIEсобі, або негайно виконавши перенаправлення (на ту саму сторінку).
caw

Відповіді:


37

$_COOKIEвстановлюється, коли сторінка завантажується, через веб-статус без громадянства. Якщо вам потрібен негайний доступ, ви можете встановити $_COOKIE['uname']себе або скористатися проміжною змінною.

Наприклад:

if (isset($_COOKIE['uname'])) {
    // get data from cookie for local use
    $uname = $_COOKIE['uname'];
}
else {
    // set cookie, local $uname already set
    setcookie('uname', $uname, time() + 1800);  
}

21
це не робить файл cookie доступним перед оновленням сторінки ... див. відповідь Марка Бейкера далі щодо цього :)
pathfinder

Це не правда. Я висловив припущення, спираючись на код OP, який вони використовують $unameу своєму сценарії. Тоді як Марк Бейкер використовує $_COOKIE['uname']безпосередньо.
Джейсон МакКрірі

1
Вибачте, я сказав це трохи неправильно. Для моїх цілей, які стосуються асинхронного сценарію, встановлення $ _COOKIE насправді не встановило файл cookie і не відправило його назад у браузер (мені там теж знадобився файл cookie), воно зробило його доступним лише в моєму сценарії. Вам також потрібно використовувати setcookie (), що і робить відповідь Марка Бейкера. Плюс його код набагато коротший та корисніший для людей, які приходять сюди із пошуку Google.
pathfinder

Я використовую setcookie(). Ця відповідь може не відповідати вашим точним потребам. Але це не робить помилки . OP та SO визнали цю відповідь корисною.
Джейсон Маккрірі

2
Я не розумію, чому ця відповідь позначена як "відповідь". Це не пояснює, як використовувати файл cookie безпосередньо, а наданий код схожий на той самий ОП. Адже setcookie()в цьому коді неможливо отримати доступ$_COOKIE['uname']
Isthar

153

Файл cookie не встановлюється доти, поки відповідь не буде відправлена ​​назад клієнту, і недоступний у вашому PHP до наступного запиту від клієнта після цього.

Однак, коли ви встановлюєте файл cookie у своєму сценарії, ви можете зробити:

setcookie('uname', $uname, time()+60*30);
$_COOKIE['uname'] = $uname;

2
Дуже просте рішення. Дякую!
dawoodman71,

1
Чудові речі. Цікаво, як другий рядок встановлює час закінчення терміну дії, коли його не передано?
мартіндурінг

2
@martinedwards Другий рядок не встановлює часу закінчення терміну дії .... він встановлюється на час запиту; точно так само, як значення файлу cookie, передане з запитом браузера, існує протягом усього запиту
Марк Бейкер

@MarkBaker Просте рішення !! Велике спасибі
Шань,

Ви хочете сказати. щоб отримати доступ до значення cookie, до сторінки (php-файлу) потрібно отримати доступ двічі. Перший раз встановити файл cookie, а другий раз отримати доступ до встановленого файлу cookie. Правильно?
Пратік

31

Якщо ви хочете отримати доступ до значення файлу cookie відразу після виклику, setcookie()ви не можете використовувати $_COOKIE. Причиною цього є природа протоколу (див. Https://tools.ietf.org/html/rfc6265 ). Коли ви використовуєте, setcookie()це визначає файл cookie, який буде надіслано клієнту разом з рештою заголовків HTTP (див. Http://php.net/manual/en/function.setcookie.php ). Але $_COOKIEз іншого боку містить змінні, передані поточному сценарію через HTTP-файли cookie від клієнта ( http://php.net/manual/en/reserved.variables.cookies.php ).

Коли ви змінюєтесь $_COOKIEпісля дзвінка setcookie()- як рекомендують деякі відповіді тут - воно більше не містить лише файлів cookie від клієнта. Це може перешкоджати припущенням, зробленим у коді третьої сторони, що використовується у вашому додатку, і може спричинити небажані ефекти сайту. Отже, загалом це не є доброю практикою, і це лише варіант, коли дзвінки setcookie()є частиною вашого власного коду.

Чистим і прозорим способом отримати набір значень у setcookie()межах одного запиту є використання headers_list()(див. Http://php.net/manual/en/function.headers-list.php ) :

function getcookie($name) {
    $cookies = [];
    $headers = headers_list();
    // see http://tools.ietf.org/html/rfc6265#section-4.1.1
    foreach($headers as $header) {
        if (strpos($header, 'Set-Cookie: ') === 0) {
            $value = str_replace('&', urlencode('&'), substr($header, 12));
            parse_str(current(explode(';', $value, 1)), $pair);
            $cookies = array_merge_recursive($cookies, $pair);
        }
    }
    return $cookies[$name];
}
// [...]
setcookie('uname', $uname, time() + 60 * 30);
echo "Cookie value: " . getcookie('uname');

Але зверніть увагу, що це не спрацює в PHP CLI (наприклад, PHPUnit). В такому випадку ви можете використовувати сторонні розширення , як XDebug (див http://xdebug.org/docs/all_functions#xdebug_get_headers ).


6
Тут лише одне реальне рішення. Чистий, без змін коду третьої сторони, який може містити setcookie.
Майкл

1
Я не впевнений, чому оп проголосував за інше рішення, але це правильне рішення, яке насправді мені допомогло.
ChrisP777

Це 100% єдина відповідь, яка є життєздатною для виробничого середовища. Чудове рішення @witrin
skidadon

Не знаю чому, але параметр $ limit на explode()мене не працює, просто повертає один елемент масиву з цілим рядком всередині: ideone.com/7SnV9y
NaturalBornCamper

5

Вам потрібно встановити змінну cookie самостійно, якщо вам це потрібно негайно, до того часу, коли ви завантажите іншу сторінку, справжній cookie був би встановлений в результаті методу setcookie.

setcookie('name', $value, time()+60*30);
$_COOKIE ['name'] = $value;

1

Ми можемо зробити це за допомогою виклику AJAX.

Якщо ми хочемо створити файли cookie за натисканням кнопки, то спочатку створіть виклик AJAX для створення файлів cookie, тоді як для успіху першого виклику AJAX ми можемо викликати інший AJAX для отримання файлів cookie.

    function saveCookie() {
            var base_url = $('#base_url').val();
            var url = base_url + '/index/cookie';
            $.ajax({
                'url': url,
                'type': 'POST',
                'success': function (data) {
                    if (data) {
                        var url = base_url + '/index/get_cookie';
                        $.ajax({
                            'url': url,
                            'type': 'POST',
                            'success': function (response) {
                                var container = $('#show');
                                if (response) {
                                    container.html(response);
                                }
                            }
                        });
                    }
                }
            });
        }

    <button type="button" onclick="saveCookie()">Save Cookie</button>
    <div id="show"></div>

Знайте, що навіть коли наміри добрі, OP вимагає відповіді лише на PHP. :) Можливо, тому у вас є голоси проти, я вас не голосував.
Максима Алекс

проголосували за те, що це також єдиний підхід, який слід враховувати!
Dhruv Thakkar

1

У мене була подібна проблема, коли я використав функцію із включеного файлу і вирішив її за допомогою функції, яка одночасно повертає значення файлу cookie та встановлює файл cookie.

function setCookie($input) {
  setcookie('uname', $input, time() + 60 * 30);
  return $input;
}

if(!isset($_COOKIE['uname'])) {
    $uname  = setCookie($whatever);
} else {
    $uname = $_COOKIE['uname'];
}

echo "Cookie value: " . $uname;

-1

Використовуючи ob_start () та ob_flush (), ви можете надіслати файл cookie клієнту та отримати його за той самий час роботи. Спробуйте це:

ob_start();
setcookie('uname', $uname, time() + 60 * 30);
ob_flush();
echo "Cookie value: " . $_COOKIE['uname'];

Здається, це не працює (PHP 5.4 з / nginx). Ви можете розширити?
Пол ДельРе

-1

Ваш сценарій setcookie()Функція запускається, коли веб-браузер вперше запитує сторінку, у вашому випадку перезавантаження. Цей файл cookie зберігається у браузері користувачів і недоступний для вашого сценарію, запущеного на сервері, до наступного запиту або у вашому випадку наступного перезавантаження.

При наступному запиті браузер надсилає цей файл cookie на сервер, і масив $_COOKIEматиме значення, яке ви встановили спочатку, а браузер надішле назад за другим запитом.


-3

Я встановив константу одночасно із створенням файлу cookie

define('CONSTANT', true);
return setcookie('cookiename', 'cookie value goes here', time() + 60 * 60 * 24 * 30, '/');

Потім я можу одразу щось зробити, виконавши:

if(isset($_COOKIE['cookiename']) || $_COOKIE['cookiename'] || defined('CONSTANT') && CONSTANT)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.