Вопрос

Многие фреймворки используют соглашения об URL, такие как / controller / action / {id} , что замечательно, но если вам нужна какая-либо конфигурация помимо этого, вы сами можете написать свои собственные маршруты.

Как бы вы обрабатывали URL-адреса, такие как / 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

<Ч>

Ответы:

Итак, что я понял из ответов, так это то, что если "вещь" это сложно (например, «друзья»), но не имеет своего собственного контроллера, вы можете дать ему один без модели, или, если это не так, вы должны добавить его в то, с чем он наиболее тесно связан. Ваши URL не должны влиять на то, где вы размещаете свой код. Большинство людей, кажется, думают, что вам следует придерживаться / controller / action / {id} там, где это возможно, потому что это то, с чем люди знакомы.

Никто на самом деле не прокомментировал расширенный класс, за исключением того, что он "неуклюжий". Возможно, FriendList был бы более подходящим классом в этом случае, если бы я действительно хотел выделить его.

Спасибо за все ответы :)

Это было полезно?

Решение

Маршруты, о которых вы говорите, и то, как вы используете подклассы для достижения этой структуры, мне немного неловко. Стандартное соглашение / controller / action / {id} отлично подходит для простых действий, но если вы создаете сложное приложение, вам всегда нужно будет создавать собственные маршруты. Вероятно, есть несколько хороших рекомендаций, которые следует использовать при создании этих маршрутов, но на самом деле все сводится к тому, чтобы оставаться согласованным во всем приложении и максимально упростить его.

Я не вижу веских причин для того, чтобы / user / {id} / friends сопоставлялся с " Friend " контроллер. Почему бы просто не иметь " друзей " быть действием на контроллере Пользователь ? После того, как вы действительно перейдете к просмотру страницы конкретного друга, вы можете использовать контроллер Friend ( / friends / view / 123 ) или переназначить своего пользователя < Контроллер / code>, чтобы он работал для друга или текущего пользователя ( / user / view / 123 ).

Re: бонусный вопрос, я бы добавил / photos / delete / {id} ( / controller / action / {id} ), так как это наиболее общепринятый механизм.

Другие советы

Я бы предпочел / photos / {id} / delete . Я рассуждаю так: если вы убираете один компонент с конца URL, это все равно имеет смысл.

Довольно легко предположить, что должен делать / photos / {id} : просмотреть набор фотографий для этого {id} .

Но что делать / photos / delete ? Это действительно неясно.

Я знаю, что по умолчанию существует соглашение / controller / action / id , но эта организация предназначена для отображения в архитектуру контроллеров класса / метода. Я не думаю, что это хорошая идея, чтобы организовать пользовательский интерфейс для размещения кода (URL является частью пользовательского интерфейса).

<Ч>

Комментарии: Да, / photos / {id} , возможно, имеет больше смысла просматривать данную фотографию по ее идентификатору. / users / {id} / photos возможно для просмотра коллекции. Тебе решать.

Дело в том, что вы должны думать о пользовательском интерфейсе с точки зрения пользователей, а не с точки зрения организации кода.

Вы можете сделать либо или. Проблема в том, когда вы смешиваете два. / users / {id} / friends и / users / friends / {id} Когда у кого-то есть идентификатор " friends " это не удастся. Это может показаться тривиальным случаем, но очень популярно использовать имена пользователей для идентификаторов. Вам придется ограничить имена пользователей для каждого действия.

<Ч>

Иногда вы не можете выполнить / {controller} / {action} / {id}

Некоторое время назад я создал инди-музыкальный сайт, и мы сделали

/artist/{username}
/artist/{username}/albums
/artist/{username}/albums/{album}

Мы не хотели проверять условия, поэтому мы не делали

/artist/{username}/{album}

Поскольку мы не хотели проверять кого-либо с альбомом с именем " album "

Мы могли бы сделать это

/artist/{username}
/artist/{username}/albums
/albums/{album}

но тогда мы потеряем преимущество SEO, поскольку в URL-адресе были указаны имя исполнителя и название альбома Также в этом случае мы бы заставляли имена альбомов быть уникальными, что было бы плохо, так как для артиста характерно, чтобы названия альбомов были такими же, как у другого исполнителя.

Вы можете выполнить чистый / {controller} / {action} / {id} , но тогда вы потеряете часть SEO и не сможете сократить URL.

/artist/view/{username}
/artist/albums/{username}
/album/view/{album}
<Ч>

Возвращаясь к вашему примеру.

  

/ users / {id} / friends / edit может работать,   но это не кажется уместным, так как   Вы никогда не должны редактировать кого-то   список других друзей.

В этом случае это должен быть / friends / edit , поскольку ваш идентификатор пользователя является дублирующей информацией, предполагающей, что вы каким-то образом участвуете в сеансе. Как правило, вы хотите поддерживать сокращение URL, а не расширение URL.

(Бонусный вопрос) Также я бы не использовал REST . DELETE / photo? id = {id}

Это также зависит от того, как вы храните свои данные. Я мог бы представить, что в некоторых случаях вам нужен «список друзей», чтобы быть сущностью в вашей модели. Тогда логичным подходом будет указать уникальный идентификатор для каждого списка друзей, первичный ключ.

Это логически может привести к следующему маршруту, поскольку для редактирования или удаления необходим только первичный ключ списка друзей ...

<код> / друзей / редактировать / {friendListId}

Это решать вам. Как указано в pix0r: для небольших приложений существует соглашение / {controller} / {action} / {id} , где {id} должен быть необязательным, чтобы соответствовать большинству действий ваших сайтов. В некоторых случаях приложения становятся большими, и вы хотите определить конкретные маршруты с более чем 3 элементами. В некоторых случаях некоторые сущности просто получают большее значение (пример выше), и вы можете решить определить собственный контроллер для него (что делает маршрут по умолчанию снова идеальным ...).

Я бы придерживался маршрута по умолчанию / controller / action / id , но просто не начинал создавать контроллеры для всего (как друзья) в начале. Шаблон Model-View-Controller позволяет вам изменить маршруты позже , если все ваши маршрутные ссылки и действия (формы и т. Д.) Генерируются на основе маршрутов и действий. Так что вам не нужно так сильно беспокоиться:)

Сами URL не имеют большого значения. Что важнее, так это то, что входит в каждый из ваших контроллеров. В вашем примере ваш список друзей расширил класс Пользователь . Если ваш список друзей - это просто список пользователей, возможно, он должен расширить контроллер 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);
    }
}

Если вам сложно определить, какой класс нужно расширить, напишите, что вам нужно, для каждого из классов и выберите класс с самым длинным списком.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top