I recently wrote about displaying ads only to search visitors in WordPress. A key part of the technique described is to set a cookie, identifying the visitor as having come from a search engine. It should have been simple, but my PHP setcookie command didn’t appear to work.
I was using the setcookie command in the same way I’d done countless times before. I’d already taken into account that the cookie wouldn’t be available on the first page view. I couldn’t see anything wrong with the command I was using (in functions.php in the WordPress theme I was creating):
setcookie("sevisitor", 1, time()+3600);
This should have set a cookie with a name of sevisitor and a value of 1, that expires after one hour. However, no cookie was created.
After scouring the Internet in vain, I found a hint somewhere in the WordPress Support Forums (although I can’t find the page again now!). It suggested that the setcookie command’s domain parameter needed to be set.
I’d never used this parameter before and although I’ve seen explanations of what it does, I still can’t find a clear explanation of why you’d want to use it. Most descriptions of it mention that it’s optional, but don’t mention under what circumstances it would be necessary. Any PHP experts out there, please feel free to put me straight in the comments!
Anyway, after some experimentation, I got it working, by using the following command:
setcookie("sevisitor", 1, time()+3600, "/", ".scratch99.com");
Problem solved! As you can see I’ve done the following:
- added the path parameter, setting it to “/”, which allows the cookie within the entire domain.
- added the domain parameter, setting it to my top level domain (.scratch99.com). Note the preceding . apparently makes it compatible with more browsers.
Obviously, if you want to set a cookie in WordPress, you’ll have to replace .scratch99.com with the domain you are using.
Alternatively, you could let WordPress work out the domain for you, by using the following:
setcookie("sevisitor", 1, time()+3600, "/", str_replace('http://www','',get_bloginfo('url')) );
This uses the get_bloginfo('url'))
command to get the site’s URL from WordPress, then strips the preceding http://www
from it, leaving only the domain. Note, if you don’t use the www on your site, you’ll need to change:
str_replace('http://www'
to
str_replace('http://'
However, it’s really not worth doing things this way – your site will be slightly faster if you hard code your domain in.
The only time you’d want to use the above would be if you were putting this into a WordPress Theme that you were creating to be distributed. In that case, you’d probably want to make it a little cleverer, so that it works whether or not the www is present. But I’ll leave that to you to work out!
Anyway, the lesson I learned: If you want to set a cookie in WordPress, you must set the path and domain parameters.
I’m not sure if this is any good to you but have you heard of Openx? It is an open source ad management program – I have been using it to geotarget adsense but it also has functions such as only showing ads after so many visits etc.
Pretty easy to use and may be worth a look. Just google openx.
That’s a very good open source tool. I have used it to monitor unique visits from SE. Will paste my code here.
LINK REMOVED: because of failure to use KeywordLuv syntax (name@keywords)
Thanks for the follow up with the fix!
I’m using Openx too on some of my sites. It has proven itself great, you should try it!
I’m surprised that wordpress doesn’t have a convenient API already set for cookies. I’m developing a plugin that will require a cookie, so found your blog this way. The closest thing I found in the true WordPress API was wp_setcookie(), which is for storing auth data only. I guess I’ll just do it the dirty way!
I haven’t tried OpenX yet. I’m using the “Who Sees Ads” plugin to limit AdSense being displayed to search visitors, although I could probably hard code the parameters into place. I’m lazy when it comes to coding, so I’ll probably leave it as is.
On using cookies to continue with search visitors… I’m not too keen on doing that. If someome moves from post to post, they’re obviously finding something they’re looking for and that completely defeats getting clicks. I suspect that the CTR would nearly drop to half of what it was before. Now, for non-AdSense pages, it’s probably a good idea — for any service that doesn’t do any kind of smart pricing.
Hi RT,
I suspect you’re right and it’s less likely they’ll click an add, but they are obviously looking for something and IF the link they clicked doesn’t give them the answer, there’s still a decent chance they’ll click on an ad before exiting.
It would reduce the CTR somewhat, but it would still be higher than normal users and I don’t believe CTR affects smart pricing. I know that’s what Court said, but I follow the Grizzly train of thought (that it’s really about targeted traffic for the advertisers and CTR is just bi-product of that).
So the real question is does Google count them as targeted traffic, because it remembers what they searched for? Or does it only recognise that they came from another page on your site?
That’s a very good open source tool. I have used it to monitor unique visits from SE. Will paste my code here. Apologies for using the wrong format Stephen.
I use “Who Sees Ads” plugin as well and it certainly helps. I am curious as to what kind of rules do you guys follow in the plugin. I have chosen to shows ads to search engine visitors or if the post is 7 days old. I see various options in there but curious if someone has fine tuned those further and your reasoning behind it.
Hi K,
I don’t use Who Sees Ads, but I just show Adsense to the search engine visitors, as a) they’re the ones who are really likely to click ads and b) other traffic can increase your chance of getting smart priced if they do click.
In some cases posts older than 7 days will be mostly search engine traffic anyway, but occasionally I get a StumbleUpon run on old posts…
OpenX wow, thanks for the info:)
Never thought about that.
D
Hi All who wrote about OpenX,
I’ve heard of OpenX but never tried it. It sounds like it’s great – but can it display only for search engine visitors? You really don’t want to show Adsense to your StumbleUpon traffic…
Thanks for the useful information . I would love to try it . Hope to see more articles like this in the future. Thanks a lot.
Thanks a lot for the excellent post! It is very helpful to me and I found exactly what I want in your site. keep it up and I am looking forward to hear more.
Ty, Cool post, Forgot about basic functions to help with cookies
Hi Stephen,
I really appreciate the follow up post to correct this bug. I’ve finally got it working and really appreciate the thoroughness of your explanations:)
Nice post. . Openx sound new to me and when I read about it it makes me so interested. I will surely try this one.
Thanks Stephen, that’s useful stuff
Hope it’s OK to digress slightly? Talking of geo-targetting, is there a way to geo-target affiliate links? For example with Amazon links, so that UK visitors see the link to Amazon.co.uk, USA visitors see the link to .com
Cheers, Jon
Hi Jon,
Well, I don’t use affiliate links much and it will depend on the individual affiliate, but it should be possible to do something. In theory, you could check where someone’s from, then display a certain link. But doing it would be a little complicated.
I’ll think about this for a future post, but no promises on when I may get to it as I’m flat out right now..
The domain parameter is there so you can restrict the accessibility of the cookie to just the domain you specify. If you put a dot before the domain, that also makes it available to all the subdomains. I would advise to ALWAYS use it this parameters, or else other sites could potentially pick up the cookies that your site dropped.
Ah I think this is why my wasnt working, doh!
You could also get the server info via PHP instead of using the WordPress setting so it would work on non-wp pages as well. Otherwise you’d need to include the blog header.
Hi Chris,
You sure could. Good point! I was just writing for WordPress users with this post. 🙂
In general, it’s probably better to go with the WordPress constants already defined for the cookie path and domain, as the processing work figuring out their values has already been done, and that way you’ll match the existing WordPress cookies:
setcookie("sevisitor", 1, time()+3600, COOKIEPATH, COOKIE_DOMAIN);
Hi Austin,
Great tip! I didn’t know these constants existed. COOKIE_DOMAIN isn’t mentioned on the WordPress Codex at all, and COOKIEPATH only has a few obscure mentions. I guess the WordPress Codex needs a list of constants that are available. Thanks for pointing this out.
thanks a lot, it works just great
Good idea to have a cookie here…I think this code should be placed in a loop such that it is activated until the process is done…Thanks for the post.
I just tried to understand(I get the .your domain.com idea, and I think I understand The 2nd part too, but I decided to bookmark the page so I can come back while I’m actually setting up the cookie for my blog.
I’m still in the stage where I’m crossing my fingers and hoping I don’t screw anything up. (i will be holding my breath while doing it). thanks for sharing the help.
Tom
You should make a complete wordpress template with your plugings so people could just install all of them with your adsense plugin in one shot. I am sure it would be very popular.
That’s a very good open source tool. I have used it to monitor unique visits from SE. Will paste my code here. Apologies for using the wrong format Stephen.
hey man this is simply new to me that cookie can be set first time. ‘set cookie command’s domain parameter’ i did not even know that this command exist. thanks man for this great piece of information. i will try to gather more knowledge about this.
Thanks for this tip. I have an area of my home page dedicated to an animated carousel of video selections. Some users have said they’d like to hide it once and not see it again, even after leaving and returning, until they choose to unhide it. Most visitors are anonymous visitors.
I was wondering if you or any of your commenters has insight into how to modify this cookie setting code so that it will remember whether a person has, at any time, clicked a “show/hide” link and “remember” their preference on the client.
Thanks for any help you can give me.
humm…. it’s not owkring for me. I’m developing a plugin and I keep getting the error message: Warning: Cannot modify header information – headers already sent by (…).
Any ideas how I can get around this? wp_setcoockie() doesn’t work either.
Hi Steven,
There could be other reasons, but the most common reason for that error is that there is a space before the opening ) in one of your files. That said, there can often be conflicts with other plugins… That’s probably not much help, but it’s somewhere to start.
hi,
I am setting cookie as setcookie(‘Test’, “displayName”, time() + 3600, get_bloginfo(‘url’)); in header.php in wordpress,and i am displaying trying to retrieve it in comments.php,but i am not able to retrive the cookie value in comments.php.
can any one help me .
omg! spent an hour wondering why my cookie wont be retrieved, yet it would outside wordpress
the / & domain were all i needed
FWIW, I did this:
$url = parse_url(get_bloginfo(‘url’));
setcookie(‘name’, ‘value’, $expires, $url[‘path’], $url[‘host’]);
that’ll get you the actual host and path of the blog.
Try this:
// Set cookie for new user
function set_newuser_cookie() {
if (!isset($_COOKIE[‘newvisitor’])) {
setcookie(‘newvisitor’, 1, time()+86400, COOKIEPATH, COOKIE_DOMAIN, false);
}
}
add_action( ‘init’, ‘set_newuser_cookie’);
Hi, there is a neat method to avoid using the str_replace command: There are two definitions inside WordPress, that can do the job for you:
1. COOKIEPATH: Stores the right path to your cookies
2. COOKIE_DOMAIN: Since WordPress 3.0 this definition isn’t set intially within the wp-config.php, so you will need to set this to what you want.
Cheers
Dietmar
Instead of messinga round with str_replace() you can also just use the PHP function parse_url() to get the domain from the URL.
Hi!
I doubt using the str_replace function, in this case, would cause any notable difference in speed. Not even worth taking into account. We’re talking about microseconds: millionths of a second.
You should use the core constant SITECOOKIEPATH instead.
Did you try that?
Works for me…
setcookie(‘bairro’, $_POST[‘name’], time()+31536000, COOKIEPATH, COOKIE_DOMAIN, false);
for those using localhost, this works for me on wordpress:
setcookie(“site_visitor”, “john”, time()+3600, “/”, $SITECOOKIEPATH, false )
Hi,
Thanks for the post, very helpful!
I have a question to something you wrote in the beginning, I tried searching for the answer but couldn’t find anything. You wrote “I’d already taken into account that the cookie wouldn’t be available on the first page view.” is that a WordPress thing? – and is there no workaround?
Hi Ann,
That’s a PHP thing (or any server side technology).
Although your code (to create a cookie) runs on the server side, the cookie’s not actually created until the browser renders the page. By that time the server side code is finished running.
If you check for the cookie’s existence on the server side, it won’t be there on the first page load, because it’s not actually created yet. After the first page load it will have been created and you can check for it’s existence.
There are ways around this – for example: a) using JavaScript on the client side to check for the cookie’s existence and send an Ajax request to the server side, or b) forcing the page to reload via JavaScript if the cookie doesn’t exist (be careful about getting into an endless loop though).
Hope that helps.
That does help. Thanks for the info!
Thank you very very much 😀
You can use the WordPress constants COOKIEPATH and COOKIE_DOMAIN to set the path and domain setcookie paramentes. Example:
setcookie(“sevisitor”, 1, time()+3600, COOKIEPATH, COOKIE_DOMAIN);
i cant get it working in local host.
George will you please explain your code with example.
i want to know that, what is “$SITECOOKIEPATH” in your code.
kindly help me . i am new to wordpress.
Hi, Any one can give me idea, how to work with cookies and track the IP, Date and Time while visitor is not logged in WP site?
Thank you, thank you! Hours of stumbling around, got cookies to set by adding the path and domain info.