Jump to content

Reference a super global by a variable


ben m

Recommended Posts

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?

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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? :)

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 :)

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.