
Дублирование страниц - явление при котором одна и та же страница доступна по нескольким адресам или же когда страницы имеют одинаковый контент. При этом не обязательно, что были допущены какие-либо ошибки в разработке сайта. Причины могут быть разные, но решать проблему надо, т.к. при выявлении дублей страниц, поисковые системы негативно проявляют себя по отношению к этому сайту.
Дубли могут быть разные и способы решения этой проблемы есть разные. В данной статье я коснусь лишь вариантов, которые можно решить с помощью самого Yii2, т.к. дубли которые мы будем исправлять и специфичны как раз для данного фреймворка и очень распространены.
Если вы владелец сайта на yii2, попробуйте вместо:
http://site.com
открыть сайт по такой ссылке:
http://site.com/frontend/web/index.php (для Yii2 Advanced)
или
http://site.com/web/index.php (для Yii2 Basic)
"site.com", разумеется, нужно заменить на доменное имя вашего сайта. Если получится открыть страницу - имеем дубли. Причем "дубли", а не дубль, т.к. скорее всего таким образом можно будет открыть не только главную страницу но и многие другие, подставив их параметры после index.php/...
Решать данную проблему будем двумя способами:
- созданием переадресации на нужную страницу (редирект 301);
- выводом ошибки (404) в ответ на запрос о получении страницы по неверному URL.
Начнем с первого варианта.

301 — это код статуса, возвращаемого веб-сервером клиенту (браузеру). Значение этого статуса - Moved Permanently (страница перемещена по новому постоянному адресу). Для создания такое переадресации нужно добавить код
public function beforeaction($action){ $absoluteUrl = Yii::$app->request->absoluteUrl; if ((strpos($absoluteUrl, 'index.php') !== false)) { $scriptUrl = Yii::$app->request->scriptUrl; $new_url = str_replace($scriptUrl, "", $absoluteUrl); $this->redirect($new_url, 301); } return true; }в нужный контроллер (в котором содержатся действия выводящие дублирующие страницы), то есть контроллер, который отвечает за вывод страниц вашего сайта. Метод beforeaction() выполняется до выполнения остальных методов и переадресует посетителя еще до того как ему откроется запрашиваемая страница. Если данный метод уже присутствует в коде, то разместите данный пример в начале метода.
В случае наличия нескольких контроллеров, например для рубрик, меток... скорее всего понадобится этот код разместить и в них. Но в данном случае, будет правильным создать один родительский контроллер, например MainController и остальные наследовать от него, с целью не дублировать код. Тогда в остальных контроллерах нужно подключить его:
use frontend\controllers\MainController;и наследовать класс нужного контроллера от него, например:
class SiteController extends MainControllerПри этом в контроллерах, где уже есть такой же (одноименный) метод, нужно дополнительно в начале этого метода прописать:
parent::beforeAction();для вызова родительского метода beforeAction(). Т.к. одноименный метод полностью перезаписывает родительский.
Что касается скрипта вышеприведенного примера, то мы вначале получаем текущий url, проверяем наличие в нем "index.php" и в случае нахождения удаляем из URL словосочетание "frontend/web/index.php" (или "frontend/web/index.php" или "web/index.php" ), после чего получившийся URL сохраняем в переменную $new_url и делаем на него перенаправление, указывая статус "301". Ищем именно index.php, а не целиком frontend/web/index.php как раз для того, чтобы данный способ был универсальным и не зависел от версии yii2 и области видимости контроллера. То есть делаем из "index.php" красную тряпку - если есть в URL - значит "Давай до свидания!" :)

Второй вариант очень похож, но вместо перенаправления мы вызываем ошибку, точно так же как если посетитель сайта введет любой другой адрес несуществующей страницы вашего сайта:
public function beforeaction($action){ $absoluteUrl = Yii::$app->request->absoluteUrl; if ((strpos($absoluteUrl, 'index.php') !== false)) { throw new \yii\web\HttpException(404 ,'Страница не найдена.'); } return true; }HttpException - класс Yii2, отвечающий за создание/вывод исключений (ошибок). В данном случае сервер выдаст ошибку 404 или Not Found что значит - «не найдено». Тогда данный URL будет выброшен из индексации поисковиками, если туда уже попал.
Какой из этих вариантов выбрать - решать вам, это уже не так важно. Например я выбрал переадресацию.