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

Дубли могут быть разные и способы решения этой проблемы есть разные. В данной статье я коснусь лишь вариантов, которые можно решить с помощью самого 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.


Начнем с первого варианта.

redirect 301

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 - значит "Давай до свидания!" :)

ошибка 404

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

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 будет выброшен из индексации поисковиками, если туда уже попал.


Какой из этих вариантов выбрать - решать вам, это уже не так важно. Например я выбрал переадресацию.