treehouse : what would you like to learn today?
Web Design Web Development iOS Development

[Solved] PHP Switch/Case and the Dreaded Unclean URLs

  • I just wanted to see if by posting this, I could get a response that actually fixes the listed issues with using Switch/Case.

    Problems

    1. How does one take these very unattractive URLs that are outputted by switch/case and make them display clean (seo friendly)?

    Update: Problem Number 1 Fixed. Much thanks to CrocoDillon.

    2. Once accomplished, how does one change the active Navigation link to remain highlighted?

    Update: Problem Number 2 Fixed. Much thanks to CrocoDillon and BenWalker.

    Part 1.) I have always practiced the use of switch/case (php) with my websites. Back in the not too distant past it wasn't such a problem to have this, but in today's modern expectations, not only by the search engine crawlers, but giving out a specific link to your colleague is very frustrating when having to provide them with something such as http://www.mysite.com/index.php?page=mypage.

    Of course I am talking about the following:

    <?php
      
        if (!isset($_GET['page']))
          $_GET['page'] = null;
        
        switch ($_GET['page']) {
      
          case "home":
        include('mydir/home.php');
        break;
        
          case "about":
        include('mydir/about.php');
        break;
      
          case "contact":
        include('mydir/contact.php');
        break;
      
        // Default Page
          default:
        include('mydir/home.php');
        break;
      }
      
      ?>
    

    The use of switch/case will output the links as follows:

    http://www.mysite.com/index.php?page=home

    http://www.mysite.com/index.php?page=about

    http://www.mysite.com/index.php?page=contact

    So, I understand that this can be cleaned up through the use of the .htaccess file, however, I have tried many ways and still no luck. So the question I have is this:

    How do I get this link:

    http://www.mysite.com/index.php?page=home

    to turn into

    http://www.mysite.com/home

    Part 2.) Once this has been accomplished, how does one get the main navigation to display the currently active link/page as highlighted?

    Example: Say I go to the about page by clicking on the about navigation link, while on the about page that link should show an active state. Any thoughts?

    Note: I have seen a few things on this site, by Chris that explain this, but what I have found is mostly for WordPress and I am not using WordPress. Also, I want to ensure that the 'home' navigation link is highlighted as active upon going to the website initially.

    If I could get some help with this/these nightmare(s) it would be greatly appreciated... Thanks in advance!

  • Part 1: Not a star on rewrite rules but this should work...

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php?$1 [NC,L]
    

    Basically rewrites /home to /index.php?home if the requested url is not a file (-f) or directory (-d). [NC,L] means it's case insensitive and the last rule to apply. You can get the value home from $_SERVER['QUERY_STRING']. You can probably use this value to highlight your currently active link too.

  • Yeah that's what I currently have, but for some reason that takes me to my "WampServer Configuration Page"... :/

  • What does your full url look like when you develop locally?

  • I mean in the browser bar, http:// and then?

  • I think that's the issue... it redirects to the root which is http://127.0.0.1, so http://127.0.0.1/index.php?home. Set up a vhost like http://rpotterjr/ or http://rpotterjr.dev/ or something so your site is at root level.

  • In C:\Windows\System32\drivers\etc\hosts add 127.0.0.1 rpotterjr.dev

    In C:\Program Files\wamp\bin\apache\apache2.2.22\conf\extra\httpd-vhosts.conf add

    <VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot "C:\path\to\your\public\folder"
        ServerName rpotterjr.dev
        ErrorLog "logs/rpotterjr-error.log"
        CustomLog "logs/rpotterjr-access.log" common
        <Directory "C:\path\to\your\public\folder">
            Options Indexes FollowSymLinks
            AllowOverride all
            Order Deny,Allow
            Deny from all
            Allow from 127.0.0.0/255.0.0.0 ::1/128
        </Directory>
    </VirtualHost>
    

    Then restart all services from the wampserver menu.

  • For some reason when I use http://rpotterjr.dev it takes me to the "WampServer Configuration Page"... Did both of what you said to do...

  • Hmmm I had the same issue once, but forgot how I fixed it. I'll look into it.

  • Can't seem to find it :( Try Google how to set up virtual hosts on Apache because it will definitely fix the .htaccess Rewrite issue.

  • Ok, nevermind. I setup the Virtual Host and now it is redirecting me to my home page. The address in the address bar is changing, but the page content is NOT.

  • In other words, the address changes through:

    rpotterjr.dev/about

    and

    rpotterjr.dev/contact

    However, the content stays stuck on the home page's content.

  • If I revert back to not having the rewrite, I can navigate from page to page changing the content, but the address displays as http://rpotterjr.dev/index.php?page=about

  • Change switch ($_GET['page']) { to switch ($_SERVER['QUERY_STRING']) {

    If that doesn't work try var_dump($_SERVER['QUERY_STRING']) and see what you get.

  • No change...

  • So, what did var_dump get you?

  • Nothing different. I tried restarting the server and clearing browser cache...

    No change..

  • I was at this stage before without the Virtual Server by specifying the root in php, but couldn't ever get past this problem...

  • Put var_dump($_SERVER['QUERY_STRING']) in you index.php file (before the switch), and show me what it gives with and without the .htaccess file.

  • Maybe you have to enable mod_rewrite in your apache install.

  • I have mod_rewrite enabled. As for the var_dump($_SERVER['QUERY_STRING']), nothing is different. Just back at square one again...

  • Nothing is different doesn't give me much info to work with.

  • I can make the var_dump($_SERVER['QUERY_STRING'])

    before the switch/case in a separate statement, but all that does is display a count of the character length of each link clicked.

  • The address changes through:

    rpotterjr.dev/about

    and

    rpotterjr.dev/contact

    However, the content stays stuck on the home page's content.

    If I revert back to not having the rewrite, I can navigate from page to page changing the content, but the address displays as http://rpotterjr.dev/index.php?page=about. This is with or without var_dump($_SERVER['QUERY_STRING'])

  • So here is my code currently:

    .htaccess RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php?$1 [NC,L]
    
  • PHP case/switch

    <?php
      
        if (!isset($_GET['page']))
          $_GET['page'] = null;
        
        switch ($_GET['page']) {
        
          case "portfolio":
        include('theme/default/pages/portfolio.php');
        break;
        
        case "resume":
        include('theme/default/pages/resume.php');
        break;
        
        case "about":
        include('theme/default/pages/about.php');
        break;
        
        case "contact":
        include('theme/default/pages/contact.php');
        break;
        // Default Page
          default:
        include('theme/default/pages/home.php');
        break;
      }
      
      ?>
    
  • The I guess QUERY_STRING just reads the URL instead of using the internal rewriting. Try var_dump($_GET) (with .htaccess) to see if the 'page' key (it won't be called page unless you change the .htaccess file) is in there. If it is, you can use something like if (isset($_GET['about'])) {...} etc.

  • Maybe try

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php?page=$1 [NC,L]
    
  • Ok, can you write that into what I posted, because I have a feeling I'm missing something...

  • Actually, ya know what that last change you made to the mod_rewrite fixed it...

  • You Rock CrocoDillon! lol Thanks soo much! Now, I just need to figure out the active navigation link part...

  • You're welcome, glad it finally works :)

    Something like:

     <li><a href="portfolio"<?php if ($_GET['page'] == 'portfolio') echo ' class="active"'; ?>>Portfolio</a></li>
    

    could work.

  • That throws off a crap load of parsing errors... :(

  • <?php
          if (!isset($_GET['page']))
            $page = 'home';
          else
            $page = $_GET['page'];
          switch ($page) {
          
            case "portfolio":
          include('theme/default/pages/portfolio.php');
          break;
          
          case "resume":
          include('theme/default/pages/resume.php');
          break;
          
          case "about":
          include('theme/default/pages/about.php');
          break;
          
          case "contact":
          include('theme/default/pages/contact.php');
          break;
      
          case "home":
            include('theme/default/pages/home.php');
            break;
    
          // Default Page
            default:
          include('theme/default/pages/home.php');
          break;
        }
        
        ?>
    

    You have access to the "$page" variable to test for which page is active in your nav menu. Of course, you could just use "$_GET['page']" each time, but it's less tidy.

  • Should be able to use jQuery to set Active Navigation, but so far everything I try is only highlighting the 'home' link.

  • Could you post your code?

  • For the parse errors I'd need to see the whole file where you create the menu.

    Nice catch about the $page variable Ben :)

  • I have tried what is shown here:

    http://css-tricks.com/snippets/jquery/add-active-navigation-class-based-on-url/

    However, in my case it is not working...

  • The menu is simply this in html:

    http://pastebin.com/gB2uHSDH

  • Chris used to have something on here showing a way to do this with jQuery by link id, but I can't find the shit.

  • Because you don't have the / that's in the jQuery selector. I'd prefer a php solution over a js one though.

  • I found his version before and modified it and it worked, but I lost all my files due to a electrical crash of my backup server...

  • The menu can't be simple html, else you wouldn't get parse errors.

  • Yeah. I tried the above php method, but it didn't do anything. It just cause some php perrors. I can try it again...

  • By the way, I'm surprised this hasn't come up already...

    I assume you will have a root variable for your site's root directory (I'll call it "$root"):

    <?php
          if( !isset( $_GET['page'] ) )
            $page = 'home';
          else
            $page = $_GET['page'];
          if( file_exists( $root . 'theme/default/pages/' . $page . '.php' ) )
              include( 'theme/default/pages/' . $page . '.php' );
          else
              include( 'theme/default/pages/404.php' );
    
  • Oh, I see the problem... I need to specify that the default index page uses home.php

  • Ok, so my default page is 'home', so how would this be written? The above code you gave didn't change anything.

  • When going directly to http://rpotterjr.dev I get errors. If I go to http://rpotterjr.dev/home I no longer have any errors. Any suggestions?