如何在php中创建友好的URL?


70

通常,显示某些个人资料页面的做法或非常古老的方法是这样的:

www.domain.com/profile.php?u=12345

u=12345用户ID在哪里。

近年来,我发现一些网站的网址非常好,例如:

www.domain.com/profile/12345

如何在PHP中做到这一点?

就像一个疯狂的猜测一样,这与.htaccess文件有关吗?您能给我更多关于如何编写.htaccess文件的提示或一些示例代码吗?

Answers:


51

根据本文的介绍,您需要一个.htaccess看起来像这样的mod_rewrite(放置在文件中)规则:

RewriteEngine on
RewriteRule ^/news/([0-9]+)\.html /news.php?news_id=$1

这映射了来自

/news.php?news_id=63

/news/63.html

另一种可能性是使用forcetype,它会迫使任何东西沿特定路径使用php评估内容。因此,在您的.htaccess文件中放入以下内容:

<Files news>
    ForceType application/x-httpd-php
</Files>

然后index.php可以根据$_SERVER['PATH_INFO']变量采取行动:

<?php
    echo $_SERVER['PATH_INFO'];
    // outputs '/63.html'
?>


2
如果要完全用PHP重写URL,另一种选择是设置重写规则以将所有请求定向到单个脚本。这样做的一大优势是,您可以将代码存储在Apache不可访问的区域中,并且仅URL分配脚本需要可访问Apache。例如:RewriteCond%{REQUEST_FILENAME}!-f RewriteCond%{REQUEST_FILENAME}!-d RewriteRule。dispatch.php这与您的forcetype示例相似。
Frank Farmer

2
有关Phpriot的文章已被删除,请在此处阅读。非常好。
Jasom Dotnet

如果id = 1,并且post_name =“ red post”,那么就有可能创建网址,例如example.com/red-post.php。目前,我正在创建网址,例如example.com/post/?id=1。即如何通过职位名称制作(url)
abilash er

James Socol和发布的链接Chad Birch已断开。
SebasSBM

31

我最近在满足我的需求的应用程序中使用了以下内容。

.htaccess

<IfModule mod_rewrite.c>
# enable rewrite engine
RewriteEngine On

# if requested url does not exist pass it as path info to index.php
RewriteRule ^$ index.php?/ [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?/$1 [QSA,L]
</IfModule>

index.php

foreach (explode ("/", $_SERVER['REQUEST_URI']) as $part)
{
    // Figure out what you want to do with the URL parts.
}

15

我尝试在以下示例中逐步解释此问题。

0)问题

我试着这样问你:

我想打开类似Facebook个人资料的页面www.facebook.com/kaila.piyush

它从url获取ID并将其解析为profile.php文件,并从数据库返回featch数据,并向用户显示其个人资料

通常,当我们开发任何网站时,其链接看起来就像www.website.com/profile.php?id=username example.com/weblog/index.php?y=2000&m=11&d=23&id=5678

现在我们以新样式更新,而不重写,我们使用www.website.com/username或example.com/weblog/2000/11/23/5678作为永久链接

http://example.com/profile/userid (get a profile by the ID) 
http://example.com/profile/username (get a profile by the username) 
http://example.com/myprofile (get the profile of the currently logged-in user)

1).htaccess文件

在根文件夹中创建.htaccess文件,或更新现有文件:

Options +FollowSymLinks
# Turn on the RewriteEngine
RewriteEngine On
#  Rules
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php

那是做什么的?

如果请求是针对真实目录或文件(服务器上存在的目录),则不会提供index.php,否则每个URL都将重定向到index.php。

2)index.php

现在,我们想知道要触发什么动作,因此我们需要阅读URL:

在index.php中:

// index.php    

// This is necessary when index.php is not in the root folder, but in some subfolder...
// We compare $requestURL and $scriptName to remove the inappropriate values
$requestURI = explode(‘/’, $_SERVER[‘REQUEST_URI’]);
$scriptName = explode(‘/’,$_SERVER[‘SCRIPT_NAME’]);

for ($i= 0; $i < sizeof($scriptName); $i++)
{
    if ($requestURI[$i] == $scriptName[$i])
    {
        unset($requestURI[$i]);
    }
}

$command = array_values($requestURI);
With the url http://example.com/profile/19837, $command would contain :

$command = array(
    [0] => 'profile',
    [1] => 19837,
    [2] => ,
)
Now, we have to dispatch the URLs. We add this in the index.php :

// index.php

require_once("profile.php"); // We need this file
switch($command[0])
{
    case ‘profile’ :
        // We run the profile function from the profile.php file.
        profile($command([1]);
        break;
    case ‘myprofile’ :
        // We run the myProfile function from the profile.php file.
        myProfile();
        break;
    default:
        // Wrong page ! You could also redirect to your custom 404 page.
        echo "404 Error : wrong page.";
        break;
}

2)profile.php

现在,在profile.php文件中,我们应该具有以下内容:

// profile.php

function profile($chars)
{
    // We check if $chars is an Integer (ie. an ID) or a String (ie. a potential username)

    if (is_int($chars)) {
        $id = $chars;
        // Do the SQL to get the $user from his ID
        // ........
    } else {
        $username = mysqli_real_escape_string($char);
        // Do the SQL to get the $user from his username
        // ...........
    }

    // Render your view with the $user variable
    // .........
}

function myProfile()
{
    // Get the currently logged-in user ID from the session :
    $id = ....

    // Run the above function :
    profile($id);
}

感谢您提供详细的帖子,我一直想学习,像wordpress这样的网站如何生成漂亮的url,并且可以每次访问它们而无需编辑htaccess文件,谢谢

这就是我想要的。
亚历杭德罗·坎帕

您如何处理#anchors?
JG Estiot '20年


4

它实际上不是PHP,而是使用mod_rewrite的apache。发生这种情况的是该人请求链接www.example.com/profile/12345,然后Apache使用重写规则将其切碎,使其看起来像www.example.com/profile.php?u=12345,指向服务器。您可以在此处找到更多信息:重写指南


-1

ModRewrite不是唯一的答案。您还可以在.htaccess中使用Options + MultiViews,然后检查$_SERVER REQUEST_URI以查找URL中的所有内容。


是的,但是MultiViews很讨厌...我想说这种用法太笼统了。
David Z

-1

有很多不同的方法可以做到这一点。一种方法是使用前面提到的RewriteRule技术来屏蔽查询字符串值。

我真正喜欢的方法之一是,如果您使用前端控制器模式,则还可以使用http://yoursite.com/index.php/path/to/your/page/here这样的网址并解析$ _SERVER的值['REQUEST_URI']。

您可以使用以下代码轻松提取/ path / to / your / page / here位:

$route = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME']));

从那里,您可以随意解析它,但是为了皮特的缘故,请确保对它进行消毒;)


-2

看来您在谈论RESTful网络服务。

http://en.wikipedia.org/wiki/Representational_State_Transfer

.htaccess文件确实重写了所有URI,以指向一个控制器,但这要比这时要详细的多。您可能想看看凹进处

这是一个全部使用PHP的RESTful框架


2
从技术上讲,我认为您是对的,但是除非OP已经对REST想法有经验,否则即使阅读Wikipedia文章也要比问题需要付出更多的努力。在这种情况下,调用整个编程范例是过大的。
David Z

1
真?我认为他的问题不完全是“我如何制作profile.php?u = 12345 goto / profile / 12345”,我认为这是一个整体的“在生产环境中如何完成?”。我认为知道存在一个范例,并且在有适当的方法解决该问题时没有一个充满重定向的.htaccess文件是有益的。
ryanday
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.