views:

810

answers:

4

I have a drop down list where users can select a theme for the site. The only problem is, I'm not quite sure how to properly load the theme once they press "Apply". I am new to PHP. I know if I use GET, it will pass the variables through a the current page and add them to the end of the URL. I would really like to avoid that. So, I guess my question is, how can I avoid using GET to update the theme? Thank you.

Here is my code to load the correct theme:

<?php
$stylesArr = array('Default', 'Black', 'Pink', 'Green', 'Red');
if(isset($_GET['theme']) && in_array($_GET['theme'], $stylesArr)) {
 $style = $_GET['theme'];
    setcookie("theme", $style, time()+(60*60*24*30));
} else {
    if(isset($_COOKIE['theme']) && in_array($_COOKIE['theme'], $stylesArr)) {
        $style = 'CSS/' . $_COOKIE['theme'] . '.css';
    } else {
        $style = 'CSS/Default.css';
    }
}
?>

Here is my drop down list to select the theme:

<form action="<?php echo $_SERVER["PHP_SELF"] ?>" method="post">
<p>Site Theme:
<select name="theme">
<option value="Default">Default</option>
<option value="Black">Black</option>
<option value="Pink">Pink</option>
<option value="Green">Green</option>
<option value="Red">Red</option>
</select>
<input type="submit" value="Apply" />
</form>
+1  A: 

You are using POST as the method for your form, not GET, thus nothing will be appended to the url, just change all $_GET to $_POST in your php code.

code_burgar
A: 

Swap $_GET for $_POST. And if it were me i would either post to a separate file e.g theme_manager.php then store it in a session or cookie, then reload the other page

header("Location: xxxxx.php");
exit(); # exit is important as page needs to exit and reload for cookie to work.

Hope that helps!

here is what you need:

choose_style.php
<?
$stylesArr = array('Default', 'Black', 'Pink', 'Green', 'Red');
if(isset($_COOKIE['theme']) && in_array($_COOKIE['theme'], $stylesArr)) {
    $style = 'CSS/' . $_COOKIE['theme'] . '.css';
} else {
    $style = 'CSS/Default.css';
}
?>
<link rel="stylesheet" href="<? echo $style; ?>">

## drop down code with form posting to theme_switch.php

theme_switch.php

<?
$stylesArr = array('Default', 'Black', 'Pink', 'Green', 'Red');
if(isset($_POST['theme']) && in_array($_POST['theme'], $stylesArr)) {
    $style = $_POST['theme'];
    setcookie("theme", $style, time()+(60*60*24*30));
}

header("Location: choose_style.php"); # this will reload your theme selector
exit(); # this will make sure the cookie gets loaded next time.

?>
Lizard
Ok, I was just going to ask why when I hit "Apply", it loads the page without any theme. Will header("Location: xxxxx.php"); exit(); fix this problem?
Nate Shoffner
Yeah, the cookie only gets read on the next page load! good luck
Lizard
Where exactly would I put header("Location: xxxxx.php"); exit();?
Nate Shoffner
You would need to put that after all you code before the closing ?>
Lizard
The only problem is, after the user selects the theme, I would like it to display the page they were on with the updated theme.
Nate Shoffner
Thats no problem. replace xxxx.php with the filename where the dropdown is and it will simply reload that page after setting the cookie. I will edit my answer with the code you need.
Lizard
Hmmm, guess I should've pointed out how the page is setup. There is "Index.php", which is the main page. Within that I have have navigation menu and the theme selector is right below that. The navigation menu and theme selector are located in "Navigation.php". (I used <?php include("Navigation.php"); ?>). So I'm not sure if I should automatically redirect the browser back to the previous page from "theme_switch.php".
Nate Shoffner
Ok, I got it. I just replaced header("Location: choose_style.php"); with header("Location:".$_SERVER['HTTP_REFERER'].""); Thank you so much for your help. I really appreciate it. Thanks again.
Nate Shoffner
+1  A: 

Well, method="post" is the right step, I guess.

The PHP code you got there makes my alarm bells go off, however. You must not trust user input from $_GET, $_POST, $_COOKIE etc.! Never!

So what I would suggest is:

  • Use $_POST to get the data from the submitted form
  • Make a PHP array with all valid themes, like this: $valid_themes = array('Default', 'Black', 'Pink', 'Green', 'Red');
  • Before you setcookie() or do anything else with $style or $_COOKIE['theme'] or $_POST['theme'], use http://de.php.net/manual/en/function.in-array.php to check if the submitted theme name is in your array of valid themes.

Without these security measures, your site will be open to XSS attacks: http://en.wikipedia.org/wiki/Cross-site%5Fscripting

KiNgMaR
The PHP array I'm currently using does have all of the valid themes. I might sound really dumb, but I'm very new to PHP. How would I go about using in_array to check if it's a valid theme?
Nate Shoffner
Ah jesus, you *are* already checking that. I didn't read properly. So never mind the alarm bells comment, it's fine. Sorry. Just use $_POST instead of $_GET and you should be set. :-)
KiNgMaR
A: 

do a POST to a page (let's say themeswitcher.php).

There you read the theme the user selected with $_POST["theme"] but the theme in the session (or perhaps even in the database)

and then direct the user back to where he came from by using

header("Location: xxxxx.php"); 
exit();
Natrium