php 简单的动态面包屑

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2594211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 07:03:33  来源:igfitidea点击:

Simple dynamic breadcrumb

phpdynamicbreadcrumbs

提问by Adrian M.

I think this script is of big interest to any noob around here :) including me :)

我认为这个脚本对这里的任何菜鸟都很感兴趣:) 包括我 :)

What I want to create is a little code that I can use in any file and will generate a breadcrumb like this:

我想要创建的是一个小代码,我可以在任何文件中使用它,并将生成一个像这样的面包屑:

If the file is called "website.com/templates/index.php" the breadcrumb should show:

如果文件名为“ website.com/templates/index.php”,面包屑应显示:

Website.com > Templates

 ^^ link                    ^^plain text

 ^^ 链接 ^^ 纯文本

If the file is called "website.com/templates/template_some_name.php" the breadcrumb should show:

如果文件名为“ website.com/templates/template_some_name.php”,面包屑应显示:

Website.com > Templates > Template Some Name

 ^^ link                   ^^link                ^^plain text

 ^^ 链接 ^^ 链接 ^^ 纯文本

回答by Dominic Barnes

This may be overkill for a simple breadcrumb, but it's worth a shot. I remember having this issue a long time ago when I first started, but I never really solved it. That is, until I just decided to write this up now. :)

对于一个简单的面包屑来说,这可能有点矫枉过正,但值得一试。我记得很久以前我刚开始的时候遇到过这个问题,但我从来没有真正解决过它。也就是说,直到我决定现在写下这个。:)

I have documented as best I can inline, at the bottom are 3 possible use cases. Enjoy! (feel free to ask any questions you may have)

我已尽我所能内联记录,底部是 3 个可能的用例。享受!(如有任何问题,请随时提出)

<?php

// This function will take $_SERVER['REQUEST_URI'] and build a breadcrumb based on the user's current path
function breadcrumbs($separator = ' &raquo; ', $home = 'Home') {
    // This gets the REQUEST_URI (/path/to/file.php), splits the string (using '/') into an array, and then filters out any empty values
    $path = array_filter(explode('/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)));

    // This will build our "base URL" ... Also accounts for HTTPS :)
    $base = ($_SERVER['HTTPS'] ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . '/';

    // Initialize a temporary array with our breadcrumbs. (starting with our home page, which I'm assuming will be the base URL)
    $breadcrumbs = Array("<a href=\"$base\">$home</a>");

    // Find out the index for the last value in our path array
    $last = end(array_keys($path));

    // Build the rest of the breadcrumbs
    foreach ($path AS $x => $crumb) {
        // Our "title" is the text that will be displayed (strip out .php and turn '_' into a space)
        $title = ucwords(str_replace(Array('.php', '_'), Array('', ' '), $crumb));

        // If we are not on the last index, then display an <a> tag
        if ($x != $last)
            $breadcrumbs[] = "<a href=\"$base$crumb\">$title</a>";
        // Otherwise, just display the title (minus)
        else
            $breadcrumbs[] = $title;
    }

    // Build our temporary array (pieces of bread) into one big string :)
    return implode($separator, $breadcrumbs);
}

?>

<p><?= breadcrumbs() ?></p>
<p><?= breadcrumbs(' > ') ?></p>
<p><?= breadcrumbs(' ^^ ', 'Index') ?></p>

回答by Sam152

Hmm, from the examples you gave it seems like "$_SERVER['REQUEST_URI']" and the explode()function could help you. You could use explode to break up the URL following the domain name into an array, separating it at each forward-slash.

嗯,从你给出的例子来看,它看起来像“$_SERVER['REQUEST_URI']”,而explode()函数可以帮助你。您可以使用 expand 将域名后面的 URL 分解为一个数组,并在每个正斜杠处将其分开。

As a very basic example, something like this could be implemented:

作为一个非常基本的例子,可以实现这样的事情:

$crumbs = explode("/",$_SERVER["REQUEST_URI"]);
foreach($crumbs as $crumb){
    echo ucfirst(str_replace(array(".php","_"),array(""," "),$crumb) . ' ');
}

回答by 3eighty

Also made a little script using RDFa (you can also use microdata or other formats) Check it out on googleThis script also keeps in mind your site structure.

还使用 RDFa 制作了一个小脚本(您也可以使用微数据或其他格式)在谷歌上查看该脚本还记住了您的网站结构。

function breadcrumbs($text = 'You are here: ', $sep = ' &raquo; ', $home = 'Home') {
//Use RDFa breadcrumb, can also be used for microformats etc.
$bc     =   '<div xmlns:v="http://rdf.data-vocabulary.org/#" id="crums">'.$text;
//Get the website:
$site   =   'http://'.$_SERVER['HTTP_HOST'];
//Get all vars en skip the empty ones
$crumbs =   array_filter( explode("/",$_SERVER["REQUEST_URI"]) );
//Create the home breadcrumb
$bc    .=   '<span typeof="v:Breadcrumb"><a href="'.$site.'" rel="v:url" property="v:title">'.$home.'</a>'.$sep.'</span>'; 
//Count all not empty breadcrumbs
$nm     =   count($crumbs);
$i      =   1;
//Loop the crumbs
foreach($crumbs as $crumb){
    //Make the link look nice
    $link    =  ucfirst( str_replace( array(".php","-","_"), array(""," "," ") ,$crumb) );
    //Loose the last seperator
    $sep     =  $i==$nm?'':$sep;
    //Add crumbs to the root
    $site   .=  '/'.$crumb;
    //Make the next crumb
    $bc     .=  '<span typeof="v:Breadcrumb"><a href="'.$site.'" rel="v:url" property="v:title">'.$link.'</a>'.$sep.'</span>';
    $i++;
}
$bc .=  '</div>';
//Return the result
return $bc;}

回答by Ramblin

I started with the code from Dominic Barnes, incorporated the feedback from cWoDeR and I still had problems with the breadcrumbs at the third level when I used a sub-directory. So I rewrote it and have included the code below.

我从 Dominic Barnes 的代码开始,结合了 cWoDeR 的反馈,当我使用子目录时,第三级的面包屑仍然有问题。所以我重写了它并包含了下面的代码。

Note that I have set up my web site structure such that pages to be subordinate to (linked from) a page at the root level are set up as follows:

请注意,我已经设置了我的网站结构,以便从属于(链接自)根级别的页面的页面设置如下:

  • Create a folder with the EXACT same name as the file (including capitalization), minus the suffix, as a folder at the root level

  • place all subordinate files/pages into this folder

  • 创建一个与文件名完全相同(包括大写)的文件夹,减去后缀,作为根级别的文件夹

  • 将所有从属文件/页面放入此文件夹

(eg, if want sobordinate pages for Customers.php:

(例如,如果想要 Customer.php 的高级页面:

  • create a folder called Customers at the same level as Customers.php

  • add an index.php file into the Customers folder which redirects to the calling page for the folder (see below for code)

  • 在与Customers.php 相同的级别创建一个名为Customers 的文件夹

  • 将 index.php 文件添加到 Customers 文件夹中,该文件重定向到该文件夹​​的调用页面(代码见下文)

This structure will work for multiple levels of subfolders.

此结构适用于多个级别的子文件夹。

Just make sure you follow the file structure described above AND insert an index.php file with the code shown in each subfolder.

只需确保您遵循上述文件结构并插入一个 index.php 文件,其中包含每个子文件夹中显示的代码。

The code in the index.php page in each subfolder looks like:

每个子文件夹中 index.php 页面中的代码如下所示:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Redirected</title>
</head>
<body>
<?php 
$root_dir = "web_root/" ;
$last_dir=array_slice(array_filter(explode('/',$_SERVER['PHP_SELF'])),-2,1,false) ;
$path_to_redirect = "/".$root_dir.$last_dir[0].".php" ; 
header('Location: '.$path_to_redirect) ; 
?>
</body>
</html>

If you use the root directory of the server as your web root (ie /var/www/html) then set $root_dir="": (do NOT leave the trailing "/" in). If you use a subdirectory for your web site (ie /var/www/html/web_root then set $root_dir = "web_root/"; (replace web_root with the actual name of your web directory)(make sure to include the trailing /)

如果您使用服务器的根目录作为您的网络根目录(即 /var/www/html),则设置 $root_dir="":(不要留下尾随的“/”)。如果您为您的网站使用一个子目录(即 /var/www/html/web_root 然后设置 $root_dir = "web_root/"; (用您的网络目录的实际名称替换 web_root)(确保包括尾随 /)

at any rate, here is my (derivative) code:

无论如何,这是我的(衍生)代码:

<?php

// Big Thank You to the folks on StackOverflow
// See http://stackoverflow.com/questions/2594211/php-simple-dynamic-breadcrumb
// Edited to enable using subdirectories to /var/www/html as root
// eg, using /var/www/html/<this folder> as the root directory for this web site
// To enable this, enter the name of the subdirectory being used as web root
// in the $directory2 variable below
// Make sure to include the trailing "/" at the end of the directory name
// eg use      $directory2="this_folder/" ;
// do NOT use  $directory2="this_folder" ;
// If you actually ARE using /var/www/html as the root directory,
// just set $directory2 = "" (blank)
// with NO trailing "/"

// This function will take $_SERVER['REQUEST_URI'] and build a breadcrumb based on the user's current path
function breadcrumbs($separator = ' &raquo; ' , $home = 'Home') 
{

    // This sets the subdirectory as web_root (If you want to use a subdirectory)
    // If you do not use a web_root subdirectory, set $directory2=""; (NO trailing /)
    $directory2 = "web_root/" ;

    // This gets the REQUEST_URI (/path/to/file.php), splits the string (using '/') into an array, and then filters out any empty values
    $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ;
    $path_array = array_filter(explode('/',$path)) ;

    // This line of code accommodates using a subfolder (/var/www/html/<this folder>) as root
    // This removes the first item in the array path so it doesn't repeat
    if ($directory2 != "")
    {
    array_shift($path_array) ;
    }

    // This will build our "base URL" ... Also accounts for HTTPS :)
    $base = ($_SERVER['HTTPS'] ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . '/'. $directory2 ;

    // Initialize a temporary array with our breadcrumbs. (starting with our home page, which I'm assuming will be the base URL)
    $breadcrumbs = Array("<a href=\"$base\">$home</a>") ;

    // Get the index for the last value in our path array
    $last = end($path_array) ;

    // Initialize the counter
    $crumb_counter = 2 ;

    // Build the rest of the breadcrumbs
    foreach ($path_array as $crumb) 
    {
        // Our "title" is the text that will be displayed representing the filename without the .suffix
        // If there is no "." in the crumb, it is a directory
        if (strpos($crumb,".") == false)
        {
            $title = $crumb ;
        }
        else
        {
            $title = substr($crumb,0,strpos($crumb,".")) ;
        }

        // If we are not on the last index, then create a hyperlink
        if ($crumb != $last)
        {
            $calling_page_array = array_slice(array_values(array_filter(explode('/',$path))),0,$crumb_counter,false) ;
            $calling_page_path = "/".implode('/',$calling_page_array).".php" ;
            $breadcrumbs[] = "<a href=".$calling_page_path.">".$title."</a>" ;
        }

        // Otherwise, just display the title
        else
        {
            $breadcrumbs[] = $title ;
        }

        $crumb_counter = $crumb_counter + 1 ;

    }
    // Build our temporary array (pieces of bread) into one big string :)
    return implode($separator, $breadcrumbs) ;
}

// <p><?= breadcrumbs() ? ></p>
// <p><?= breadcrumbs(' > ') ? ></p>
// <p><?= breadcrumbs(' ^^ ', 'Index') ? ></p>
?>

回答by knittl

use parse_urland then output the result in a loop:

使用parse_url然后在循环中输出结果:

$urlinfo = parse_url($the_url);
echo makelink($urlinfo['hostname']);
foreach($breadcrumb in $urlinfo['path']) {
  echo makelink($breadcrumb);
}

function makelink($str) {
  return '<a href="'.urlencode($str).'" title="'.htmlspecialchars($str).'">'.htmlspecialchars($str).'</a>';
}

(pseudocode)

(伪代码)

回答by briankip

hey dominic your answer was nice but if your have a site like http://localhost/project/index.phpthe 'project' link gets repeated since it's part of $base and also appears in the $path array. So I tweaked and removed the first item in the $path array.

嘿多米尼克,你的回答很好,但如果你有一个像http://localhost/project/index.php这样的网站,“项目”链接会重复,因为它是 $base 的一部分,也出现在 $path 数组中。所以我调整并删除了 $path 数组中的第一项。

//Trying to remove the first item in the array path so it doesn't repeat
array_shift($path);

I dont know if that is the most elegant way, but it now works for me.

我不知道这是否是最优雅的方式,但它现在对我有用。

I add that code before this one on line 13 or something

我在第 13 行之类的代码之前添加了该代码

// Find out the index for the last value in our path array
$last = end(array_keys($path));

回答by BenDZN

Here is a great simple dynamic breadcrumb (tweak as needed):

这是一个非常简单的动态面包屑(根据需要进行调整):

    <?php 
    $docroot = "/zen/index5.php";
    $path =($_SERVER['REQUEST_URI']);
    $names = explode("/", $path); 
    $trimnames = array_slice($names, 1, -1);
    $length = count($trimnames)-1;
    $fixme = array(".php","-","myname");
    $fixes = array(""," ","My<strong>Name</strong>");
    echo '<div id="breadwrap"><ol id="breadcrumb">';
    $url = "";
    for ($i = 0; $i <= $length;$i++){
    $url .= $trimnames[$i]."/";
        if($i>0 && $i!=$length){
            echo '<li><a href="/'.$url.'">'.ucfirst(str_replace($fixme,$fixes,$trimnames[$i]) . ' ').'</a></li>';
    }
    elseif ($i == $length){
        echo '<li class="current">'.ucfirst(str_replace($fixme,$fixes,$trimnames[$i]) . ' ').'</li>';       
    }
    else{
        echo $trimnames[$i]='<li><a href='.$docroot.' id="bread-home"><span>&nbsp;</span></a></li>';
    }
}
echo '</ol>';
?>

回答by Krishna Manoj Varanasi

A better one using explode()function is as follows...

一个更好的使用explode()函数如下......

Don't forget to replace your URL variable in the hyperlink href.

不要忘记替换超链接中的 URL 变量href

<?php 
    if($url != ''){
        $b = '';
        $links = explode('/',rtrim($url,'/'));
        foreach($links as $l){
            $b .= $l;
            if($url == $b){
                echo $l;
            }else{
                echo "<a href='URL?url=".$b."'>".$l."/</a>";
            }
            $b .= '/';
         }
     }
?>

回答by Brick

Here is my solution based on Skeptic answer. It gets page title from WordPress DB, not from URL because there is a problem with latin characters (slug doesn't has a latin characters). You can also choose to display "home" item or not.

这是我基于怀疑论者回答的解决方案。它从 WordPress DB 获取页面标题,而不是从 URL 获取页面标题,因为拉丁字符存在问题(slug 没有拉丁字符)。您还可以选择是否显示“主页”项目。

/**
 * Show Breadcrumbs
 * 
 * @param string|bool $home
 * @param string $class
 * @return string
 * 
 * Using: echo breadcrumbs();
 */
function breadcrumbs($home = 'Home', $class = 'items') {
    $breadcrumb  = '<ul class="'. $class .'">';
    $breadcrumbs = array_filter(explode('/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)));

    if ($home) {
        $breadcrumb .= '<li><a href="' . get_site_url() . '">' . $home . '</a></li>';
    }

    $path = '';
    foreach ($breadcrumbs as $crumb) {
        $path .=  $crumb . '/';
        $page = get_page_by_path($path);

        if ($home && ($page->ID == get_option('page_on_front'))) {
            continue;
        }

        $breadcrumb .= '<li><a href="'. get_permalink($page) .'">' . $page->post_title . '</a></li>';
    }

    $breadcrumb .= '</ul>';
    return $breadcrumb;
}

Using:

使用:

<div class="breadcrumb">
    <div class="container">
        <h3 class="breadcrumb__title">Jazda na maxa!</h3>
        <?php echo breadcrumbs('Start', 'breadcrumb__items'); ?>
    </div>
</div>

回答by Codeparl

function  makeBreadCrumbs($separator = '/'){
        //extract uri path parts into an array
        $breadcrumbs =  array_filter(explode('/',parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)));

        //determine the base url or domain 
        $base = (isset($_SERVER['HTTPS'])  ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . '/';

        $last  =  end($breadcrumbs); //obtain the last piece of the path parts
        $crumbs['Home'] = $base; //Our first crumb is the base url 
        $current =  $crumbs['Home']; //set the current breadcrumb to base url

    //create valid urls from the breadcrumbs and store them in an array
    foreach ($breadcrumbs as $key => $piece) {

    //ignore file names and create urls from  directory path
    if( strstr($last,'.php') == false){
        $current   =  $current.$separator.$piece;
        $crumbs[$piece] =$current;

    }else{

        if($piece !== $last){
            $current   =  $current.$separator.$piece;
            $crumbs[$piece] =$current;
        }
    }

    }


    $links = '';
    $count = 0;

//create html tags for displaying the breadcrumbs
foreach ($crumbs as $key => $value) :
    $x = array_filter(explode('/',parse_url($value, PHP_URL_PATH)));
    $last =  end($x);
    //this will add a class to the last link to control its appearance
    $clas = ($count === count($crumbs) -1 ? ' current-crumb' : '' );

    //determine where to print separators 
    $sep = ( $count > -1 && $count < count($crumbs) -1 ? '&raquo;' :'');

    $links .= "<a class=\"$clas\" href=\"$value\">$key</a> $sep";
    $count++;

endforeach;

return $links; 

}

}