PHP框架URL约定

PHP框架URL约定,php,url-routing,conventions,Php,Url Routing,Conventions,很多框架都使用URL约定,比如/controller/action/{id},这很好,但是如果您需要除此之外的任何配置,则由您自己编写路由 如何在后端处理像/users/{id}/friends这样的URL?(列出用户的所有好友) 我认为在控制器中,类似这样的东西是合适的: class User { function index() { echo 'user index'; } } class Friend extends User { function

很多框架都使用URL约定,比如
/controller/action/{id}
,这很好,但是如果您需要除此之外的任何配置,则由您自己编写路由

如何在后端处理像
/users/{id}/friends
这样的URL?(列出用户的所有好友)

我认为在控制器中,类似这样的东西是合适的:

class User {
    function index() {
        echo 'user index';
    }
}

class Friend extends User {
    function index($user_id) {
        echo 'friend index';
    }    
}
那么您将拥有以下地图:

/users              -> User::index()
/users/{id}         -> User::view($id)
/users/{id}/friends -> Friend::index($user_id)
我想把Friend类放在User类中,但显然你不能在PHP中这样做,所以这是我能想到的最好的方法。想法

什么URL将用于编辑您的好友列表
/users/{id}/friends/edit
可以工作,但它似乎不合适,因为您不应该编辑其他人的朋友列表。
/account/friends/edit
会是更好的选择吗?你会把相应的代码放在哪里?在朋友控制器、用户控制器或专用帐户控制器中

奖金问题:你更喜欢哪一个
/photos/delete/{id}
/photos/{id}/delete


答案:

所以,我从答案中收集到的是,如果“东西”很复杂(比如“朋友”),但没有自己的控制器,你可以给它一个没有模型的控制器,或者如果它没有,你应该用它最密切相关的东西来填充它。URL不应影响代码的放置位置。大多数人似乎认为只要可能,你就应该坚持使用
/controller/action/{id}
,因为这是人们所熟悉的

除了说它“笨拙”之外,没有人真正评论这个扩展类。如果我真的想把FriendList分开,那么在这种情况下,FriendList可能是一个更合适的类


感谢所有的答案:)

您所谈论的路线,以及您使用子类实现此结构的方式,对我来说似乎有点尴尬。
/controller/action/{id}
的标准约定非常适用于简单的操作,但是如果要创建复杂的应用程序,则始终需要创建自定义路由。在创建这些路由时,可能有一些很好的指导原则可供使用,但它实际上可以归结为在整个应用程序中保持一致,并使事情尽可能简单

我看不出有什么好的理由将
/user/{id}/friends
映射到“
friends
”控制器。为什么不让“
friends
”成为
用户
控制器上的一个操作?一旦你真正深入查看某个特定朋友的页面,你可以使用
朋友
控制器(
/friends/view/123
),或者你可以重新调整
用户
控制器的用途,以便它为朋友或当前登录的用户工作(
/User/view/123


回复:关于奖金问题,我坚持认为
/photos/delete/{id}
/controller/action/{id}
)是最广泛接受的机制。

我更喜欢
/photos/{id}/delete
。我的理由是,如果你从URL的末尾去掉一个组件,它仍然是有意义的

很容易假设
/photos/{id}
应该做什么:查看该
{id}
的照片集

但是
/photos/delete
应该做什么呢?这真的不清楚

我知道有一种默认约定是
/controller/action/id
,但这种组织是为了映射到控制器的类/方法体系结构。我认为组织UI以容纳代码(URL在某种程度上是UI的一部分)不是一个好主意


重新评论:是的,
/photos/{id}
通过id查看给定照片可能更有意义。
/users/{id}/photos
可能查看收藏。这取决于你


关键是您应该从用户的角度来考虑UI,而不是从代码组织的角度来考虑。

这还取决于您如何存储数据。我可以想象,在某些情况下,您需要一个“朋友列表”作为模型中的一个实体。逻辑方法是为每个好友列表指定一个唯一标识符,即主键

这在逻辑上会导致以下路由,因为您只需要朋友列表的主键就可以编辑或删除它

/friends/edit/{friendListId}

由你来决定。正如pix0r所述:小型应用程序的约定是
/{controller}/{action}/{id}
,其中{id}应该是可选的,以匹配大多数网站操作。在某些情况下,应用程序变得越来越大,您需要定义包含3个以上元素的特定路由。在某些情况下,某些实体只是获得了更大的意义(上面的示例),您可以决定为其定义自定义控制器(这使默认路由再次完美…)


我会坚持默认路线
/controller/action/id
,但不要一开始就为所有东西(比如朋友)制作控制器。“模型-视图-控制器”模式使您以后更改路线变得非常容易,只要所有路线链接和动作(表单等)都是基于路线和动作生成的。所以你真的不需要那么麻烦:)

你可以做或。问题是当你把两者混合在一起时/users/{id}/friends和/users/friends/{id}当某人的id为“friends”时,此操作将失败。这似乎是一个微不足道的例子,但在ID中使用用户名是非常流行的。您必须限制每个操作的用户名


有时您不能执行
/{controller}/{action}/{id}

不久前我做了一个独立音乐网站,我们做了

/artist/{username}
/artist/{username}/albums
/artist/{username}/albums/{album}
我们不想测试条件句,所以我们没有这样做

/artist/{username}/{album}
因为我们不想查看任何人的专辑名为“albums”

我们本来可以做到的

/artist/{username}
/artist/{username}/albums
/albums/{album}
但这样我们就失去了搜索引擎优化的优势
/artist/view/{username}
/artist/albums/{username}
/album/view/{album}
class Users {

    public function index() {
        $users = $this->findUsers();
    }

    protected function findUsers($userId=null) { ... }
}

class Friends extends Users {

    public function index($userId) {
        $users = $this->findUsers($userId);
    }
}