ben m Posted August 23, 2012 Share Posted August 23, 2012 Hi All, I have been fighting with a piece of code but cannot figure it out. It could be that I am taking the completely wrong approach with what I am trying to achieve so I welcome any tips etc. for alternative options. To start this is the code I am trying to get working: error_reporting(E_ALL); $domain=$_GET['domain']; $update=$_GET['update']; $check="Quota_avail_" . $domain; if ( isset($_COOKIE["Quota_avail_$domain"])) { $quota_avail = $_COOKIE["Quota_avail_$domain"]; $quota_used = $_COOKIE["Quota_used_$domain"]; $bandwidth_avail = $_COOKIE["Bandwidth_avail_$domain"]; $bandwidth_used = $_COOKIE["Bandwidth_used_$domain"]; echo "Cookies set"; // Testing print_r($_COOKIE["Quota_avail_$domain"]); //testing } else { // Get domain info $dom_return = explode("\n", shell_exec("sudo /usr/share/webmin/virtual-server/list-domains.pl --multiline --domain $domain")); // Strip out and save quota details $quota = array_values(preg_grep("/Server quota/", $dom_return)); $quota_avail_tmp = explode(":", $quota[0]); $quota_used_tmp = explode(":", $quota[1]); $quota_avail = $quota_avail_tmp[1]; $quota_used = $quota_used_tmp[1]; // Strip out and save bandwidth details $bandwidth = array_values(preg_grep("/Bandwidth/", $dom_return)); $bandwidth_avail_tmp = explode(":", $bandwidth[0]); $bandwidth_usage_tmp = explode(":", $bandwidth[3]); $bandwidth_avail = $bandwidth_avail_tmp[1]; $bandwidth_used = $bandwidth_usage_tmp[1]; // Set cookies to speed up access setcookie( "Quota_avail_$domain", "$quota_avail", time()+300 ); setcookie( "Quota_used_$domain", "$quota_used", time()+300 ); setcookie( "Bandwidth_avail_$domain", "$bandwidth_avail", time()+300 ); setcookie( "Bandwidth_used_$domain", "$bandwidth_used", time()+300 ); print_r($_COOKIE["Quota_avail_$domain"]); //testing as is not getting caught in the if so see if I can print it on page refresh echo $check; // This prints the string I am hoping for but trying to reference the cookie by this still doesnt work. setcookie( "$domain", "$quota_avail", time()+300 ); // This sets the cookie with the correct name but then if I just use $_COOKIE["$domain"] it still doesnt work } The purpose of this is that I am building a portal to manage all of the domains we host. This is part of the details page which you can view for each domain and one of the things it does is get all the details about a domain and provide you with the storage quota and bandwidth usage. But that command takes 3-5 seconds to load. I am trying to make the whole portal the best experience it can be and one key thing is speed. Due to fact I am populating the majority of the data straight from MySQL everything else is blazingly fast and so I thought that instead of running the command each time I would run it once when you first view the details of a domain and then save it in a cookie for a couple of minutes so you can flick between pages and make any changes without waiting for the command each time. Or go out of the details and go back in etc. The thing is that I need uniquely named cookies so that if you go back to the main page, view another domain and then go back to the original, if you do that within the time frame the command still does not need to re-run so I need a cookie with the details for each domain you view. Now I have explained that, the problem I am having is that I dont seem to be able to reference a super global by a variable. You can see from the code I have tried a number of different options to achieve it. As a trial and error I tried setting the cookie name to be just the domain name and then referenced that to save combining the string with the variable when I was trying to reference it but that still didn't work. I tried: $_COOKIE["$domain"]; and $_COOKIE[$domain]; But got nothing returned so I am fairly certain that what I am trying to do is not possible. But I welcome any suggestions or ideas? Quote Link to comment Share on other sites More sharing options...
ManiacDan Posted August 23, 2012 Share Posted August 23, 2012 Why do you believe the cookie is full of data about your domains? That's probably the first question you should answer. Have you used setcookie() for some reason to fill this data to the user's cookies on their computer? Have you done print_r($_COOKIE) to see what's in the cookie? Quote Link to comment Share on other sites More sharing options...
Jessica Posted August 23, 2012 Share Posted August 23, 2012 That was my first thought too but he is doing it, it's in the else{} block. OP what is the output of it? Quote Link to comment Share on other sites More sharing options...
ben m Posted August 23, 2012 Author Share Posted August 23, 2012 Sorry I did try and explain what I was doing. The page itself provides details on domains which we host. And for domains which have websites it runs a command: $dom_return = explode("\n", shell_exec("sudo /usr/share/webmin/virtual-server/list-domains.pl --multiline --domain $domain")); Which populates a whole host of information regarding the website into $dom_return. I then break all that down and I am left with 4 variables; $quota_avail, $quota_used, $bandwidth_avail and $bandwidth_used. Which contain the used and available storage quota and bandwidth respectively: // Strip out and save quota details $quota = array_values(preg_grep("/Server quota/", $dom_return)); $quota_avail_tmp = explode(":", $quota[0]); $quota_used_tmp = explode(":", $quota[1]); $quota_avail = $quota_avail_tmp[1]; $quota_used = $quota_used_tmp[1]; // Strip out and save bandwidth details $bandwidth = array_values(preg_grep("/Bandwidth/", $dom_return)); $bandwidth_avail_tmp = explode(":", $bandwidth[0]); $bandwidth_usage_tmp = explode(":", $bandwidth[3]); $bandwidth_avail = $bandwidth_avail_tmp[1]; $bandwidth_used = $bandwidth_usage_tmp[1]; The problem is that the initial command takes about 3-5 seconds to run, and that happens each time you load the page. Now if a user is going to be updating details, flicking between pages etc. it is going to be very tedious waiting for this page to load each time and I want the portal to be as quick and responsive as I can make it. So I decided I would save each of those 4 variables in a cookie on the EU's PC. Only for a short amount of time, I set the expiry to three minutes as the data updates all the time so I did not want it to be to far out of date and I decided that if they are making changes to a domain they aren't really going to be doing so for more than three minutes so that is a reasonable time. I have used print_r($_COOKIE); and it does show all the four cookies I have saved, with the correct names and correct values so that is all working as I expected. My problem is coming when I try to retrieve the cookie. What I do is initially assign the domain which is being viewed to a variable named $domain: $domain=$_GET['domain']; I am then checking to see if there are already cookies for that domain. If there are then assign them to variables ($quota_avail, $quota_used, $bandwidth_avail and $bandwidth_used) and if not run the command, populate the variables from the output from the script and then assign the cookies so that next time the page is loaded, if it is within 3 minutes then take the data from the cookies instead of rerunning the command. Any lines of code with comments at the end instead of on the preceding line are just me trying to test and get it working so they can be ignored. the line assigning the variable $check can also be ignored as that was also just testing. I just included them for reference to help give an indication of what I am trying to achieve. But ignoring those you can see what I am trying to get at. The problem is occurring when I try and reference a particular cookie. I set a cookie: setcookie( "Quota_avail_$domain", "$quota_avail", time()+300 ); And say in that example $domain=example.com. I can then see the cookie exists, it has the name "Quota_avail_example.net" and contains the data which was in $quota_avail so that all works fine. If I then try and reference that cookie, say in the IF statement or directly from a print_r using a variable: print_r($_COOKIE["Quota_avail_$domain"]); I get nothing returned. ($domain IS set correctly, that can be verified with a print of $domain in the preceding line). If I try and reference the cookie directly: print_r($_COOKIE['Quota_avail_example.com']); I get the cookie cookie array printed. The problem is occurring at the point when I try and retrieve the cookie by its direct name but create the name dynamically. Hopefully that explains better what I am trying to do? Quote Link to comment Share on other sites More sharing options...
Jessica Posted August 23, 2012 Share Posted August 23, 2012 So to sum it up print_r($_COOKIE['Quota_avail_example.com']); // prints the cookie array print_r($domain); //prints example.com print_r($_COOKIE["Quota_avail_$domain"]); // empty? That's what you're saying? Quote Link to comment Share on other sites More sharing options...
Christian F. Posted August 23, 2012 Share Posted August 23, 2012 I haven't had time to really study the issue you're having in detail, but there was one question that really stood out to me: What happens if the user edits the cookie, and adds domains which he does not control? If I were you, I'd at least use a session for this. Preferably, save the data in a proper database instead of running that script every page load. Quote Link to comment Share on other sites More sharing options...
ManiacDan Posted August 23, 2012 Share Posted August 23, 2012 Another thing I noticed: And say in that example $domain=example.com. I can then see the cookie exists, it has the name "Quota_avail_example.net" Typo? Or the actual problem? Either way, Christian is right. Cookies are wrong for this, use the session. Then you don't have to mess with setcookie() or anything, just treat the session like one big array: $_SESSION[$domain]['quota']; //etc. Quote Link to comment Share on other sites More sharing options...
ben m Posted August 23, 2012 Author Share Posted August 23, 2012 So to sum it up print_r($_COOKIE['Quota_avail_example.com']); // prints the cookie array print_r($domain); //prints example.com print_r($_COOKIE["Quota_avail_$domain"]); // empty? That's what you're saying? Hi Jesi, yup that is exactly what I am saying I haven't had time to really study the issue you're having in detail, but there was one question that really stood out to me: What happens if the user edits the cookie, and adds domains which he does not control? If I were you, I'd at least use a session for this. Preferably, save the data in a proper database instead of running that script every page load. Another thing I noticed: And say in that example $domain=example.com. I can then see the cookie exists, it has the name "Quota_avail_example.net" Typo? Or the actual problem? Either way, Christian is right. Cookies are wrong for this, use the session. Then you don't have to mess with setcookie() or anything, just treat the session like one big array: $_SESSION[$domain]['quota']; //etc. Christian and Dan. Thank you, this is the sort of thing I was after, alternative and preferred/more efficient ways of doing things. I will look into using session instead. I am pretty new to PHP, well programming in general, I always wanted to learn but never had a project or any goals to set myself until I started going this and I love it The portal is going to be internal anyway so I don't have much worry about people changing cookies etc. And the cookie is not for access to a page, its just to speed up the loading of pages. I will look into and swap to using a session though if that works for me. Plus if this is ever offered to external users to manage there own domains I would prefer to have this done correctly in the first instance, and I would also like to learn to do things in the correct manner. Oh and yea, the example.com/net was a typo. I just used it as an example and rushed it out before I left work Quote Link to comment Share on other sites More sharing options...
ben m Posted August 23, 2012 Author Share Posted August 23, 2012 OK I have looked at the session and I am not sure session's are what I need. I am only using the cookie to cache data, to save running that script every time the page is loaded to increase performance. If someone was to manually edit the cookie all they would not achieve anything to compromise the site as it doesn't grant or provide any data except how much storage and bandwidth a website has used. If I was to use sessions I would have to implement timeouts for the session etc. Is that really the correct way to implement something like this? I understand the point of sessions (I think), and see where they would be used, but that is why I am not not sure its what I need? Quote Link to comment Share on other sites More sharing options...
Christian F. Posted August 23, 2012 Share Posted August 23, 2012 A session is almost the same as a cookie, with the biggest difference being that the session data never leaves the server. Thus it cannot be manipulated by the user, but is still loaded from disk every time you start a session with a defined session ID. Note that the session ID is sent to the user, as a cookie, and as such can be captured and manipulated as well. It raises the bar considerably though, as any potential attacker needs to find an active session ID. Not just set the domain information at will. There are steps that can, and should, be taken to further increase the bar of an attack. Primary of which are generating new session IDs upon a successful login. Sessions are for storing data between page loads, which are specific to the individual browser loading a set of pages from the same server in succession. Quote Link to comment Share on other sites More sharing options...
Jessica Posted August 23, 2012 Share Posted August 23, 2012 Sessions are in fact what you want to use. You don't need to do anything with timeouts, the session expires when the user closes the browser. Quote Link to comment Share on other sites More sharing options...
xyph Posted August 23, 2012 Share Posted August 23, 2012 Here's how you'd do it with sessions. <?php session_start(); error_reporting(E_ALL); $domain=$_GET['domain']; $update=$_GET['update']; if ( isset($_SESSION['domains'][$domain]) && $_SESSION['domains'][$domain]['expire'] > time() ) { $quota_avail = $_SESSION['domains'][$domain]['quota_avail']; $quota_used = $_SESSION['domains'][$domain]['quota_used']; $bandwidth_avail = $_SESSION['domains'][$domain]['band_avail']; $bandwidth_used = $_SESSION['domains'][$domain]['band_used']; } else { // Get domain info $dom_return = explode("\n", shell_exec("sudo /usr/share/webmin/virtual-server/list-domains.pl --multiline --domain $domain")); // Strip out and save quota details $quota = array_values(preg_grep("/Server quota/", $dom_return)); $quota_avail_tmp = explode(":", $quota[0]); $quota_used_tmp = explode(":", $quota[1]); $quota_avail = $quota_avail_tmp[1]; $quota_used = $quota_used_tmp[1]; // Strip out and save bandwidth details $bandwidth = array_values(preg_grep("/Bandwidth/", $dom_return)); $bandwidth_avail_tmp = explode(":", $bandwidth[0]); $bandwidth_usage_tmp = explode(":", $bandwidth[3]); $bandwidth_avail = $bandwidth_avail_tmp[1]; $bandwidth_used = $bandwidth_usage_tmp[1]; $_SESSION['domains'][$domain]['expire'] = time() + 300; $_SESSION['domains'][$domain]['quota_avail'] = $quota_avail; $_SESSION['domains'][$domain]['quota_used'] = $quota_used; $_SESSION['domains'][$domain]['band_avail'] = $bandwidth_avail; $_SESSION['domains'][$domain]['band_used'] = $bandwidth_used; } ?> Simply handle any expiry times within the session itself. Quote Link to comment Share on other sites More sharing options...
Christian F. Posted August 23, 2012 Share Posted August 23, 2012 What Jesi wrote is not quite correct, or rather accurate, I'm afraid. The session cookie gets deleted when the user closes the browser, but the session itself still lives on on the server. The only way to actually remove a session before the timer expires, is to manually destroy it. Normally done via a logout page. Quote Link to comment Share on other sites More sharing options...
Jessica Posted August 23, 2012 Share Posted August 23, 2012 Good point, but the files on the server get cleaned up periodically, correct? Quote Link to comment Share on other sites More sharing options...
ben m Posted August 23, 2012 Author Share Posted August 23, 2012 OK I see. Thank you very much for your help everyone, I got exactly the sort of help and advice I was looking for so I really appreciate it Quote Link to comment Share on other sites More sharing options...
Christian F. Posted August 23, 2012 Share Posted August 23, 2012 Jesi: Yes, it does. But only after the session max life has been reached, and even then the garbage collector isn't run on every load. The php.ini settings control both the max lifetime, and the probability of the session garbage collector being triggered1. Until that time, anyone who can replicate the cookie will get access to the session. Ben: You're most welcome, and I'm glad we could be of help. 1Not sure if the garbage collector always cleans out the session in question, if the max lifetime has been exceeded, or if it allows it to be loaded. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.