PHP 8.3.4 Released!

setcookie

(PHP 4, PHP 5, PHP 7, PHP 8)

setcookieBir çerez gönderir

Açıklama

setcookie(
    string $isim,
    string $değer = "",
    int $süreler_veya_seçenekler = 0,
    string $yol = "",
    string $alan = "",
    bool $güvenli = false,
    bool $sadece_http = false
): bool

PHP 7.3.0 ve sonrasında böyle de kullanılabilir (isimli bağımsız değişkenler desteklenmiyor):

setcookie(string $isim, string $değer = "", array $seçenekler = []): bool

setcookie() işlevi, HTTP başlıklarının kalanıyla gönderilmek üzere bir çerez tanımlar. Diğer başlıklar gibi, çerezlerde betiğinizin herhangi bir çıktısından önce gönderilmelidir (bu bir protokol kısıtlamasıdır). Bu kısıtlama, bu işleve yapılacak çağrıların, <html> ve <head> etiketleri ve hatta her türlü boşluk karakteri çıktısından bile önce yer almasını gerektirir.

Çerezler bir kere atandı mı, artık $_COOKIE dizisi ile sonraki sayfa yüklemesinde erişilebilir olacaktır. Çerez değerleri ayrıca, $_REQUEST içinde de mevcut olabilir.

Bağımsız Değişkenler

setcookie() bağımsız değişkenlerinin her birinin nasıl çalıştığını hakkında bilgi edinmek için bkz: » RFC 6265

isim

Çerezin ismi.

değer

Çerezin değeri. Bu değer istemcinin bilgisayarında saklanır. Bu bakımdan çerezlerde güvenlik ihlaline konu bilgiler saklanmamalıdır. isim bağımsız değişkeninde 'çerezim' isminin kullanıldığı varsayımıyla, bu çerezin değeri $_COOKIE['çerezim'] değişkeni ile alınabilir.

süreler_veya_seçenekler

Çerezin zaman aşımına uğrama süresi. Değer bir Unix zaman damgasıdır. Bu değeri elde etmenin tek yolu, time() işlevinden dönen değere çerezin zaman aşımına uğrayacağı süreyi saniye cinsinden eklemektir. Örneğin, time()+60*60*24*30 ile çerez 30 gün sonra zaman aşımına uğrar. Ayrıca, mktime() işlevi de kullanılabilir. Burada 0 atanır veya birşey belirtilmezse, çerez oturumun sonunda (tarayıcı kapandığında) zaman aşımına uğrar.

Bilginize:

süreler_veya_seçenekler bağımsız değişkeni değer olarak bir Unix zaman damgası alır. Bu, başlıkta belirtilen Wdy, DD-Mon-YYYY HH:MM:SS GMT tarih biçeminin zıddı olup bu dönüşümü PHP dahili olarak yapar.

yol

Çerezin üzerinde etkin olacağı sunucudaki yol. '/' belirtilirse çerez alan'ın tamamında kullanılabilir olacaktır. Eğer '/foo/' belirtilirse, çerez sadece /foo/ dizininde ve /foo/bar/ gibi alt dizinlerde kullanılabilir olacaktır. Öntanımlı değer çerezin atandığı içinde bulunulan dizindir.

alan

Çerezin kullanılabileceği (alt)alan. Çerezi ('www.example.com' gibi) bir alt alan adında kullanılabilir yapmak onu tüm diğer alt alan adlarında da (w2.www.example.com gibi) kullanılabilir kılacaktır. Çerezi tüm alt alan adlarında kullanılabilir yapmak için buraya alan adı (örneğimiz için ('example.com') yazılmalıdır.

Eski tarayıcılar hala kullanımdan kalkmış olan ve alt alan adıyla eşleşme sağlamak için . ile başlatmayı gerektiren » RFC 2109'u gerçeklemektedir.

güvenli

Çerezin istemciye güvenli bir HTTPS bağlantısı üzerinden mi aktarılması gerektiğini belirtmek için kullanılır. true belirtildiği takdirde, çerez sadece güvenli bağlantı mevcutsa gönderilecektir. Sunucu tarafında, bu çeşit çerezin sadece ($_SERVER["HTTPS"] ile ilgili) güvenli bağlantı üzerinden gönderilmesi kararı yazılımcıya aittir.

sadece_http

true olduğu takdirde çerez sadece HTTP protokolü üzerinden erişilebilir olacaktır. Yani çerez, JavaScript gibi betik dilleri tarafından erişilebilir olmayacaktır. Bu ayarlama, XSS saldırılarıyla kimlik hırsızlığı riskini etkin şekilde azaltmaya (tüm tarayıcılar tarafından desteklenmese de) yardımcı olabilir, fakat bu sava çoğunlukla itiraz edilir. Değer olarak true veya false belirtilebilir.

seçenekler

zaman_aşımı, yol, alan, güvenli, sadece_http ve samesite bağımsız değişkenlerinden herhangi birine sahip olabilen ilişkisel bir dizi. Bunlar dışında bir anahtar varsa, E_WARNING seviyesinde bir hata üretilir. Değerler, aynı ada sahip bağımsız değişkenler için açıklananla aynı anlama sahiptir. samesite öğesinin değeri None, Lax veya Strict olmalıdır. İzin verilen seçeneklerden herhangi biri belirtilmezse, bunların öntanımlı değerleri, açık bağımsız değişkenlerin öntanımlı değerleri ile aynıdır. samesite öğesi atlanırsa, SameSite çerez özelliği ayarlanmaz.

Dönen Değerler

Bu işlev çağrılmadan önce yapılmış çıktı varsa setcookie() başarısız olup false döndürür. setcookie() başarılı olduğu takdirde true döndürür. Dönüş değeri, kullanıcının çerezi kabul ettiği ya da etmediği anlamına gelmez.

Sürüm Bilgisi

Sürüm: Açıklama
8.2.0 Çerezin tarih biçemi 'D, d M Y H:i:s \G\M\T' oldu; evvelce 'D, d-M-Y H:i:s T' idi.
7.3.0 seçenekler dizisini destekleyen ek bir yöntem tanımı eklendi. Dizi içinde SameSite çerezinin değerleri de destekleniyor.

Örnekler

Çerez gönderimi ile ilgili bazı örnekler:

Örnek 1 - setcookie() gönderim örneği

<?php
$value
= 'bir şeyler bir yerlere';

setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600); /* 1 saatliğine geçerli */
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", "example.com", 1);
?>

Çerez gönderilirken çerez değerinin otomatik olarak URL kodlamasından geçirileceğine, alınırken ise bu kodlamanın yine otomatik olarak çözüleceğine ve yine aynı çerez ismine atanacağına dikkat ediimalidir. Bu istenmiyorsa, Bu işlevin yerine setrawcookie() işlevi kullanılabilir. Deneme çerezimizin bir betik içindeki değerini görmek için aşağıdaki örneklerden biri kullanılabilir:

<?php
// Bağımsız bir çerez bas
echo $_COOKIE["TestCookie"];

// Tüm çerezleri görmek için başka bir yol
print_r($_COOKIE);
?>

Örnek 2 - setcookie() silme örneği

Bir çerezi silerken, tarayıcının yürürlükten kaldırma mekanizmasını tetikleyebilmek için, süre bitiminin geçmişte kalmasını sağlamanız gerekir. Önceki örnekte gönderilen çerezin silinmesi:

<?php
// süre bitimini 1 saat önceye ayarla
setcookie ("TestCookie", "", time() - 3600);
setcookie ("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);
?>

Örnek 3 - setcookie() ve diziler

Çerez ismini belirtirken dizi gösterimini kullanmak suretiyle çerez dizileri tanımlanabilir. Bu sayede dizi elemanı sayısı kadar çerez tanımlanabilir, fakat çerezler betikle alındığında değerlerin hepsi çerez isminde bir diziye yerleştirilir:

<?php
// çerezleri tanımla
setcookie("cookie[three]", "cookiethree");
setcookie("cookie[two]", "cookietwo");
setcookie("cookie[one]", "cookieone");

// sayfayı yeniden yükledikten sonra çerezler bas
if (isset($_COOKIE['cookie'])) {
foreach (
$_COOKIE['cookie'] as $name => $value) {
$name = htmlspecialchars($name);
$value = htmlspecialchars($value);
echo
"$name : $value <br />\n";
}
}
?>

Yukarıdaki örneğin çıktısı:

three : cookiethree
two : cookietwo
one : cookieone

Bilginize: Çerez isminin paraçası olarak [ ve ] gibi ayırıcı karakterlerin kullanımı RFC 6265, bölüm 4 ile uyumlu değildir, fakat RFC 6265, bölüm 5'e göre kullanıcı istemcileri tarafından desteklendikleri varsayılmıştır.

Notlar

Bilginize:

Bu işlevi çağırmadan önce, tarayıcıya gönderilene kadar sunucuda bekletilmek üzere çıktı bir tampona yazılabilir. Bu işlem, betikten ob_start() ve ob_end_flush() işlevlerini çağırarak veya output_buffering yapılandırma yönergesi php.ini veya sunucu yapılandırma dosyalarında belirtilerek yapılabilir.

Bilinen Güçlükler:

  • Çerezler sonraki sayfada görünür olmak üzere atanırlar, dolayısıyla sonraki sayfa yüklenene kadar görünür olmazlar. Bir çerezin başarıyla tanımlanıp tanımlanmadığını anlayabilmek için çerez zaman aşımına uğramadan sonraki sayfa üzerinde çerez denenmelidir. Zaman aşımı süresi zaman_aşımı bağımsız değişkeni ile belirtilebilir. Bir çerezin varlığını sınamanın en kolay yolu print_r($_COOKIE); çağrısı yapmaktır.
  • Çerezler atandıkları sırada kullanılan bağımsız değişkenler kullanılarak silinmelidir. değer bağımsız değişkeninde bir boş dizge belirtilir ve tüm diğer bağımsız değişkenlerin çerezi atarken kullanılan bağımsız değişkenlerle aynı olması sağlanırsa, ismi belirtilen çerez uzak istemciden silinir. Bu işlem dahili olarak çereze 'deleted' değeri atanarak ve zaman aşımı tarihi bir yıl önceye çekilerek gerçekleştirilir.
  • Bir çereze silmek amacıyla false değeri atanırken mantıksal değerler kullanılmamalıdır. false için 0, true için 1 kullanılmalıdır.
  • Çerez isimleri dizi isimleri olabilir. Böylece PHP betiğinde bu çerezler için dizi kullanılırken, kullanıcının sisteminde bunlar ayrı ayrı çerezler olarak saklanırlar. Tek bir çereze çok sayıda isim ve değer atamak için explode() işlevi kullanılabilir. Güvenlik zafiyeti oluşturması nedeniyle bu işlem için serialize() işlevinin kullanılması önerilmemektedir.

Peşpeşe pek çok setcookie() çağrısı yapılabilir.

Ayrıca Bakınız

add a note

User Contributed Notes 12 notes

up
390
walterquez
11 years ago
Instead of this:
<?php setcookie( "TestCookie", $value, time()+(60*60*24*30) ); ?>

You can this:
<?php setcookie( "TestCookie", $value, strtotime( '+30 days' ) ); ?>
up
259
Bachsau
11 years ago
Want to remove a cookie?

Many people do it the complicated way:
setcookie('name', 'content', time()-3600);

But why do you make it so complicated and risk it not working, when the client's time is wrong? Why fiddle around with time();

Here's the easiest way to unset a cookie:
setcookie('name', 'content', 1);

Thats it.
up
87
Anonymous
3 years ago
Just an example to clarify the use of the array options, especially since Mozilla is going to deprecate / penalise the use of SameSite = none, which is used by default if not using array options.

<?php
$arr_cookie_options
= array (
'expires' => time() + 60*60*24*30,
'path' => '/',
'domain' => '.example.com', // leading dot for compatibility or use subdomain
'secure' => true, // or false
'httponly' => true, // or false
'samesite' => 'None' // None || Lax || Strict
);
setcookie('TestCookie', 'The Cookie Value', $arr_cookie_options);
?>
up
36
paul nospam AT nospam sitepoint dot com
17 years ago
Note when setting "array cookies" that a separate cookie is set for each element of the array.

On high traffic sites, this can substantially increase the size of subsequent HTTP requests from clients (including requests for static content on the same domain).

More importantly though, the cookie specification says that browsers need only accept 20 cookies per domain. This limit is increased to 50 by Firefox, and to 30 by Opera, but IE6 and IE7 enforce the limit of 20 cookie per domain. Any cookies beyond this limit will either knock out an older cookie or be ignored/rejected by the browser.
up
21
nacho at casinelli dot com
7 years ago
It's worth a mention: you should avoid dots on cookie names.

<?php
// this will actually set 'ace_fontSize' name:
setcookie( 'ace.fontSize', 18 );
?>
up
13
synnus at gmail dot com
3 years ago
The " PHPSESSID " cookie will soon be rejected because its " sameSite " attribute is set to " none " or an invalid value, and without " secure " attribute. To learn more about the "sameSite" attribute, visit https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite.

<?php
ini_set
("session.cookie_secure", 1);
session_start();

my PHP code ....

?>
up
42
Anonymous
17 years ago
something that wasn't made clear to me here and totally confused me for a while was that domain names must contain at least two dots (.), hence 'localhost' is invalid and the browser will refuse to set the cookie! instead for localhost you should use false.

to make your code work on both localhost and a proper domain, you can do this:

<?php

$domain
= ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
setcookie('cookiename', 'data', time()+60*60*24*365, '/', $domain, false);

?>
up
19
gabe at fijiwebdesign dot com
17 years ago
If you want to delete all cookies on your domain, you may want to use the value of:

<?php $_SERVER['HTTP_COOKIE'] ?>

rather than:

<?php $_COOKIE ?>

to dertermine the cookie names.
If cookie names are in Array notation, eg: user[username]
Then PHP will automatically create a corresponding array in $_COOKIE. Instead use $_SERVER['HTTP_COOKIE'] as it mirrors the actual HTTP Request header.

<?php

// unset cookies
if (isset($_SERVER['HTTP_COOKIE'])) {
$cookies = explode(';', $_SERVER['HTTP_COOKIE']);
foreach(
$cookies as $cookie) {
$parts = explode('=', $cookie);
$name = trim($parts[0]);
setcookie($name, '', time()-1000);
setcookie($name, '', time()-1000, '/');
}
}

?>
up
9
ellert at vankoperen dot nl
9 years ago
Caveat: if you use URL RewriteRules to get stuff like this: domain.com/bla/stuf/etc into parameters, you might run into a hickup when setting cookies.
At least in my setup a change in one of the parameters resulted in the cookie not being 'there' anymore.
The fix is simple: specify the domain. '/' will usualy do fine.
up
6
laffen
14 years ago
Note that the $_COOKIE variable not will hold multiple cookies with the same name. It is legitimate to set two cookies with the same name to the same host where the sub domain is different.
<?php
setcookie
("testcookie", "value1hostonly", time(), "/", ".example.com", 0, true);
setcookie("testcookie", "value2subdom", time(), "/", "subdom.example.com", 0, true);
?>
The next request from the browser will have both cookies in the $_SERVER['HTTP_COOKIE'] variable, but only one of them will be found in the $_COOKIE variable. Requests to subdom.example.com will have both cookies, while browser request to example.com or www.example.com only sends the cookie with the "value1hostonly" value.

<?php
$kaker
= explode(";", $_SERVER['HTTP_COOKIE']);
foreach(
$kaker as $val){
$k = explode("=", $val);
echo
trim($k[0]) . " => " . $k[1];
}

// output
testcookie => value1hostonly
testcookie
=> value2subdom

?>
up
2
Anonymous
13 years ago
A period in a cookie name (like user.name) seems to show up in the $_COOKIE array as an underscore (so user_name). This means that for example $_COOKIE["user_name"] must be used to read a cookie that has been set with setcookie("user.name" ...), which is already rather confusing.

Furthermore the variable $_COOKIE["user_name"] will retain the value set by setcookie("user.name" ...) and no amount of calling setcookie("user_name" ...) will alter this value. This is rather trivially fixed by clearing the "user.name" cookie, but it can take a while to realize this since there's only "user_name" in $_COOKIE.

Hope this saves someone some time.
up
0
hansel at gretel dot com
17 years ago
The following code snippet combines abdullah's and Charles Martin's examples into a powerful combination function (and fixes at least one bug in the process):

<?php
function set_cookie_fix_domain($Name, $Value = '', $Expires = 0, $Path = '', $Domain = '', $Secure = false, $HTTPOnly = false)
{
if (!empty(
$Domain))
{
// Fix the domain to accept domains with and without 'www.'.
if (strtolower(substr($Domain, 0, 4)) == 'www.') $Domain = substr($Domain, 4);
$Domain = '.' . $Domain;

// Remove port information.
$Port = strpos($Domain, ':');
if (
$Port !== false) $Domain = substr($Domain, 0, $Port);
}

header('Set-Cookie: ' . rawurlencode($Name) . '=' . rawurlencode($Value)
. (empty(
$Expires) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', $Expires) . ' GMT')
. (empty(
$Path) ? '' : '; path=' . $Path)
. (empty(
$Domain) ? '' : '; domain=' . $Domain)
. (!
$Secure ? '' : '; secure')
. (!
$HTTPOnly ? '' : '; HttpOnly'), false);
}
?>

Basically, if the domain parameter is supplied, it is converted to support a broader range of domains. This behavior may or may not be desireable (e.g. could be a security problem depending on the server) but it makes cookie handling oh-so-much-nicer (IMO).
To Top