как получить динамический URL-адрес, например mydomain.com/username, используя zend framework

Я разрабатываю приложение с использованием zend framework. В приложении я должен указать URL-адрес для каждого пользователя, например mydomain.com/[username], тогда публика сможет просмотреть его профиль. [имя пользователя] – это имя пользователя конкретного пользователя

Но как я могу это достичь? Я думаю, что в ZF mydomain.com/username пытается получить контроллер с именем пользователя , но я должен показать профили пользователей в этом URL-адресе, и он должен перейти к правильному контроллеру, если что-то еще похоже на mydomain.com/controller1

Это, похоже, довольно много, есть несколько вариантов:

Вариант 1: пользовательский класс маршрута

Я разместил сообщение в блоге с подробным примером того, как добиться этого в ZF, используя собственный класс маршрутов, см.

http://tfountain.co.uk/blog/2010/9/9/vanity-urls-zend-framework

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

Вариант 2: расширение маршрутизатора

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

class My_Router extends Zend_Controller_Router_Rewrite { public function route(Zend_Controller_Request_Abstract $request) { $pathBits = explode('/', $request->getPathInfo()); if (!empty($pathBits[0])) { // check whether $pathBits[0] is a username here // with a database lookup, if yes, set params and return } // fallback on the standard ZF router return parent::route($request); } } 

Затем вам нужно сказать фронт-контроллеру, чтобы использовать ваш маршрутизатор вместо стандартного, поэтому в вашем бутстрапе:

 protected function _initRoutes() { Zend_Controller_Front::getInstance()->setRouter(new My_Router()); } 

замените «Мой» на собственное пространство имен вашего приложения.

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

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

 public function _initRouter() { $router = Zend_Controller_Front::getinstance()->getRouter(); $users = array() // get the usernames from DB or wherever you have them // Adds some routes foreach($users as $user) { $router->addRoute($user['name'], new Zend_Controller_Router_Route($user['name'].'/:controller/:action/*', array( 'module' => 'users', // module name 'controller' => 'index', // controller name 'action' => 'profile', // action name 'username' => $user['name']))); // user name } return $router; } } 

Мне кажется, что здесь сложность заключается в том, что вы используете одну и ту же схему URL:

http:/example.com/something

для представления двух типов действий:

  1. Если «что-то» представляет собой имя пользователя, рассмотрите этот запрос для контроллера = user, action = viewProfile, param = something.
  2. В противном случае рассмотрите это как стандартный запрос к контроллеру SomethingController

Мне это кажется немного странным. Я бы предпочел поставить пользовательские запросы под другой схемой URL, например:

http://example.com/user/bob

где могут применяться стандартные правила маршрутизации. Хотите избежать риска, что пользователь регистрируется с именем, которое конфликтует с одним из ваших статических контроллеров. Конечно, вы могли бы поддерживать пул «зарезервированных» имен пользователей для ваших статических контроллеров, которые были бы недоступны для пользователей.

Но если на самом деле является требованием, чтобы один и тот же формат url использовался для обоих типов запросов, я бы сделал следующее: directTrafficAction() все запросы на что-то вроде TrafficCopController с действием directTrafficAction() . Действие может протестировать – возможно, через db query – если переданный «что-то» параметр представляет реального пользователя. Если это так, controller=user, action=viewProfile запрос на controller=user, action=viewProfile . В противном случае переслать запрос controller=something, action=index .

Смотрите, что я имею в виду?

Создайте настраиваемый маршрут (не Router, нет необходимости создавать настраиваемый маршрутизатор!).

Ваш новый маршрут должен расширять Zend_Controller_Router_Route_Abstract и переопределять метод match , который принимает Zend_Controller_Request_Abstract $request в качестве первого параметра.

В вашем новом методе сопоставления просто запросите свою базу данных, чтобы узнать, существует ли пользовательская страница, пользователь и т. Д., Сравнивая с $request->getRequestUri() , и если это так, верните соответствующую информацию о маршрутизации. Пример:

 return array( 'module' => 'default', 'controller' => 'users', 'action' => 'view', 'user' => $user ); 

При сбое (не удается найти нужного пользователя или страницу и т. Д.), Тогда:

 return false 

Это будет намного лучше, чем создание маршрута для каждого отдельного пользователя, и не требует, чтобы вы слишком много путались с маршрутизацией. Он по-прежнему будет работать со стандартным маршрутизатором, и вы можете добавить его на свои маршруты через application.ini, как и ожидалось.

Попробуйте использовать Apache .htaccess mod_rewrite.

4) Переписывание yoursite.com/user.php?username=xyz на yoursite.com/xyz

Вы проверили zorpia.com. Если вы наберете hxxp: //zorpia.com/roshanbh233 в браузере, вы можете увидеть мой профиль там. Если вы хотите сделать такое же перенаправление, т.е.

hxxp: //yoursite.com/xyz to hxxp: //yoursite.com/user.php? username = xyz, то вы можете добавить следующий код в файл .htaccess.

 RewriteEngine On RewriteRule ^([a-zA-Z0-9_-]+)$ user.php?username=$1 RewriteRule ^([a-zA-Z0-9_-]+)/$ user.php?username=$1 

источник: http://roshanbh.com.np/2008/03/url-rewriting-examples-htaccess.html

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

Альтернативой является добавление общего маршрута, который по умолчанию сопоставляется с действием пользователя (это определяется сначала, когда маршруты сопоставляются в обратном порядке). Затем добавьте маршруты к контроллерам, которые у вас есть на самом деле – у вас, скорее всего, будет гораздо меньше контроллеров, чем у пользователей.

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