Go Back  HTML Forums - Free Webmaster Forums and Help Forums > WEBSITE DEVELOPMENT > All Around Tutorials > Serverside Scripting Tutorials
User Name:
Password:
 

Reply
Thread Tools   Display Modes
  View First Unread
 
Old 11-12-2006, 12:50 AM
  #1
erisco
P(s|h)?i
 
erisco's Avatar
 
Join Date: Dec 2005
Location: Within the division of zero
Posts: 5,795
iTrader: (0)
erisco will become famous soon enougherisco will become famous soon enough
Making a breadcrumb in PHP

Please Note:
While this function should still work, I have written a new one which you can download directly at http://pack.abstractflow.com/php/bre...breadcrumb.zip it functions much like this one. Instructions are included in the file. Please let me know of any issues with this new breadcrumb function.

Notes before starting
It is assumed you already know how to use PHP on your webpages. The basics of knowing a '.php' extension, and calling a function and passing variables to it. Potentially how to use includes, and in that case knowing how to navigate a filesystem.

First off, what is a breadcrumb?
This is easily answered with an example. Let's say we are currently visiting, say this address:
Code:
http://www.example.com/foo/bar/file.php?get=data#fragment
The breadcrumb serves the purpose of breaking this down. After it does that, it can output links to each directory, the root, and the current file. This is is a navigation feature suitable for any website.

An example output of that URL would be:
Home / Foo / Bar / file.php

If you hover over those links you should be able to see each location in your status bar (and if not just click the links). It should be self-explanatory how this can be useful for navigating a website.

Now to get to the actual code.

PHP Code:
<?php
function breadcrumb(
    
$home 'Home'// Name of root link
    
$division ' / '// Divider between links
    
$hidextra true// Toggle hide/show get data and fragment in text
    
$index false,  // Toggle show/hide link to directory if it does not contain a file
    
$indexname 'index.php' // The definition of the file the directory must contain
) {

    
$whole $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    
$parts explode('/'$whole);
    
$parts[0] = 'http://'.$parts[0];

    
$breadcrumb .=  '<a href="'.$parts[0].'">'.$home.'</a>'.$division;
    
$k 1;
    for (
$i=1;$i sizeof($parts);$i++) {
        
$uri '/';
        while (
$k <= $i) {
                
$uri .= $parts[$k];
                if (
$k != (sizeof($parts)-1)) $uri .= '/';
                
$k++;
         }

          if (
$index && is_dir($_SERVER['DOCUMENT_ROOT'].$uri) && is_file($_SERVER['DOCUMENT_ROOT'].$uri.$indexname
        || !
$index 
        
|| !is_dir($_SERVER['DOCUMENT_ROOT'].$uri)) {
            
$breadcrumb .= '<a href="'.$uri.'">';
            if (
$hidextra) {
                
$breadcrumb .= implode(''array_slice(explode('?'ucfirst($parts[$i])), 0, -1));
            }
            else {
                
$breadcrumb .= ucfirst($parts[$i]);
            }
            
$breadcrumb .= '</a>';
        }
        else {
            
$breadcrumb .= ucfirst($parts[$i]);
        }

          if (isset(
$parts[($i+1)])) {
            
$breadcrumb .= $division;
        }
          
$k 1;
    }
    return 
$breadcrumb;
}
?>
Complicated? No fear, no editing of that portion is needed. You simply need it in every file that you want the breadcrumb to appear on. For ease, you can create a new file "breadcrumb.php" and include() this file onto your pages. This way you don't have to copy and paste it over and over. However, even though this is optional, I will still use it in my example.

So let's assume I have my file "breadcrumb.php" with the above function in it. Now I have another file. To use the breadcrumb I am going to include it.

newfile.php
PHP Code:
<?php
include 'breadcrumb.php';
?>
Keep note of directories when including a file.

Now I need to call the function. The function already has some default values. You may or may not change these when calling the function. here is a rundown...

The first argument is the name of the "root link". So the link to http://www.example.com will be masked as "Home", or to whatever you specify.

The second argument is the divider between links. So between Home and newfile.php there will be a forward slash.

The third argument says whether to hide get data and fragments from the TEXT of the file link. The get data and fragment will still be in the HREF in the HTML source. This feature was added because some sites use really long get data strings, and this would break a page since it is usually one solid line of text.

The fourth argument toggles "file sensitivity". (true is on and false is off) This is meant to be used to check if there is an index file in the directory before making a link to it. The text will still be displayed, just not an HTML link surrounding it.

The fifth argument is the filename the fourth argument checks for. See if there is no index file in a directory and the breadcrumb makes a link to it, if someone clicks on that link they will either get a directory listing (potentially bad) or a 403 error. If the breadcrumb checks to make sure the index file exists first, the link will not show up and only the text. However the way it has been setup, the breadcrumb can actually check for any file in any directory before making the link. **NOTE: to never display a link for a directory, simply require the function to look for a file that will never exist.

Feel free to change the defaults in the function! This will save time when calling the breadcrumb() function if your arguments are already there.

newfile.php
PHP Code:
<?php
include 'breadcrumb.php';
echo 
breadcrumb();
?>
Try that out! Make some dummy directories to see the breadcrumb in action.

If you want to override the defaults you have set, you must override them in the order they were set in the function. The argument order is still the same.

Try out these calls:
PHP Code:
echo breadcrumb('Bring Me Home'' // '); 
PHP Code:
echo '{'.breadcrumb('Root''}{').'}'
PHP Code:
echo breadcrumb('Home'' \ 'falsetrue); 
Be creative, and enjoy!
__________________
Haven't updated my signature in forever!
Namespaces in PHP 5.3 | Taking up some C | Getting more Pythonic...
Confused on framework choice? Agavi.

Last edited by erisco : 02-02-2008 at 12:09 AM.
erisco is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 11-17-2006, 12:34 PM
  #2
platey
Novice (Level 1)
 
Join Date: Nov 2006
Posts: 3
iTrader: (0)
platey is an unknown quantity at this point
Talking

Beautiful PHP!

this is exactly what ive been looking for, thank you!

my only questions regarding this code -

is there anyway you can code it to hide or take off the .php suffixes when it displays it back to the viewer/user? which leads me towards this question: on the Home page is there any way that the code can take away the index file rather than have it display this 'Home / index.php'??

also, my css doesnt seem to have any affect to the script, regarding positioning, once pulled in.

thanks again though!
platey is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 11-18-2006, 12:31 PM
  #3
erisco
P(s|h)?i
 
erisco's Avatar
 
Join Date: Dec 2005
Location: Within the division of zero
Posts: 5,795
iTrader: (0)
erisco will become famous soon enougherisco will become famous soon enough
Here is a script with your desired modifications

PHP Code:
<?php
function breadcrumb(
            
$home 'Home'// Name of root link
            
$division ' / '// Divider between links
            
$hidextra true// Toggle hide/show get data and fragment in text
            
$index false,  // Toggle show/hide link to directory if it does not contain a file
            
$indexname 'index.php' // The definition of the file the directory must contain
) {

    
// Requested addons...
    
$extension '.php'// Extension to cut off the end of the TEXT links
    
$ifIndex 'index.php'// Filename of index/default/home files to not display
    // End requested addons

    
$whole $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    
$parts explode('/'$whole);
    
$parts[0] = 'http://'.$parts[0];

    
$breadcrumb .=  "<a href=\"{$parts[0]}\">{$home}</a>{$division}";
    
$k 1;
    for (
$i=1;$i sizeof($parts);$i++) {
        
$uri '/';
        while (
$k <= $i) {
                
$uri .= $parts[$k];
                if (
$k != (sizeof($parts)-1)) $uri .= '/';
                
$k++;
         }

          if ((
$index && is_dir($_SERVER['DOCUMENT_ROOT'].$uri) && is_file($_SERVER['DOCUMENT_ROOT'].$uri.$indexname
        || !
$index 
        
|| !is_dir($_SERVER['DOCUMENT_ROOT'].$uri)) && $parts[$i] != $ifIndex) {
            
$breadcrumb .= "<a href=\"$uri\">";
            if (
$hidextra) {
                
$breadcrumb .= rtrim(preg_replace("/\?.*$/"''ucfirst($parts[$i])), $extension);
            }
            else {
                
$breadcrumb .= rtrim(ucfirst($parts[$i]), $extension);
            }
            
$breadcrumb .= '</a>';
        }
        else {
            
$breadcrumb .= ucfirst($parts[$i]);
        }

          if (isset(
$parts[($i+1)])) {
            
$breadcrumb .= $division;
        }
          
$k 1;
    }
    return 
$breadcrumb;
}

echo 
'{'.breadcrumb('Root''}{').'}';
echo 
'<br>';
echo 
breadcrumb('Bring Me Home'' // ');
?>
I didn't put the addons into the passed arrays, I didn't feel there would be a need to because all servers should only have one permitable filename for your index/home/default or whatever. Also most web masters or developers typically keep the same file extensions and don't mix up .php and .html and .htm and the whatnot.

If you want your CSS to work with it, try this call:

PHP Code:
echo '<span class="breadcrumb">'.breadcrumb().'</span>'
Now in your CSS you can do the following:

Code:
.breadcrumb A:link, .breadcrumb A:visited, .breadcrumb A:hover, .breadcrumb A:active {
text-decoration:underline;
color:#333;
}
.breadcrumb A:hover {
color:#990000;
}
Just for example. You can output whatever you want around the breadcrumb for customized appearance.

I hope this helps!
__________________
Haven't updated my signature in forever!
Namespaces in PHP 5.3 | Taking up some C | Getting more Pythonic...
Confused on framework choice? Agavi.
erisco is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 11-20-2006, 05:34 AM
  #4
platey
Novice (Level 1)
 
Join Date: Nov 2006
Posts: 3
iTrader: (0)
platey is an unknown quantity at this point
Seriously erisco, this is brilliant!

Thank you for this, and i hope someone else will stumble across this code and find it as useful as i did!
platey is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 03-21-2007, 06:39 PM
  #5
Mac
SuperHero (Level 14)
 
Join Date: May 2001
Location: SF, CA
Posts: 276
iTrader: (0)
Mac is on a distinguished road
I literally just stumbled upon this code....absolutely brilliant.
__________________
Mac
Mac is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 03-21-2007, 07:13 PM
  #6
erisco
P(s|h)?i
 
erisco's Avatar
 
Join Date: Dec 2005
Location: Within the division of zero
Posts: 5,795
iTrader: (0)
erisco will become famous soon enougherisco will become famous soon enough
Great to see the script came into good use! Thank-you for the compliments. To better the script I sped up a couple of the strings, but the main improvement was dropping the need for preg_replace() to slice off query strings which will use the regex engine. Although the new alternative using a few more, yet faster, functions isn't as perfect it will certainly still do the job. If anyone has problems with this change please let me know and I can rework a solution. Also keep note that only the original script changed and not the one platey requested.

Thanks!
erisco
__________________
Haven't updated my signature in forever!
Namespaces in PHP 5.3 | Taking up some C | Getting more Pythonic...
Confused on framework choice? Agavi.
erisco is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 03-24-2007, 11:42 AM
  #7
robin1
Novice (Level 1)
 
Join Date: Mar 2007
Posts: 1
iTrader: (0)
robin1 is an unknown quantity at this point
breadcrumb help

Hello,
I'm new to php and i'm working on a small classified script for my website. I'm trying to add the script you posted here and could use some help.
right now i'm testing the scrip on my local PC(apache,php,mysql).

the script works awesome but not sure how to modify to fit my classified script.
folder the php scripts are located: http://192.168.0.101/classified/

http://192.168.0.101/classified//index.php , i added the breadcrumb function:
breadcrumb('Classified', ' >> ', false, false)

after running it it displays the the following:
Classified >> Classified >>
how do i just display the classified rather the the url and classified i entered in the breadcrumb?

sec problem:
when i click on a category it goes to page_2 (as it should) but it displays:
page2 >> Classified >> Page_2.php?subcat=Housing
it moves page2 to the beginning and classified(which is the main page) to the sec spot?

any help you can give me would be greatly appreciated.
Thanks
robin

Last edited by robin1 : 03-24-2007 at 11:44 AM. Reason: for clearfication in my description
robin1 is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 03-24-2007, 03:19 PM
  #8
Paul
Super Deity (Level 18)
 
Paul's Avatar
 
Join Date: Mar 2001
Location: 127.0.0.1
Posts: 3,954
iTrader: (0)
Paul will become famous soon enoughPaul will become famous soon enough
Looks like google picked up on this, just search for breadcrumb PHP and this post comes up toward the top. Congrats erisco, you are famous .
__________________

Pawel Kowalski
Albuquerque Web Design

templatesXchange.com - Free Web Templates
Paul is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 03-26-2007, 12:21 AM
  #9
johnz
charlie dont surf!
 
johnz's Avatar
 
Join Date: May 2006
Location: Long Island, New York
Posts: 1,237
iTrader: (0)
johnz will become famous soon enough
Great stuff erisco! I'm sure this will be helpful for many people.
__________________
Job: collegehumor.com
Blog: johnzanussi.com


If someone has helped you be sure to add to their reputation
johnz is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 04-02-2007, 10:43 PM
  #10
erisco
P(s|h)?i
 
erisco's Avatar
 
Join Date: Dec 2005
Location: Within the division of zero
Posts: 5,795
iTrader: (0)
erisco will become famous soon enougherisco will become famous soon enough
robin1, the script relies on splitting the url at forward slashes. In the url http://192.168.0.101/classified//index.php there is a double forward slash which is probably the culprit. The other problems may have cascaded from this.

If the url must contain two forward slashes, for whatever reason, do a realpath() call on $_SERVER['REQUEST_URI'] so that the line looks like this:

PHP Code:
    $whole $_SERVER['HTTP_HOST'].realpath($_SERVER['REQUEST_URI']); 
And that should clear it up.

Paul, wow, that is pretty neat I don't think I have ever had something less than six keywords long appear on the first page of Google before heheh.

johnz, thanks, happy PHP'ing!
__________________
Haven't updated my signature in forever!
Namespaces in PHP 5.3 | Taking up some C | Getting more Pythonic...
Confused on framework choice? Agavi.
erisco is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 04-28-2007, 04:18 PM
  #11
sugar_lisx
Novice (Level 1)
 
Join Date: Apr 2007
Posts: 1
iTrader: (0)
sugar_lisx is an unknown quantity at this point
hey, That code is the only code that works for me!
Is there a way of labeling the directories? So it doesn't come up as the file name? If that makes sense?
thanks
sugar_lisx is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 04-29-2007, 07:45 PM