Собственные ссылки в yii2. Как?
Собственные ссылки в yii2. Как?
Привет всем. Возник собственно хороший и нужный вопрос, как создавать собственные ссылки в yii2?
Легче всего понять меня и то, что я хочу на примере:
Допустим регистрация пользователя у меня здесь -> test.ru/user/registration (controller/action) соответственно.
В базе есть таблица "pages", я создал CRUD для нее в бэкэнде. Теперь там же создаем запись:
id | alias | route
1 | registration | user/registration
Теперь я хочу при обращении во фронтенде на страницу "test.ru/registration" получить содержимое "test.ru/user/registration", при этом "test.ru/user/registration" уже не должен работать, т.к. есть созданный короткий алиас. Если алиаса нет, тогда без алиаса должно работать "test.ru/user/registration", ну и соответственно если не попадает не под одно правило -> 404.
Спасибо.
Легче всего понять меня и то, что я хочу на примере:
Допустим регистрация пользователя у меня здесь -> test.ru/user/registration (controller/action) соответственно.
В базе есть таблица "pages", я создал CRUD для нее в бэкэнде. Теперь там же создаем запись:
id | alias | route
1 | registration | user/registration
Теперь я хочу при обращении во фронтенде на страницу "test.ru/registration" получить содержимое "test.ru/user/registration", при этом "test.ru/user/registration" уже не должен работать, т.к. есть созданный короткий алиас. Если алиаса нет, тогда без алиаса должно работать "test.ru/user/registration", ну и соответственно если не попадает не под одно правило -> 404.
Спасибо.
Re: Собственные ссылки в yii2. Как?
в конфиге (config/web.php) url настрой
Код: Выделить всё
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
// прочие правила
'registration/' => 'user/registration', // контроллер/действие
'/' => 'site/error404'
],
],
Re: Собственные ссылки в yii2. Как?
Да я сам знаю что так можно. Вопрос был про то, что бы именно с базы эти правила тянуть. Притом если правило в базе есть, то ссылка (контроллер/действие) должна не работать. В Вашем примере ни того, ни другого.nextdrift писал(а):в конфиге (config/web.php) url настрой
Код: Выделить всё
'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ // прочие правила 'registration/' => 'user/registration', // контроллер/действие '/' => 'site/error404' ], ],
Re: Собственные ссылки в yii2. Как?
Подгружать из базы можно с использование метода addRules
а вот как сделать защиту в случае, если в БД уже есть роут, тут надо думать
Например, при динамическом добавлении роутов у вас есть 2 списка маршрутов: из БД и маршруты по-умолчанию.
Вы идете циклом по списку из БД и добавляете маршруты в urlManager. Далее после того как все данные из БД обработаны, вы выбираете все маршруты из списка по-умолчанию, которые не встретились в БД и добавляете их.
а вот как сделать защиту в случае, если в БД уже есть роут, тут надо думать
Например, при динамическом добавлении роутов у вас есть 2 списка маршрутов: из БД и маршруты по-умолчанию.
Вы идете циклом по списку из БД и добавляете маршруты в urlManager. Далее после того как все данные из БД обработаны, вы выбираете все маршруты из списка по-умолчанию, которые не встретились в БД и добавляете их.
Re: Собственные ссылки в yii2. Как?
Все бы хорошо, но. Проблема в том, что в базе ведь может быть много записей. Например 500. Я себе не представляю постоянно расширяющуюся таблицу, в которой будет расти кол-во записей. И потом около 1000 строк тащить из базы и обрабатывать совсем не круто.unclead писал(а):Подгружать из базы можно с использование метода addRules
а вот как сделать защиту в случае, если в БД уже есть роут, тут надо думать
Например, при динамическом добавлении роутов у вас есть 2 списка маршрутов: из БД и маршруты по-умолчанию.
Вы идете циклом по списку из БД и добавляете маршруты в urlManager. Далее после того как все данные из БД обработаны, вы выбираете все маршруты из списка по-умолчанию, которые не встретились в БД и добавляете их.
Читал конечно же. Единственное это то, что не совсем я понимаю что нужно делать...mkramer писал(а):http://www.yiiframework.com/doc-2.0/gui ... le-classes
Re: Собственные ссылки в yii2. Как?
непонятна задача.
опишите алгоритм того, что хотите получить.
опишите алгоритм того, что хотите получить.
Re: Собственные ссылки в yii2. Как?
Попытаюсь, если не понятно объяснить проще.dmg писал(а):непонятна задача.
опишите алгоритм того, что хотите получить.
Сейчас (стандартно) сайт работает так: test.loc/site/registration, где site/registration это контроллер/действие. Хотелось бы в некоторых случаях заменить ссылку такого вида на свою (придуманную), например заменить ссылку test.loc/site/registration на test.loc/registration , что заменить и на что его менять хранится в БД.
Алгоритм: Я создаю контроллер, потом действие и оно уже доступно через ссылку test.loc/controller/action, затем добавляю правило замены данной ссылки в БД ( ссылку test.loc/controller/action заменить например на test.loc/registration ) и уже в браузере вместо test.loc/controller/action, ввожу test.loc/registration, причем эта ссылка уже не должна работать -> test.loc/controller/action, а работает test.loc/registration вместо нее.
Грубо говоря, yii2 придумывает ссылки вида контроллер/действие. А я хочу сам давать произвольные имена ссылкам, только мои имена хранятся в БД.
Re: Собственные ссылки в yii2. Как?
Создайте свой класс UrlRule, который берет данные из БД и обрабатывает их. Храните данные в кэше и обновляйте его при добавлении/редактировании правил.Все бы хорошо, но. Проблема в том, что в базе ведь может быть много записей. Например 500. Я себе не представляю постоянно расширяющуюся таблицу, в которой будет расти кол-во записей. И потом около 1000 строк тащить из базы и обрабатывать совсем не круто.
Re: Собственные ссылки в yii2. Как?
Да, я понял что именно по этому пути надо идти. Но все же сложности возникают.unclead писал(а):Создайте свой класс UrlRule, который берет данные из БД и обрабатывает их. Храните данные в кэше и обновляйте его при добавлении/редактировании правил.
Добавил в правила свой класс обработки url.
Код: Выделить всё
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules'=> [
// 'register' => 'user/index',
['class' => 'frontend\components\Pages\PagesUrlRule', 'connectionID' => 'db'],
],
],
Код: Выделить всё
namespace frontend\components\Pages;
use frontend\models\Pages\Pages;
use yii\web\UrlRule;
class PagesUrlRule extends UrlRule
{
public $connectionID = 'db';
public function init()
{
if ($this->name === null) {
$this->name = __CLASS__;
}
}
public function createUrl($manager, $route, $params)
{
$model = Pages::find()->select('alias')->where(['route' => $route])->one()->alias;
if ($model) {
return $model;
}
return false; // это правило не подходит
}
public function parseRequest($manager, $request)
{
$pathInfo = $request->getPathInfo();
if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches)) {
$route = Pages::find()->select('route')->where(['alias' => $pathInfo])->one()->route;
$params= array();
if($route) {
return [$route, $params];
}
}
return false; // это правило не подходит
}
}
Что для меня еще не ясно:
1) Каждый раз при загрузке страницы, выполняется столько запросов в БД, сколько вызовов \Yii::$app->urlManager->createUrl(['user/registration']);
А если вызовов "createUrl" например 50 будет, то и запросов в БД будет 50. Не понятно как тут поступить.
2) Как сделать недоступной ссылку test.loc/user/registration (controller/action), если в базе есть короткая ссылка test.loc/registration
Re: Собственные ссылки в yii2. Как?
выгрузите 1 раз все правила и храните их во внутренней переменной класса, например, сделайте метода
и в коде уже просто выбирайте данные из массивов. Это лишь примерный путь в котором я бы двигался
Код: Выделить всё
private $routes;
private $aliases;
public function init()
{
parent::init();
$this->prepareData();
}
private function prepareData()
{
$pages = Pages::find()->asArray(true)->all();
$this->aliases = ArrayHelper::map($pages, 'route', 'alias');
$this->routes = ArrayHelper::map($pages, 'alias', 'route')
}
Re: Собственные ссылки в yii2. Как?
Я вот и думаю, а если записей в таблице со временем станет 500 или вообще 1000 (а в дальнейшем и еще больше)? Это будет тяжело, т.к. каждый раз при обновлении страницы 1000 записей будет тянуться из БД.unclead писал(а):выгрузите 1 раз все правила и храните их во внутренней переменной класса, например, сделайте метода
и в коде уже просто выбирайте данные из массивов. Это лишь примерный путь в котором я бы двигался
Re: Собственные ссылки в yii2. Как?
КешируйтеMatthew писал(а): Я вот и думаю, а если записей в таблице со временем станет 500 или вообще 1000 (а в дальнейшем и еще больше)? Это будет тяжело, т.к. каждый раз при обновлении страницы 1000 записей будет тянуться из БД.
Re: Собственные ссылки в yii2. Как?
Кеш - наше всё
Кстати, вопрос к гуру: зачем указывать 'connectionID' => 'db' ?
Кстати, вопрос к гуру: зачем указывать 'connectionID' => 'db' ?
Спишь?
Re: Собственные ссылки в yii2. Как?
в данном случае не нужно.Ferro7 писал(а):Кеш - наше всё
Кстати, вопрос к гуру: зачем указывать 'connectionID' => 'db' ?
а вообще для работы через нужный DB-компонент, который обычно 'db'
Re: Собственные ссылки в yii2. Как?
что конкретно?mkramer писал(а):КешируйтеMatthew писал(а): Я вот и думаю, а если записей в таблице со временем станет 500 или вообще 1000 (а в дальнейшем и еще больше)? Это будет тяжело, т.к. каждый раз при обновлении страницы 1000 записей будет тянуться из БД.
Re: Собственные ссылки в yii2. Как?
1000 записей, которые один раз вытянулись из базы данных, разместить в какой-нибудь memcache, и они себе там висят и быстренько берутся.
Re: Собственные ссылки в yii2. Как?
если не секрет, какое мега приложение может требовать 1000 и более действий contoller/action и каждый с уникальными Url?
Re: Собственные ссылки в yii2. Как?
вы считаете 1000 строк в бд это большие объемы? интересно, что тогда для вас миллион записей. Поверьте это не будет самым узким местом т.к. вы выбираете все данные без условий, сортировок и лимитов. В противном случае кешируйте, как уже написали вышеЭто будет тяжело, т.к. каждый раз при обновлении страницы 1000 записей будет тянуться из БД.
Re: Собственные ссылки в yii2. Как?
Хорошо, я в этом вопросе доверюсь советам и кэшу, спасибо. Только вот такая конструкция не работает:
Метод init не выполняется. Я пробовал __construct тоже не выполняется.
Что на счет того, чтобы заблокировать ссылки controller/action если уже есть короткая (есть в БД, кеше) ссылка?
Код: Выделить всё
public function init()
{
parent::init();
$this->prepareData();
}
private function prepareData()
{
$pages = Pages::find()->asArray(true)->all();
$this->aliases = ArrayHelper::map($pages, 'route', 'alias');
$this->routes = ArrayHelper::map($pages, 'alias', 'route')
}
Что на счет того, чтобы заблокировать ссылки controller/action если уже есть короткая (есть в БД, кеше) ссылка?