题
许多框架都使用URL约定,例如 / controller / action / {id}
,这很好,但是如果你需要任何配置,那么由你来编写自己的路由。 / p>
如何在后端处理 / users / {id} / friends
等网址? (列出所有用户的朋友)
我认为在控制器中,这样的事情是合适的:
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
答案:
所以,我从答案中得到的是,如果“事物”是是复杂的(比如“朋友”),但是没有自己的控制器,你可以在没有模型的情况下给它一个,或者如果不是,你应该用它最密切相关的东西填充它。您的网址不应影响您放置代码的位置。大多数人似乎认为你应该尽可能坚持 / controller / action / {id}
,因为这是人们所熟悉的。
除了说“尴尬”之外,没有人真正对扩展类发表评论。如果我真的想将它分开,那么FriendList可能是一个更合适的类。
感谢所有答案:)
解决方案
您正在谈论的路线以及您使用子类实现此结构的方式对我来说似乎有点尴尬。 / controller / action / {id}
的标准约定适用于简单的操作,但如果您要创建复杂的应用程序,则始终需要创建自定义路由。创建这些路线时可能会有一些很好的指导原则,但它实际上归结为在整个应用程序中保持一致并尽可能简化。
我认为没有任何理由让 / user / {id} / friends
映射到“ Friend
”控制器。为什么不只是拥有“ friends
”是 User
控制器上的操作?一旦您真正深入查看特定朋友的页面,您可以使用 Friend
控制器( / friends / view / 123
),或者您可以重新调整您的 User
controller,以便它适用于朋友或当前登录的用户( / user / view / 123
)。
Re:红利问题,我坚持使用 / 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
也许是为了查看集合。由你决定。
重点是你应该根据用户而不是代码组织来考虑用户界面。
你可以做任何一个或。问题是你混合两者。 / users / {id} / friends和/ users / friends / {id}当某人的ID为“朋友”时这会失败。这似乎是一个微不足道的案例,但使用用户名进行ID非常流行。您必须限制每个操作的用户名。
有时你不能做 / {controller} / {action} / {id}
我不久前做了一个独立音乐网站,我们做了
/artist/{username}
/artist/{username}/albums
/artist/{username}/albums/{album}
我们不想测试条件,所以我们没有做
/artist/{username}/{album}
因为我们不想检查任何名为“专辑”的专辑
我们本可以做到的
/artist/{username}
/artist/{username}/albums
/albums/{album}
但是我们将失去在网址中同时拥有艺术家姓名和专辑名称的SEO优势。同样在这种情况下,我们会强制专辑名称是独一无二的,因为艺术家的专辑名称与其他艺术家相同是很常见的。
你可以做纯 / {controller} / {action} / {id}
,但是你会失去一些搜索引擎优化,你不能做网址缩短。
/artist/view/{username}
/artist/albums/{username}
/album/view/{album}
回到你的例子。
/ users / {id} / friends / edit可以正常工作, 但这似乎不合适 你永远不应该编辑某人 别的朋友名单。
在这种情况下,它应该是 / friends / edit
,因为您的用户ID是重复信息,假设您在会话中以某种方式。通常,您希望支持URL缩短而不支持URL扩展。
(奖金问题)
我也不会使用 REST 。 DELETE / photo?id = {id}
这还取决于您存储数据的方式。我可以想象在某些情况下你需要一个'朋友列表'作为你模型中的一个实体。然后,逻辑方法是为每个朋友列表(主键)指定唯一标识符。
这在逻辑上会导致以下路由,因为您只需要友元列表的主键来编辑或删除它...
<代码> /朋友/编辑/ {friendListId} 代码>
由你来决定。正如pix0r所述:小型应用程序的约定是 / {controller} / {action} / {id}
,其中{id}应该是可选的,以匹配您的大多数网站操作。在某些情况下,应用程序变大,您希望定义具有3个以上元素的特定路径。在某些情况下,某些实体只是获得更大的意义(上面的例子),你可以决定为它定义一个自定义控制器(这使得默认路线再次完美......)。
我坚持使用默认路由 / controller / action / id
,但不要在开始时为所有内容(如朋友)开始制作控制器。模型 - 视图 - 控制器模式使您可以轻松地稍后更改路径,只要所有路径链接和操作(表单等)都是基于路由和操作生成的。所以你真的不必费心那么多:)
网址本身并不重要。更重要的是每个控制器的内容。在您的示例中,您的好友列表扩展了 User
类。如果你的朋友列表实际上只是一个用户列表,也许它应该扩展 Users
控制器,以便你在一个地方处理用户列表。
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);
}
}
如果您很难确定要扩展哪个类,请从每个类中写出您需要的内容并选择具有最长列表的类。