200
Ugh… (309, 400, 403, 409, 415, 422)… a lot of answers trying to guess, argue and standardize what is the best return code for a successful HTTP request but a failed REST call.
It is wrong to mix HTTP status codes and REST status codes.
However, I saw many implementations mixing them, and many developers may not agree with me.
HTTP return codes are related to the HTTP Request itself. A REST call is done using a Hypertext Transfer Protocol request and it works at a lower level than invoked REST method itself. REST is a concept/approach, and its output is a business/logical result, while HTTP result code is a transport one.
For example, returning «404 Not found» when you call /users/ is confuse, because it may mean:
- URI is wrong (HTTP)
- No users are found (REST)
«403 Forbidden/Access Denied» may mean:
- Special permission needed. Browsers can handle it by asking the user/password. (HTTP)
- Wrong access permissions configured on the server. (HTTP)
- You need to be authenticated (REST)
And the list may continue with ‘500 Server error» (an Apache/Nginx HTTP thrown error or a business constraint error in REST) or other HTTP errors etc…
From the code, it’s hard to understand what was the failure reason, a HTTP (transport) failure or a REST (logical) failure.
If the HTTP request physically was performed successfully it should always return 200 code, regardless is the record(s) found or not. Because URI resource is found and was handled by the HTTP server. Yes, it may return an empty set. Is it possible to receive an empty web-page with 200 as HTTP result, right?
Instead of this you may return 200 HTTP code with some options:
- «error» object in JSON result if something goes wrong
- Empty JSON array/object if no record found
- A bool result/success flag in combination with previous options for a better handling.
Also, some internet providers may intercept your requests and return you a 404 HTTP code. This does not means that your data are not found, but it’s something wrong at transport level.
From Wiki:
In July 2004, the UK telecom provider BT Group deployed the Cleanfeed
content blocking system, which returns a 404 error to any request for
content identified as potentially illegal by the Internet Watch
Foundation. Other ISPs return a HTTP 403 «forbidden» error in the same
circumstances. The practice of employing fake 404 errors as a means to
conceal censorship has also been reported in Thailand and Tunisia. In
Tunisia, where censorship was severe before the 2011 revolution,
people became aware of the nature of the fake 404 errors and created
an imaginary character named «Ammar 404» who represents «the invisible
censor».
Why not simply answer with something like this?
{
"result": false,
"error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}
Google always returns 200 as status code in their Geocoding API, even if the request logically fails: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes
Facebook always return 200 for successful HTTP requests, even if REST request fails: https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling
It’s simple, HTTP status codes are for HTTP requests. REST API is Your, define Your status codes.
Почти все разработчики так или иначе постоянно работают с api по http, клиентские разработчики работают с api backend своего сайта или приложения, а бэкендеры «дергают» бэкенды других сервисов, как внутренних, так и внешних. И мне кажется, одна из самых главных вещей в хорошем API это формат передачи ошибок. Ведь если это сделано плохо/неудобно, то разработчик, использующий это API, скорее всего не обработает ошибки, а клиенты будут пользоваться молчаливо ломающимся продуктом.
За 7 лет я как поддерживал множество legacy API, так и разрабатывал c нуля. И я поработал, наверное, с большинством стратегий по возвращению ошибок, но каждая из них создавала дискомфорт в той или иной мере. В последнее время я нащупал оптимальный вариант, о котором и хочу рассказать, но с начала расскажу о двух наиболее популярных вариантах.
№1: HTTP статусы
Если почитать апологетов REST, то для кодов ошибок надо использовать HTTP статусы, а текст ошибки отдавать в теле или в специальном заголовке. Например:
Success:
HTTP 200 GET /v1/user/1
Body: { name: 'Вася' }
Error:
HTTP 404 GET /v1/user/1
Body: 'Не найден пользователь'
Если у вас примитивная бизнес-логика или API из 5 url, то в принципе это нормальный подход. Однако как-только бизнес-логика станет сложнее, то начнется ряд проблем.
Http статусы предназначались для описания ошибок при передаче данных, а про логику вашего приложения никто не думал. Статусов явно не хватает для описания всего разнообразия ошибок в вашем проекте, да они и не были для этого предназначены. И тут начинается натягивание «совы на глобус»: все начинают спорить, какой статус ошибки дать в том или ином случае. Пример: Есть API для task manager. Какой статус надо вернуть в случае, если пользователь хочет взять задачу, а ее уже взял в работу другой пользователь? Ссылка на http статусы. И таких проблемных примеров можно придумать много.
REST скорее концепция, чем формат общения из чего следует неоднозначность использования статусов. Разработчики используют статусы как им заблагорассудится. Например, некоторые API при отсутствии сущности возвращают 404 и текст ошибки, а некоторые 200 и пустое тело.
Бэкенд разработчику в проекте непросто выбрать статус для ошибки, а клиентскому разработчику неочевидно какой статус предназначен для того или иного типа ошибок бизнес-логики. По-хорошему в проекте придется держать enum для того, чтобы описать какие ошибки относятся к тому или иному статусу.
Когда бизнес-логика приложения усложняется, начинают делать как-то так:
HTTP 400 PUT /v1/task/1 { status: 'doing' }
Body: { error_code: '12', error_message: 'Задача уже взята другим исполнителем' }
Из-за ограниченности http статусов разработчики начинают вводить “свои” коды ошибок для каждого статуса и передавать их в теле ответа. Другими словами, пользователю API приходится писать нечто подобное:
if (status === 200) {
// Success
} else if (status === 500) {
// some code
} else if (status === 400) {
if (body.error_code === 1) {
// some code
} else if (body.error_code === 2) {
// some code
} else {
// some code
}
} else if (status === 404) {
// some code
} else {
// some code
}
Из-за этого ветвление клиентского кода начинает стремительно расти: множество http статусов и множество кодов в самом сообщении. Для каждого ошибочного http статуса необходимо проверить наличие кодов ошибок в теле сообщения. От комбинаторного взрыва начинает конкретно пухнуть башка! А значит обработку ошибок скорее всего сведут к сообщению типа “Произошла ошибка” или к молчаливому некорректному поведению.
Многие системы мониторинга сервисов привязываются к http статусам, но это не помогает в мониторинге, если статусы используются для описания ошибок бизнес логики. Например, у нас резкий всплеск ошибок 429 на графике. Это началась DDOS атака, или кто-то из разработчиков выбрал неудачный статус?
Итог: Начать с таким подходом легко и просто и для простого API это вполне подойдет. Но если логика стала сложнее, то использование статусов для описания того, что не укладывается в заданные рамки протокола http приводит к неоднозначности использования и последующим костылям для работы с ошибками. Или что еще хуже к формализму, что ведет к неприятному пользовательскому опыту.
№2: На все 200
Есть другой подход, даже более старый, чем REST, а именно: на все ошибки связанные с бизнес-логикой возвращать 200, а уже в теле ответа есть информация об ошибке. Например:
Вариант 1:
Success:
HTTP 200 GET /v1/user/1
Body: { ok: true, data: { name: 'Вася' } }
Error:
HTTP 200 GET /v1/user/1
Body: { ok: false, error: { code: 1, msg: 'Не найден пользователь' } }
Вариант 2:
Success:
HTTP 200 GET /v1/user/1
Body: { data: { name: 'Вася' }, error: null }
Error:
HTTP 200 GET /v1/user/1
Body: { data: null, error: { code: 1, msg: 'Не найден пользователь' } }
На самом деле формат зависит от вас или от выбранной библиотеки для реализации коммуникации, например JSON-API.
Звучит здорово, мы теперь отвязались от http статусов и можем спокойно ввести свои коды ошибок. У нас больше нет проблемы “впихнуть невпихуемое”. Выбор нового типа ошибки не вызывает споров, а сводится просто к введению нового числового номера (например, последовательно) или строковой константы. Например:
module.exports = {
NOT_FOUND: 1,
VALIDATION: 2,
// ….
}
module.exports = {
NOT_FOUND: ‘NOT_AUTHORIZED’,
VALIDATION: ‘VALIDATION’,
// ….
}
Клиентские разработчики просто основываясь на кодах ошибок могут создать классы/типы ошибок и притом не бояться, что сервер вернет один и тот же код для разных типов ошибок (из-за бедности http статусов).
Обработка ошибок становится менее ветвящейся, множество http статусов превратились в два: 200 и все остальные (ошибки транспорта).
if (status === 200) {
if (body.error) {
var error = body.error;
if (error.code === 1) {
// some code
} else if (error.code === 2) {
// some code
} else {
// some code
}
} else {
// Success
}
} else {
// transport erros
}
В некоторых случаях, если есть библиотека десериализации данных, она может взять часть работы на себя. Писать SDK вокруг такого подхода проще нежели вокруг той или иной имплементации REST, ведь реализация зависит от того, как это видел автор. Кроме того, теперь никто не вызовет случайное срабатывание alert в мониторинге из-за того, что выбрал неудачный код ошибки.
Но неудобства тоже есть:
-
Избыточность полей при передаче данных, т.е. нужно всегда передавать 2 поля: для данных и для ошибки. Это усложняет чтение логов и написание документации.
-
При использовании средств отладки (Chrome DevTools) или других подобных инструментов вы не сможете быстро найти ошибочные запросы бизнес логики, придется обязательно заглянуть в тело ответа (ведь всегда 200)
-
Мониторинг теперь точно будет срабатывать только на ошибки транспорта, а не бизнес-логики, но для мониторинга логики надо будет дописывать парсинг тела сообщения.
В некоторых случаях данный подход вырождается в RPC, то есть по сути вообще отказываются от использования url и шлют все на один url методом POST, а в теле сообщения передают все параметры. Мне кажется это не правильным, ведь url это прекрасный именованный namespace, зачем от этого отказываться, не понятно?! Кроме того, RPC создает проблемы:
-
нельзя кэшировать по http GET запросы, так как замешали чтение и запись в один метод POST
-
нельзя делать повторы для неудавшихся GET запросов (на backend) на реверс-прокси (например, nginx) по указанной выше причине
-
имеются проблемы с документированием – swagger и ApiDoc не подходят, а удобных аналогов я не нашел
Итог: Для сложной бизнес-логики с большим количеством типов ошибок такой подход лучше, чем расплывчатый REST, не зря в проектах c “разухабистой” бизнес-логикой часто именно такой подход и используют.
№3: Смешанный
Возьмем лучшее от двух миров. Мы выберем один http статус, например, 400 или 422 для всех ошибок бизнес-логики, а в теле ответа будем указывать код ошибки или строковую константу. Например:
Success:
HTTP 200 /v1/user/1
Body: { name: 'Вася' }
Error:
HTTP 400 /v1/user/1
Body: { error: { code: 1, msg: 'Не найден пользователь' } }
Коды:
-
200 – успех
-
400 – ошибка бизнес логики
-
остальное ошибки в транспорте
Тело ответа для удачного запроса у нас имеет произвольную структуру, а вот для ошибки есть четкая схема. Мы избавляемся от избыточности данных (поле ошибки/данных) благодаря использованию http статуса в сравнении со вторым вариантом. Клиентский код упрощается в плане обработки ошибки (в сравнении с первым вариантом). Также мы снижаем его вложенность за счет использования отдельного http статуса для ошибок бизнес логики (в сравнении со вторым вариантом).
if (status === 200) {
// Success
} else if (status === 400) {
if (body.error.code === 1) {
// some code
} else if (body.error.code === 2) {
// some code
} else {
// some code
}
} else {
// transport erros
}
Мы можем расширять объект ошибки для детализации проблемы, если хотим. С мониторингом все как во втором варианте, дописывать парсинг придется, но и риска “стрельбы” некорректными alert нету. Для документирования можем спокойно использовать Swagger и ApiDoc. При этом сохраняется удобство использования инструментов разработчика, таких как Chrome DevTools, Postman, Talend API.
Итог: Использую данный подход уже в нескольких проектах, где множество типов ошибок и все крайне довольны, как клиентские разработчики, так и бэкендеры. Внедрение новой ошибки не вызывает споров, проблем и противоречий. Данный подход объединяет преимущества первого и второго варианта, при этом код более читабельный и структурированный.
Самое главное какой бы формат ошибок вы бы не выбрали лучше обговорить его заранее и следовать ему. Если эту вещь пустить на “самотек”, то очень скоро обработка ошибок в проекте станет невыносимо сложной для всех.
P.S. Иногда ошибки любят передавать массивом
{ error: [{ code: 1, msg: 'Не найден пользователь' }] }
Но это актуально в основном в двух случаях:
-
Когда наш API выступает в роли сервиса без фронтенда (нет сайта/приложения). Например, сервис платежей.
-
Когда в API есть url для загрузки какого-нибудь длинного отчета в котором может быть ошибка в каждой строке/колонке. И тогда для пользователя удобнее, чтобы ошибки в приложении сразу показывались все, а не по одной.
В противном случае нет особого смысла закладываться сразу на массив ошибок, потому что базовая валидация данных должна происходить на клиенте, зато код упрощается как на сервере, так и на клиенте. А user-experience хакеров, лезущих напрямую в наше API, не должен нас волновать?HTTP
Информационные
100
Continue
«Продолжить». Этот промежуточный ответ указывает, что запрос успешно
принят и клиент может продолжать присылать запросы либо проигнорировать
этот ответ, если запрос был завершён.
Только HTTP/1.1
101
Switching Protocol
«Переключение протокола». Этот код присылается в ответ на запрос
клиента, содержащий заголовок Upgrade:, и указывает, что
сервер переключился на протокол, который был указан в заголовке. Эта
возможность позволяет перейти на несовместимую версию протокола и обычно
не используется.
Только HTTP/1.1
102
Processing
«В обработке». Этот код указывает, что сервер получил запрос и
обрабатывает его, но обработка ещё не завершена.
Только HTTP/1.1
103
Early Hints
«Ранние подсказки». В ответе сообщаются ресурсы, которые могут быть
загружены заранее, пока сервер будет подготавливать основной ответ.
RFC 8297 (Experimental).
Только HTTP/1.1
Успешные
200
OK
«Успешно». Запрос успешно обработан. Что значит «успешно», зависит от
метода HTTP, который был запрошен:
- GET: «ПОЛУЧИТЬ». Запрошенный ресурс был найден и передан в теле
ответа. - HEAD: «ЗАГОЛОВОК». Заголовки переданы в ответе.
- POST: «ПОСЫЛКА». Ресурс, описывающий результат действия сервера на
запрос, передан в теле ответа. - TRACE: «ОТСЛЕЖИВАТЬ». Тело ответа содержит тело запроса полученного
сервером.
HTTP/0.9 и выше
201
Created
«Создано». Запрос успешно выполнен и в результате был создан ресурс.
Этот код обычно присылается в ответ на запрос PUT «ПОМЕСТИТЬ».
HTTP/0.9 и выше
202
Accepted
«Принято». Запрос принят, но ещё не обработан. Не поддерживаемо, т.е.,
нет способа с помощью HTTP отправить асинхронный ответ позже, который
будет показывать итог обработки запроса. Это предназначено для случаев,
когда запрос обрабатывается другим процессом или сервером, либо для
пакетной обработки.
HTTP/0.9 и выше
203
Non-Authoritative Information
«Информация не авторитетна». Этот код ответа означает, что информация,
которая возвращена, была предоставлена не от исходного сервера, а из
какого-нибудь другого источника. Во всех остальных ситуациях более
предпочтителен код ответа 200 OK.
HTTP/0.9 и 1.1
204
No Content
«Нет содержимого». Нет содержимого для ответа на запрос, но заголовки
ответа, которые могут быть полезны, присылаются. Клиент может
использовать их для обновления кешированных заголовков полученных ранее
для этого ресурса.
HTTP/0.9 и выше
205
Reset Content
«Сбросить содержимое». Этот код присылается, когда запрос обработан,
чтобы сообщить клиенту, что необходимо сбросить отображение документа,
который прислал этот запрос.
Только HTTP/1.1
206
Partial Content
«Частичное содержимое». Этот код ответа используется, когда клиент
присылает заголовок диапазона, чтобы выполнить загрузку отдельно, в
несколько потоков.
Только HTTP/1.1
Сообщения о перенаправлениях
300
Multiple Choice
«Множественный выбор». Этот код ответа присылается, когда запрос имеет
более чем один из возможных ответов. И User-agent или пользователь
должен выбрать один из ответов. Не существует стандартизированного
способа выбора одного из полученных ответов.
HTTP/1.0 и выше
301
Moved Permanently
«Перемещён на постоянной основе». Этот код ответа значит, что URI
запрашиваемого ресурса был изменён. Возможно, новый URI будет
предоставлен в ответе.
HTTP/0.9 и выше
302
Found
«Найдено». Этот код ответа значит, что запрошенный ресурс
временно изменён. Новые изменения в URI могут быть доступны в
будущем. Таким образом, этот URI, должен быть использован клиентом в
будущих запросах.
HTTP/0.9 и выше
303
See Other
«Просмотр других ресурсов». Этот код ответа присылается, чтобы
направлять клиента для получения запрашиваемого ресурса в другой URI с
запросом GET.
HTTP/0.9 и 1.1
304
Not Modified
«Не модифицировано». Используется для кеширования. Это код ответа
значит, что запрошенный ресурс не был изменён. Таким образом, клиент
может продолжать использовать кешированную версию ответа.
HTTP/0.9 и выше
305
Use Proxy
«Использовать прокси». Это означает, что запрошенный ресурс должен быть
доступен через прокси. Этот код ответа в основном не поддерживается из
соображений безопасности.
Только HTTP/1.1
306
Switch Proxy
Больше не использовать. Изначально подразумевалось, что » последующие
запросы должны использовать указанный прокси.»
Только HTTP/1.1
307
Temporary Redirect
«Временное перенаправление». Сервер отправил этот ответ, чтобы клиент
получил запрошенный ресурс на другой URL-адрес с тем же методом, который
использовал предыдущий запрос. Данный код имеет ту же семантику, что код
ответа 302 Found, за исключением того, что агент
пользователя не должен изменять используемый метод HTTP: если в первом
запросе использовался POST, то во втором запросе также
должен использоваться POST.
Только HTTP/1.1
308
Permanent Redirect
«Перенаправление на постоянной основе». Это означает, что ресурс
теперь постоянно находится в другом URI, указанном в заголовке
Location: HTTP Response. Данный код ответа имеет ту же
семантику, что и код ответа 301 Moved Permanently, за
исключением того, что агент пользователя не должен изменять
используемый метод HTTP: если POST использовался в первом
запросе, POST должен использоваться и во втором запросе.
Примечание: Это экспериментальный код ответа,
Спецификация которого в настоящее время находится в черновом виде.
draft-reschke-http-status-308
Клиентские
400
Bad Request
«Плохой запрос». Этот ответ означает, что сервер не понимает запрос
из-за неверного синтаксиса.
HTTP/0.9 и выше
401
Unauthorized
«Неавторизованно». Для получения запрашиваемого ответа нужна
аутентификация. Статус похож на статус 403, но,в этом случае,
аутентификация возможна.
HTTP/0.9 и выше
402
Payment Required
«Необходима оплата». Этот код ответа зарезервирован для будущего
использования. Первоначальная цель для создания этого кода была в
использовании его для цифровых платёжных систем(на данный момент не
используется).
HTTP/0.9 и 1.1
403
Forbidden
«Запрещено». У клиента нет прав доступа к содержимому, поэтому сервер
отказывается дать надлежащий ответ.
HTTP/0.9 и выше
404
Not Found
«Не найден». Сервер не может найти запрашиваемый ресурс. Код этого
ответа, наверно, самый известный из-за частоты его появления в вебе.
HTTP/0.9 и выше
405
Method Not Allowed
«Метод не разрешён». Сервер знает о запрашиваемом методе, но он был
деактивирован и не может быть использован. Два обязательных метода,
GET и HEAD, никогда не должны быть
деактивированы и не должны возвращать этот код ошибки.
Только HTTP/1.1
406
Not Acceptable
Этот ответ отсылается, когда веб сервер после выполнения
server-driven content negotiation, не нашёл контента, отвечающего критериям, полученным из user agent.
Только HTTP/1.1
407
Proxy Authentication Required
Этот код ответа аналогичен коду 401, только аутентификация требуется для
прокси сервера.
Только HTTP/1.1
408
Request Timeout
Ответ с таким кодом может прийти, даже без предшествующего запроса. Он
означает, что сервер хотел бы отключить это неиспользуемое соединение.
Этот метод используется все чаще с тех пор, как некоторые браузеры,
вроде Chrome и IE9, стали использовать
HTTP механизмы предварительного соединения
для ускорения сёрфинга (смотрите баг 634278, будущей
реализации этого механизма в Firefox). Также учитывайте, что некоторые
серверы прерывают соединения не отправляя подобных сообщений.
Только HTTP/1.1
409
Conflict
Этот ответ отсылается, когда запрос конфликтует с текущим состоянием
сервера.
Только HTTP/1.1
410
Gone
Этот ответ отсылается, когда запрашиваемый контент удалён с сервера.
Только HTTP/1.1
411
Length Required
Запрос отклонён, потому что сервер требует указание заголовка
Content-Length, но он не указан.
Только HTTP/1.1
412
Precondition Failed
Клиент указал в своих заголовках условия, которые сервер не может
выполнить
Только HTTP/1.1
413
Request Entity Too Large
Размер запроса превышает лимит, объявленный сервером. Сервер может
закрыть соединение, вернув заголовок Retry-After
Только HTTP/1.1
414
Request-URI Too Long
URI запрашиваемый клиентом слишком длинный для того, чтобы сервер смог
его обработать
Только HTTP/1.1
415
Unsupported Media Type
Медиа формат запрашиваемых данных не поддерживается сервером, поэтому
запрос отклонён
Только HTTP/1.1
416
Requested Range Not Satisfiable
Диапазон указанный заголовком запроса Range не может быть
выполнен; возможно, он выходит за пределы переданного URI
Только HTTP/1.1
417
Expectation Failed
Этот код ответа означает, что ожидание, полученное из заголовка запроса
Expect, не может быть выполнено сервером.
Только HTTP/1.1
Серверные
500
Internal Server Error
«Внутренняя ошибка сервера». Сервер столкнулся с ситуацией, которую он
не знает как обработать.
HTTP/0.9 и выше
501
Not Implemented
«Не реализовано». Метод запроса не поддерживается сервером и не может быть
обработан. Единственные методы, которые сервера должны поддерживать (и,
соответственно, не должны возвращать этот код) — GET и
HEAD.
HTTP/0.9 и выше
502
Bad Gateway
«Плохой шлюз». Эта ошибка означает что сервер, во время работы в
качестве шлюза для получения ответа, нужного для обработки запроса,
получил недействительный (недопустимый) ответ.
HTTP/0.9 и выше
503
Service Unavailable
«Сервис недоступен». Сервер не готов обрабатывать запрос. Зачастую
причинами являются отключение сервера или то, что он перегружен.
Обратите внимание, что вместе с этим ответом удобная для
пользователей(user-friendly) страница должна отправлять объяснение
проблемы. Этот ответ должен использоваться для временных условий и
Retry-After: HTTP-заголовок должен, если возможно,
содержать предполагаемое время до восстановления сервиса. Веб-мастер
также должен позаботиться о заголовках, связанных с кешем, которые
отправляются вместе с этим ответом, так как эти ответы, связанные с
временными условиями, обычно не должны кешироваться.
HTTP/0.9 и выше
504
Gateway Timeout
Этот ответ об ошибке предоставляется, когда сервер действует как шлюз и
не может получить ответ вовремя.
Только HTTP/1.1
505
HTTP Version Not Supported
«HTTP-версия не поддерживается». HTTP-версия, используемая в запросе, не
поддерживается сервером.
Только HTTP/1.1
Наличие ошибок в коде страницы сайта всегда влечет за собой негативные последствия – от ухудшения позиций в ранжировании до жалоб со стороны пользователей. Ошибки валидации могут наблюдаться как на главной, так и на иных веб-страницах, их наличие свидетельствует о том, что ресурс является невалидным. Некоторые проблемы замечают даже неподготовленные пользователи, другие невозможно обнаружить без предварительного аудита, анализа. О том, что такое ошибки валидации и как их обнаружить, мы сейчас расскажем.

Ошибка валидации, что это такое?
Для написания страниц используется HTML – стандартизированный язык разметки, применяемый в веб-разработке. HTML, как любой другой язык, имеет специфические особенности синтаксиса, грамматики и т. д. Если во время написания кода правила не учитываются, то после запуска сайта будут появляться различные виды проблем. Если HTML-код ресурса не соответствует стандарту W3C, то он является невалидным, о чем мы писали выше.
Почему ошибки валидации сайта оказывают влияние на ранжирование, восприятие?
Наличие погрешностей в коде – проблема, с которой необходимо бороться сразу после обнаружения. Поисковые системы «читают» HTML-код, если он некорректный, то процесс индексации и ранжирования может быть затруднен. Поисковые роботы должны понимать, каким является ресурс, что он предлагает, какие запросы использует. Особо критичны такие ситуации для ресурсов, имеющих большое количество веб-страниц.
Как проверить ошибки валидации?
Для этой работы используется либо технический аудит сайта, либо валидаторы, которые ищут проблемы автоматически. Одним из самых популярных является сервис The W3C Markup Validation Service, выполняющий сканирование с оглядкой на World Wide Web Consortium (W3C). Рассматриваемый валидатор предлагает три способа, с помощью которых можно осуществить проверку сайта:
- ввод URL-адреса страниц, которые необходимо просканировать;
- загрузка файла страницы;
- ввод части HTML-кода, нуждающегося в проверке.
После завершения проверки вы получите развернутый список выявленных проблем, дополненных описанием, ссылками на стандарты W3C. По ходу анализа вы увидите слабые места со ссылками на правила, что позволит самостоятельно исправить проблему.
Существуют другие сервисы, позволяющие выполнить проверку валидности кода:
- Dr. Watson. Проверяет скорость загрузки страниц, орфографию, ссылки, а также исходный код;
- InternetSupervision.com. Отслеживает производительность сайта, проверяет доступность HTML.
Плагины для браузеров, которые помогут найти ошибки в коде
Решить рассматриваемую задачу можно с помощью плагинов, адаптированных под конкретный браузер. Можно использовать следующие инструменты (бесплатные):
- HTML Validator для браузера Firefox;
- HTML Validator for Chrome;
- Validate HTML для Firefox.
После проверки нужно решить, будете ли вы устранять выявленные ошибки. Многие эксперты акцентируют внимание на том, что поисковые системы сегодня уделяют больше внимания качеству внешней/внутренней оптимизации, контенту, другим характеристикам. Однако валидность нельзя оставлять без внимания, ведь если даже обнаруженные проблемы не будут мешать поисковым ботам, то они точно начнут раздражать посетителей сайта.
Как исправить ошибку валидации?
В первую очередь нужно сосредоточить внимание на слабых местах, связанных с контентом – это то, что важно для поисковых систем. Если во время сканирования было выявлено более 25 проблем, то их нельзя игнорировать из-за ряда причин:
- частичная индексация;
- медленная загрузка;
- баги, возникающие во время непосредственной коммуникации пользователя с ресурсом.
Например, игнорирование ошибок может привести к тому, что некоторые страницы не будут проиндексированы. Для решения рассматриваемой проблемы можно привлечь опытного фрилансера, однако лучшее решение – заказ услуги в веб-агентстве, что позволит исправить, а не усугубить ситуацию.
Технический и SEO-аудит
Выявление ошибок – первый шаг, ведь их еще нужно будет устранить. При наличии большого пула проблем целесообразно заказать профессиональный аудит сайта. Он поможет найти разные виды ошибок, повысит привлекательность ресурса для поисковых ботов, обычных пользователей: скорость загрузки страниц, верстка, переспам, другое.
В заключение
На всех сайтах наблюдаются ошибки валидации – их невозможно искоренить полностью, но и оставлять без внимания не стоит. Например, если провести проверку сайтов Google или «Яндекс», то можно увидеть ошибки, однако это не означает, что стоит вздохнуть спокойно и закрыть глаза на происходящее. Владелец сайта должен ставить во главу угла комплексное развитие, при таком подходе ресурс будет наполняться, обновляться и «лечиться» своевременно. Если проблем мало, то можно попробовать устранить их своими силами или с помощью привлечения стороннего частного специалиста. В остальных случаях лучше заказать услугу у проверенного подрядчика.

Просмотров 1.2к. Опубликовано 19.12.2022
Обновлено 19.12.2022
Каждый сайт, который создает компания, должен отвечать принятым стандартам. В первую очередь затем, чтобы он попадал в поисковую выдачу и был удобен для пользователей. Если код страниц содержит ошибки, неточности, он становится “невалидным”, то есть не соответствующим требованиям. В результате интернет-ресурс не увидят пользователи или информация на нем будет отображаться некорректно.
В этой статье рассмотрим, что такое валидность, какие могут быть ошибки в HTML-разметке и как их устранить.
Содержание
- Что такое HTML-ошибка валидации и зачем она нужна
- Чем опасны ошибки в разметке
- Как проверить ошибки валидации
- Предупреждения
- Ошибки
- Пример прохождения валидации для страницы сайта
- Как исправить ошибку валидации
- Плагины для браузеров, которые помогут найти ошибки в коде
- Коротко о главном
Что такое HTML-ошибка валидации и зачем она нужна
Под понятием “валидация” подразумевается процесс онлайн-проверки HTML-кода страницы на соответствие стандартам w3c. Эти стандарты были разработаны Организацией всемирной паутины и стандартов качества разметки. Сама организация продвигает идею унификации сайтов по HTML-коду — чтобы каждому пользователю, вне зависимости от браузера или устройства, было удобно использовать ресурс.
Если код отвечает стандартам, то его называют валидным. Браузеры могут его прочитать, загрузить страницы, а поисковые системы легко находят страницу по соответствующему запросу.
Чем опасны ошибки в разметке
Ошибки валидации могут разными — видимыми для глаза простого пользователя или такими, которые можно засечь только с помощью специальных программ. В первом случае кроме технических проблем, ошибки в разметке приводят к негативному пользовательскому опыту.
К наиболее распространённым последствиям ошибок в коде HTML-разметки также относят сбои в нормальной работе сайта и помехи в продвижении ресурса в поисковых системах.
Рассмотрим несколько примеров, как ошибки могут проявляться при работе:
- Медленно подгружается страница
Согласно исследованию Unbounce, более четверти пользователей покидают страницу, если её загрузка занимает более 3 секунд, ещё треть уходит после 6 секунд;
- Не видна часть текстовых, фото и видео-блоков
Эта проблема делает контент для пользователей неинформативным, поэтому они в большинстве случаев уходят со страницы, не досмотрев её до конца;
- Страница может остаться не проиндексированной
Если поисковый робот распознает недочёт в разметке, он может пропустить страницу и прервать её размещение в поисковых системах;
- Разное отображение страниц на разных устройствах
Например, на компьютере или ноутбуке страница будет выглядеть хорошо, а на мобильных гаджетах половина кнопок и изображений будет попросту не видна.
Из-за этих ошибок пользователь не сможет нормально работать с ресурсом. Единственное решение для него — закрыть вкладку и найти нужную информацию на другом сайте. Так количество посетителей сайта постепенно уменьшается, он перестает попадать в поисковую выдачу — в результате ресурс становится бесполезным и пропадает в пучине Интернета.
Как проверить ошибки валидации
Владельцы ресурсов используют 2 способа онлайн-проверки сайтов на наличие ошибок — технический аудит или использование валидаторов.
Первый случай подходит для серьёзных проблем и масштабных сайтов. Валидаторами же пользуются ежедневно. Наиболее популярный — сервис The W3C Markup Validation Service. Он сканирует сайт и сравнивает код на соответствие стандартам W3C. Валидатор выдаёт 2 типа несоответствий разметки стандартам W3C: предупреждения и ошибки.
Давайте рассмотрим каждый из типов чуть подробнее.
Предупреждения
Предупреждения отмечают незначительные проблемы, которые не влияют на работу ресурса. Они появляются из-за расхождений написания разметки со стандартами W3C.
Тем не менее, предупреждения всё равно нужно устранять, так как из-за них сайт может работать медленнее — например, по сравнению с конкурентами с такими же сайтами.
Примером предупреждения может быть указание на отсутствие тега alt у изображения.
Ошибки
Ошибки — это те проблемы, которые требуют обязательного устранения.
Они представляют угрозу для корректной работы сайта: например, из-за них могут скрываться разные блоки — текстовые, фото, видео. А в некоторых более запущенных случаях содержимое страницы может вовсе не отображаться, и сам ресурс не будет загружаться. Поэтому после проверки уделять внимание ошибкам с красными отметками нужно в первую очередь.
Распространённым примером ошибки может быть отсутствие тега <!DOCTYPE html> в начале страницы, который помогает информации преобразоваться в разметку.
Пример прохождения валидации для страницы сайта
Рассмотрим процесс валидации на примере сайта avavax.ru, который создали на WordPress.
В результате проверки валидатор выдал 17 замечаний. После анализа отчета их можно свести к 3 основным:
- атрибут ‘text/javascript’ не требуется при подключении скрипта;
- атрибут ‘text/css’ не требуется при подключении стиля;
- у одного из элементов section нет внутри заголовка h1-h6.
Первое и второе замечания генерирует сам движок WordPress, поэтому разработчикам не нужно их убирать. Третье же замечание предполагает, что каждый блок текста должен иметь заголовок, даже если это не всегда необходимо или видно для читателя.
Решить проблемы с предупреждениями для стилей и скриптов можно через добавление кода в файл темы function.php.
Для этого на хук wp_loaded нужно повесить функцию output_buffer_start(), которая загрузит весь генерируемый код html в буфер. При выводе в буфер вызывается функция output_callback($tag), которая просматривает все теги, находит нежелательные атрибуты с помощью регулярных выражений и заменяет их пробелами. Затем на хук ‘shutdown вешается функция output_buffer_end(), которая возвращает обработанное содержимое буфера.
Для исправления семантики на сайте нужно использовать заголовки. Валидатор выдаёт предупреждение на секцию about, которая содержит фото и краткий текст. Валидатор требует, чтобы в каждой секции был заголовок. Для исправления предупреждения нужно добавить заголовок, но сделать это так, чтобы его не было видно пользователям:
- Добавить заголовок в код: <h3>Обо мне</h3>
Отключить отображение заголовка:
1 #about h3 {
2 display: none;
3 }
После этой части заголовок будет в коде, но валидатор его увидит, а посетитель — нет.
За 3 действия удалось убрать все предупреждения, чтобы качество кода устроило валидатор. Это подтверждается зелёной строкой с надписью: “Document checking completed. No errors or warnings to show”.
Как исправить ошибку валидации
Всё зависит от того, какими техническими знаниями обладает владелец ресурса. Он может сделать это сам, вручную. Делать это нужно постепенно, разбирая ошибку за ошибкой. Но нужно понимать, что если при проверке валидатором было выявлено 100 проблем — все 100 нужно обязательно решить.
Поэтому если навыков и знаний не хватает, лучше привлечь сторонних специалистов для улучшения качества разметки. Это могут быть как фрилансеры, так и профессиональные веб-агентства. При выборе хорошего специалиста, результат будет гарантироваться в любом случае, но лучше, чтобы в договоре оказания услуг будут чётко прописаны цели проведения аудита и гарантии решения проблем с сайтом.
Если объём работ большой, выгоднее заказать профессиональный аудит сайта. С его помощью можно обнаружить разные виды ошибок, улучшить внешний вид и привлекательность интернет-ресурса для поисковых ботов, обычных пользователей, а также повысить скорость загрузки страниц, сделать качественную верстку и избавиться от переспама.
Плагины для браузеров, которые помогут найти ошибки в коде
Для поиска ошибок валидации можно использовать и встроенные в браузеры плагины. Они помогут быстро находить неточности еще на этапе создания кода.
Для каждого браузера есть свой адаптивный плагин:
- HTML Validator для браузера Firefox;
- HTML Validator for Chrome;
- HTML5 Editor для Opera.
С помощью этих инструментов можно не допускать проблем, которые помешают нормальному запуску сайта. Плагины помогут оценить качество внешней и внутренней оптимизации, контента и другие характеристики.
Коротко о главном
Валидация — процесс выявления проблем с HTML-разметкой сайта и ее соответствия стандартам W3C. Это унифицированные правила, с помощью которых сайт может нормально работать и отображаться и для поисковых роботов, и для пользователей.
Проверку ресурса можно проводить тремя путями: валидаторами, специалистам полномасштабного аудита и плагинами в браузере. В большинстве случаев валидатор — самое удобное и быстрое решение для поиска проблем. С его помощью можно выявить 2 типа проблем с разметкой — предупреждения и ошибки.
Работать необходимо сразу с двумя типами ошибок. Даже если предупреждение не приведет к неисправности сайта, оставлять без внимания проблемные блоки нельзя, так как это снизит привлекательность ресурса в глазах пользователя. Ошибки же могут привести к невозможности отображения блоков на сайте, понижению сайта в поисковой выдаче или полному игнорированию ресурса со стороны поискового бота.
Даже у крупных сайтов с миллионной аудиторией, например, Яндекс.Дзен или ВКонтакте, есть проблемы с кодом. Но комплексный подход к решению проблем помогает устранять серьёзные моменты своевременно. Нужно развивать сайт всесторонне, чтобы получить результат от его существования и поддержки. Если самостоятельно разобраться с проблемами не получается, не стоит “доламывать” — лучше обратиться за помощью к профессионалам, например, агентствам по веб-аудиту.
Here’s another interesting scenario to discuss.
What if its an type detection API that for instance accepts as input a reference to some locally stored parquet file, and after reading through some metadata of the blocks that compose the file, may realize that one or more of the block sizes exceed a configured threshold and therefor the server decided the file is not partitioning correctly and refuses to start the type detection process.
This validation is there to protect against one of two (or both) scenarios: (1) Long processing time, bad user experience ; (2) Server application explodes with OutOfMemoryError
What would be an appropriate response in this case?
400 (Bad Request) ? — sort of works, generically.
401 (Unauthorized i.e. Unauthenticated) ? — unrelated.
403 (Forbidden i.e. Unauthorized) ? — some would argue it may be somewhat appropriate in this case —
422 (Unprocessable entity) ? — many older answers mention this as appropriate option for input validation failure. What bothers me about using it in my case is the definition of this response code saying its «due to semantic error» while I couldn’t quite understand what semantic error means in that context and whether can we consider this failure indeed as a semantic error failure.
Also the allegedly simple concept of «input» as part of «input validation» can be confusing in cases like this where the physical input provided by the client is only but a pointer, a reference to some entity which is stored in the server, where the actual validation is done on data stored in the server (the parquet file metadata) in conjunction with the action the client tries to trigger (type detection).
413 (PayloadTooLarge)? Going through the different codes I encounter one that may be suitable in my case, one that no one mentioned here so far, that is 413 PayloadTooLarge which I also wonder if it may be suitable or again, not, since its not the actual payload sent in the request that is too large, but the payload of the resource stored in the server.
Which leads me to thinking maybe a 5xx response is more appropriate here.
507 Insufficient Storage ? If we say that «storage» is like «memory» and if we also say that we’re failing fast here with a claim that we don’t have enough memory (or we may blow out with out of memory trying) to process this job, then maybe 507 can me appropriate. but not really.
My conclusion is that in this type of scenario where the server refused to invoke an action on a resource due to space-time related constraints the most suitable response would be 413 PayloadTooLarge
Here’s another interesting scenario to discuss.
What if its an type detection API that for instance accepts as input a reference to some locally stored parquet file, and after reading through some metadata of the blocks that compose the file, may realize that one or more of the block sizes exceed a configured threshold and therefor the server decided the file is not partitioning correctly and refuses to start the type detection process.
This validation is there to protect against one of two (or both) scenarios: (1) Long processing time, bad user experience ; (2) Server application explodes with OutOfMemoryError
What would be an appropriate response in this case?
400 (Bad Request) ? — sort of works, generically.
401 (Unauthorized i.e. Unauthenticated) ? — unrelated.
403 (Forbidden i.e. Unauthorized) ? — some would argue it may be somewhat appropriate in this case —
422 (Unprocessable entity) ? — many older answers mention this as appropriate option for input validation failure. What bothers me about using it in my case is the definition of this response code saying its «due to semantic error» while I couldn’t quite understand what semantic error means in that context and whether can we consider this failure indeed as a semantic error failure.
Also the allegedly simple concept of «input» as part of «input validation» can be confusing in cases like this where the physical input provided by the client is only but a pointer, a reference to some entity which is stored in the server, where the actual validation is done on data stored in the server (the parquet file metadata) in conjunction with the action the client tries to trigger (type detection).
413 (PayloadTooLarge)? Going through the different codes I encounter one that may be suitable in my case, one that no one mentioned here so far, that is 413 PayloadTooLarge which I also wonder if it may be suitable or again, not, since its not the actual payload sent in the request that is too large, but the payload of the resource stored in the server.
Which leads me to thinking maybe a 5xx response is more appropriate here.
507 Insufficient Storage ? If we say that «storage» is like «memory» and if we also say that we’re failing fast here with a claim that we don’t have enough memory (or we may blow out with out of memory trying) to process this job, then maybe 507 can me appropriate. but not really.
My conclusion is that in this type of scenario where the server refused to invoke an action on a resource due to space-time related constraints the most suitable response would be 413 PayloadTooLarge
Содержание
Составили подробный классификатор кодов состояния HTTP. Добавляйте в закладки, чтобы был под рукой, когда понадобится.
Что такое код ответа HTTP
Когда посетитель переходит по ссылке на сайт или вбивает её в поисковую строку вручную, отправляется запрос на сервер. Сервер обрабатывает этот запрос и выдаёт ответ — трехзначный цифровой код HTTP от 100 до 510. По коду ответа можно понять реакцию сервера на запрос.
Первая цифра в ответе обозначает класс состояния, другие две — причину, по которой мог появиться такой ответ.
Как проверить код состояния страницы
Проверить коды ответа сервера можно вручную с помощью браузера и в панелях веб‑мастеров: Яндекс.Вебмастер и Google Search Console.
В браузере
Для примера возьмём Google Chrome.
-
Откройте панель разработчика в браузере клавишей F12, комбинацией клавиш Ctrl + Shift + I или в меню браузера → «Дополнительные инструменты» → «Инструменты разработчика». Подробнее об этом рассказывали в статье «Как открыть исходный код страницы».
-
Переключитесь на вкладку «Сеть» в Инструментах разработчика и обновите страницу:
В Яндекс.Вебмастере
Откройте инструмент «Проверка ответа сервера» в Вебмастере. Введите URL в специальное поле и нажмите кнопку «Проверить»:
Как добавить сайт в Яндекс.Вебмастер и другие сервисы Яндекса
В Google Search Console
Чтобы посмотреть код ответа сервера в GSC, перейдите в инструмент проверки URL — он находится в самом верху панели:
Введите ссылку на страницу, которую хотите проверить, и нажмите Enter. В результатах проверки нажмите на «Изучить просканированную страницу» в блоке «URL есть в индексе Google».
А затем в открывшемся окне перейдите на вкладку «Подробнее»:
Теперь расскажем подробнее про все классы кодов состояния HTTP.
1* класс кодов (информационные сообщения)
Это системный класс кодов, который только информирует о процессе передачи запроса. Такие ответы не являются ошибкой, хотя и могут отображаться в браузере как Error Code.
100 Continue
Этот ответ сообщает, что полученные сведения о запросе устраивают сервер и клиент может продолжать отправлять данные. Такой ответ может требоваться клиенту, если на сервер отправляется большой объём данных.
101 Switching Protocols
Сервер одобрил переключение типа протокола, которое запросил пользователь, и в настоящий момент выполняет действие.
102 Processing
Запрос принят — он находится в обработке, и на это понадобится чуть больше времени.
103 Checkpoint
Контрольная точка — используется в запросах для возобновления после прерывания запросов POST или PUT.
POST отправляет данные на сервер, PUT создает новый ресурс или заменяет существующий данными, представленными в теле запроса.
Разница между ними в том, что PUT работает без изменений: повторное его применение даёт такой же результат, что и в первый раз, а вот повторный вызов одного и того же метода POST часто меняет данные.
Пример — оформленный несколько раз интернет‑заказ. Такое часто происходит как раз по причине неоднократного использования запроса PUT.
105 Name Not Resolved
Не удается преобразовать DNS‑адрес сервера — это означает ошибку в службе DNS. Эта служба преобразует IP‑адреса в знакомые нам доменные имена.
2* класс кодов (успешно обработанные запросы)
Эти коды информируют об успешности принятия и обработки запроса. Также сервер может передать заголовки или тело сообщений.
200 ОК
Все хорошо — HTTP‑запрос успешно обработан (не ошибка).
201 Created
Создано — транзакция успешна, сформирован новый ресурс или документ.
202 Accepted
Принято — запрос принят, но ещё не обработан.
203 Non‑Authoritative Information
Информация не авторитетна — запрос успешно обработан, но передаваемая информация была взята не из первичного источника (данные могут быть устаревшими).
204 No Content
Нет содержимого — запрос успешно обработан, однако в ответе только заголовки без контента сообщения. Не нужно обновлять содержимое документа, но можно применить к нему полученные метаданные.
205 Reset Content
Сбросить содержимое. Запрос успешно обработан — но нужно сбросить введенные данные. Страницу можно не обновлять.
206 Partial Content
Частичное содержимое. Сервер успешно обработал часть GET‑запроса, а другую часть вернул.
GET — метод для чтения данных с сайта. Он говорит серверу, что клиент хочет прочитать какой‑то документ.
Представим интернет‑магазин и страницы каталога. Фильтры, которые выбирает пользователь, передаются благодаря методу GET. GET‑запрос работает с получением данных, а POST‑запрос нужен для отправки данных.
При работе с подобными ответами следует уделить внимание кэшированию.
207 Multi‑Status
Успешно выполнено несколько операций — сервер передал результаты выполнения нескольких независимых операций. Они появятся в виде XML‑документа с объектом multistatus.
226 IM Used
Успешно обработан IM‑заголовок (специальный заголовок, который отправляется клиентом и используется для передачи состояния HTTP).
3* класс кодов (перенаправление на другой адрес)
Эти коды информируют, что для достижения успешной операции нужно будет сделать другой запрос, возможно, по другому URL.
300 Multiple Choices
Множественный выбор — сервер выдает список нескольких возможных вариантов перенаправления (максимум — 5). Можно выбрать один из них.
301 Moved Permanently
Окончательно перемещено — страница перемещена на другой URL, который указан в поле Location.
302 Found/Moved
Временно перемещено — страница временно перенесена на другой URL, который указан в поле Location.
303 See Other
Ищите другую страницу — страница не найдена по данному URL, поэтому смотрите страницу по другому URL, используя метод GET.
304 Not Modified
Модификаций не было — с момента последнего визита клиента изменений не было.
305 Use Proxy
Используйте прокси — запрос к нужному ресурсу можно сделать только через прокси‑сервер, URL которого указан в поле Location заголовка.
306 Unused
Зарезервировано. Код в настоящий момент не используется.
307 Temporary Redirect
Временное перенаправление — запрашиваемый ресурс временно доступен по другому URL.
Этот код имеет ту же семантику, что код ответа 302 Found, за исключением того, что агент пользователя не должен изменять используемый метод HTTP: если в первом запросе использовался POST, то во втором запросе также должен использоваться POST.
308 Resume Incomplete
Перемещено полностью (навсегда) — запрашиваемая страница была перенесена на новый URL, указанный в поле Location заголовка. Метод запроса (GET/POST) менять не разрешается.
4* класс кодов (ошибки на стороне клиента)
Эти коды указывают на ошибки со стороны клиентов.
400 Bad Request
Неверный запрос — запрос клиента не может быть обработан, так как есть синтаксическая ошибка (возможно, опечатка).
401 Unauthorized
Не пройдена авторизация — запрос ещё в обработке, но доступа нет, так как пользователь не авторизован.
Для доступа к запрашиваемому ресурсу клиент должен представиться, послав запрос, включив при этом в заголовок сообщения поле Authorization.
402 Payment Required
Требуется оплата — зарезервировано для использования в будущем. Код предусмотрен для платных пользовательских сервисов, а не для хостинговых компаний.
403 Forbidden
Запрещено — запрос принят, но не будет обработан, так как у клиента недостаточно прав. Может возникнуть, когда пользователь хочет открыть системные файлы (robots, htaccess) или не прошёл авторизацию.
404 Not Found
Не найдено — запрашиваемая страница не обнаружена. Сервер принял запрос, но не нашёл ресурса по указанному URL (возможно, была ошибка в URL или страница была перемещена).
405 Method Not Allowed
Метод не разрешён — запрос был сделан методом, который не поддерживается данным ресурсом. Сервер должен предложить доступные методы решения в заголовке Allow.
406 Not Acceptable
Некорректный запрос — неподдерживаемый поисковиком формат запроса (поисковый робот не поддерживает кодировку или язык).
407 Proxy Authentication Required
Нужно пройти аутентификацию прокси — ответ аналогичен коду 401, только нужно аутентифицировать прокси‑сервер.
408 Request Timeout
Тайм‑аут запроса — запрос клиента занял слишком много времени. На каждом сайте существует свое время тайм‑аута — проверьте интернет‑соединение и просто обновите страницу.
409 Conflict
Конфликт (что‑то пошло не так) — запрос не может быть выполнен из‑за конфликтного обращения к ресурсу (несовместимость двух запросов).
410 Gone
Недоступно — ресурс раньше был размещён по указанному URL, но сейчас удалён и недоступен (серверу неизвестно месторасположение).
411 Length Required
Добавьте длины — сервер отклоняет отправляемый запрос, так как длина заголовка не определена, и он не находит значение Content‑Length.
Нужно исправить заголовки на сервере, и в следующий раз робот сможет проиндексировать страницу.
412 Precondition Failed
Предварительное условие не выполнено — стоит проверить правильность HTTP‑заголовков данного запроса.
413 Request Entity Too Large
Превышен размер запроса — перелимит максимального размера запроса, принимаемого сервером. Браузеры поддерживают запросы от 2 до 8 килобайт.
414 Request‑URI Too Long
Превышена длина запроса — сервер не может обработать запрос из‑за длинного URL. Такая ошибка может возникнуть, например, когда клиент пытается передать чересчур длинные параметры через метод GET, а не POST.
415 Unsupported Media Type
Формат не поддерживается — сервер не может принять запрос, так как данные подгружаются в некорректном формате, и сервер разрывает соединение.
416 Requested Range Not Satisfiable
Диапазон не поддерживается — ошибка возникает в случаях, когда в самом HTTP‑заголовке прописывается некорректный байтовый диапазон.
Корректного диапазона в необходимом документе может просто не быть, или есть опечатка в синтаксисе.
417 Expectation Failed
Ожидания не оправдались — прокси некорректно идентифицировал содержимое поля «Expect: 100‑Continue».
418 I’m a teapot
Первоапрельская шутка разработчиков в 1998 году. В расшифровке звучит как «я не приготовлю вам кофе, потому что я чайник». Не используется в работе.
422 Unprocessable Entity
Объект не обработан — сервер принял запрос, но в нём есть логическая ошибка. Стоит посмотреть в сторону семантики сайта.
423 Locked
Закрыто — ресурс заблокирован для выбранного HTTP‑метода. Можно перезагрузить роутер и компьютер. А также использовать только статистический IP.
424 Failed Dependency
Неуспешная зависимость — сервер не может обработать запрос, так как один из зависимых ресурсов заблокирован.
Выполнение запроса напрямую зависит от успешности выполнения другой операции, и если она не будет успешно завершена, то вся обработка запроса будет прервана.
425 Unordered Collection
Неверный порядок в коллекции — ошибка возникает, если клиент указал номер элемента в неупорядоченном списке или запросил несколько элементов в порядке, отличном от серверного.
426 Upgrade Required
Нужно обновление — в заголовке ответа нужно корректно сформировать поля Upgrade и Connection.
Этот ответ возникает, когда серверу требуется обновление до SSL‑протокола, но клиент не имеет его поддержки.
428 Precondition Required
Нужно предварительное условие — сервер просит внести в запрос информацию о предварительных условиях обработки данных, чтобы выдавать корректную информацию по итогу.
429 Too Many Requests
Слишком много запросов — отправлено слишком много запросов за короткое время. Это может указывать, например, на попытку DDoS‑атаки, для защиты от которой запросы блокируются.
431 Request Header Fields Too Large
Превышена длина заголовков — сервер может и не отвечать этим кодом, вместо этого он может просто сбросить соединение.
Исправляется это с помощью сокращения заголовков и повторной отправки запроса.
434 Requested Host Unavailable
Адрес запрашиваемой страницы недоступен.
444 No Response
Нет ответа — код отображается в лог‑файлах, чтобы подтвердить, что сервер никак не отреагировал на запрос пользователя и прервал соединение. Возвращается только сервером nginx.
Nginx — программное обеспечение с открытым исходным кодом. Его используют для создания веб‑серверов, а также в качестве почтового или обратного прокси‑сервера. Nginx решает проблему падения производительности из‑за роста трафика.
449 Retry With
Повторите попытку — ошибка говорит о необходимости скорректировать запрос и повторить его снова. Причиной становятся неверно указанные параметры (возможно, недостаточно данных).
450 Blocked by Windows Parental Controls
Заблокировано родительским контролем — говорит о том, что с компьютера попытались зайти на заблокированный ресурс. Избежать этой ошибки можно изменением параметров системы родительского контроля.
451 Unavailable For Legal Reasons
Недоступно по юридическим причинам — доступ к ресурсу закрыт, например, по требованию органов государственной власти или по требованию правообладателя в случае нарушения авторских прав.
456 Unrecoverable Error
Неустранимая ошибка — при обработке запроса возникла ошибка, которая вызывает некорректируемые сбои в таблицах баз данных.
499 Client Closed Request
Запрос закрыт клиентом — нестандартный код, используемый nginx в ситуациях, когда клиент закрыл соединение, пока nginx обрабатывал запрос.
5* класс кодов (ошибки на стороне сервера)
Эти коды указывают на ошибки со стороны серверов.
При использовании всех методов, кроме HEAD, сервер должен вернуть в теле сообщения гипертекстовое пояснение для пользователя. И его можно использовать в работе.
500 Internal Server Error
Внутренняя ошибка сервера — сервер столкнулся с неким условием, из‑за которого не может выполнить запрос.
Проверяйте, корректно ли указаны директивы в системных файлах (особенно htaccess) и нет ли ошибки прав доступа к файлам. Обратите внимание на ошибки внутри скриптов и их медленную работу.
501 Not Implemented
Не выполнено — код отдается, когда сам сервер не может идентифицировать метод запроса.
Сами вы эту ошибку не исправите. Устранить её может только сервер.
502 Bad Gateway
Ошибка шлюза — появляется, когда сервер, выступая в роли шлюза или прокси‑сервера, получил ответное сообщение от вышестоящего сервера о несоответствии протоколов.
Актуально исключительно для прокси и шлюзовых конфигураций.
503 Service Unavailable
Временно не доступен — сервер временно не имеет возможности обрабатывать запросы по техническим причинам (обслуживание, перегрузка и прочее).
В поле Retry‑After заголовка сервер укажет время, через которое можно повторить запрос.
504 Gateway Timeout
Тайм‑аут шлюза — сервер, выступая в роли шлюза или прокси‑сервера, не получил ответа от вышестоящего сервера в нужное время.
Исправить эту ошибку самостоятельно не получится. Здесь дело в прокси, часто — в веб‑сервере.
Первым делом просто обновите веб‑страницу. Если это не помогло, нужно почистить DNS‑кэш. Для этого нажмите горячие клавиши Windows+R и введите команду cmd (Control+пробел). В открывшемся окне укажите команду ipconfig / flushdns и подтвердите её нажатием Enter.
505 HTTP Version Not Supported
Сервер не поддерживает версию протокола — отсутствует поддержка текущей версии HTTP‑протокола. Нужно обеспечить клиента и сервер одинаковой версией.
506 Variant Also Negotiates
Неуспешные переговоры — с такой ошибкой сталкиваются, если сервер изначально настроен неправильно. По причине ошибочной конфигурации выбранный вариант указывает сам на себя, из‑за чего процесс и прерывается.
507 Insufficient Storage
Не хватает места для хранения — серверу недостаточно места в хранилище. Нужно либо расчистить место, либо увеличить доступное пространство.
508 Loop Detected
Обнаружен цикл — ошибка означает провал запроса и выполняемой операции в целом.
509 Bandwidth Limit Exceeded
Превышена пропускная способность — используется при чрезмерном потреблении трафика. Владельцу площадки следует обратиться к своему хостинг‑провайдеру.
510 Not Extended
Не продлён — ошибка говорит, что на сервере отсутствует нужное для клиента расширение. Чтобы исправить проблему, надо убрать часть неподдерживаемого расширения из запроса или добавить поддержку на сервер.
511 Network Authentication Required
Требуется аутентификация — ошибка генерируется сервером‑посредником, к примеру, сервером интернет‑провайдера, если нужно ввести пароль для получения доступа к сети через платную точку доступа.
Просмотров 8.7к. Опубликовано 19.12.2022
Обновлено 19.12.2022
Каждый сайт, который создает компания, должен отвечать принятым стандартам. В первую очередь затем, чтобы он попадал в поисковую выдачу и был удобен для пользователей. Если код страниц содержит ошибки, неточности, он становится “невалидным”, то есть не соответствующим требованиям. В результате интернет-ресурс не увидят пользователи или информация на нем будет отображаться некорректно.
В этой статье рассмотрим, что такое валидность, какие могут быть ошибки в HTML-разметке и как их устранить.
Содержание
- Что такое HTML-ошибка валидации и зачем она нужна
- Чем опасны ошибки в разметке
- Как проверить ошибки валидации
- Предупреждения
- Ошибки
- Пример прохождения валидации для страницы сайта
- Как исправить ошибку валидации
- Плагины для браузеров, которые помогут найти ошибки в коде
- Коротко о главном
Что такое HTML-ошибка валидации и зачем она нужна
Под понятием “валидация” подразумевается процесс онлайн-проверки HTML-кода страницы на соответствие стандартам w3c. Эти стандарты были разработаны Организацией всемирной паутины и стандартов качества разметки. Сама организация продвигает идею унификации сайтов по HTML-коду — чтобы каждому пользователю, вне зависимости от браузера или устройства, было удобно использовать ресурс.
Если код отвечает стандартам, то его называют валидным. Браузеры могут его прочитать, загрузить страницы, а поисковые системы легко находят страницу по соответствующему запросу.
Чем опасны ошибки в разметке
Ошибки валидации могут разными — видимыми для глаза простого пользователя или такими, которые можно засечь только с помощью специальных программ. В первом случае кроме технических проблем, ошибки в разметке приводят к негативному пользовательскому опыту.
К наиболее распространённым последствиям ошибок в коде HTML-разметки также относят сбои в нормальной работе сайта и помехи в продвижении ресурса в поисковых системах.
Рассмотрим несколько примеров, как ошибки могут проявляться при работе:
- Медленно подгружается страница
Согласно исследованию Unbounce, более четверти пользователей покидают страницу, если её загрузка занимает более 3 секунд, ещё треть уходит после 6 секунд;
- Не видна часть текстовых, фото и видео-блоков
Эта проблема делает контент для пользователей неинформативным, поэтому они в большинстве случаев уходят со страницы, не досмотрев её до конца;
- Страница может остаться не проиндексированной
Если поисковый робот распознает недочёт в разметке, он может пропустить страницу и прервать её размещение в поисковых системах;
- Разное отображение страниц на разных устройствах
Например, на компьютере или ноутбуке страница будет выглядеть хорошо, а на мобильных гаджетах половина кнопок и изображений будет попросту не видна.
Из-за этих ошибок пользователь не сможет нормально работать с ресурсом. Единственное решение для него — закрыть вкладку и найти нужную информацию на другом сайте. Так количество посетителей сайта постепенно уменьшается, он перестает попадать в поисковую выдачу — в результате ресурс становится бесполезным и пропадает в пучине Интернета.
Как проверить ошибки валидации
Владельцы ресурсов используют 2 способа онлайн-проверки сайтов на наличие ошибок — технический аудит или использование валидаторов.
Первый случай подходит для серьёзных проблем и масштабных сайтов. Валидаторами же пользуются ежедневно. Наиболее популярный — сервис The W3C Markup Validation Service. Он сканирует сайт и сравнивает код на соответствие стандартам W3C. Валидатор выдаёт 2 типа несоответствий разметки стандартам W3C: предупреждения и ошибки.
Давайте рассмотрим каждый из типов чуть подробнее.
Предупреждения
Предупреждения отмечают незначительные проблемы, которые не влияют на работу ресурса. Они появляются из-за расхождений написания разметки со стандартами W3C.
Тем не менее, предупреждения всё равно нужно устранять, так как из-за них сайт может работать медленнее — например, по сравнению с конкурентами с такими же сайтами.
Примером предупреждения может быть указание на отсутствие тега alt у изображения.
Ошибки
Ошибки — это те проблемы, которые требуют обязательного устранения.
Они представляют угрозу для корректной работы сайта: например, из-за них могут скрываться разные блоки — текстовые, фото, видео. А в некоторых более запущенных случаях содержимое страницы может вовсе не отображаться, и сам ресурс не будет загружаться. Поэтому после проверки уделять внимание ошибкам с красными отметками нужно в первую очередь.
Распространённым примером ошибки может быть отсутствие тега <!DOCTYPE html> в начале страницы, который помогает информации преобразоваться в разметку.
Пример прохождения валидации для страницы сайта
Рассмотрим процесс валидации на примере сайта avavax.ru, который создали на WordPress.
В результате проверки валидатор выдал 17 замечаний. После анализа отчета их можно свести к 3 основным:
- атрибут ‘text/javascript’ не требуется при подключении скрипта;
- атрибут ‘text/css’ не требуется при подключении стиля;
- у одного из элементов section нет внутри заголовка h1-h6.
Первое и второе замечания генерирует сам движок WordPress, поэтому разработчикам не нужно их убирать. Третье же замечание предполагает, что каждый блок текста должен иметь заголовок, даже если это не всегда необходимо или видно для читателя.
Решить проблемы с предупреждениями для стилей и скриптов можно через добавление кода в файл темы function.php.

Для этого на хук wp_loaded нужно повесить функцию output_buffer_start(), которая загрузит весь генерируемый код html в буфер. При выводе в буфер вызывается функция output_callback($tag), которая просматривает все теги, находит нежелательные атрибуты с помощью регулярных выражений и заменяет их пробелами. Затем на хук ‘shutdown вешается функция output_buffer_end(), которая возвращает обработанное содержимое буфера.
Для исправления семантики на сайте нужно использовать заголовки. Валидатор выдаёт предупреждение на секцию about, которая содержит фото и краткий текст. Валидатор требует, чтобы в каждой секции был заголовок. Для исправления предупреждения нужно добавить заголовок, но сделать это так, чтобы его не было видно пользователям:
- Добавить заголовок в код: <h3>Обо мне</h3>
Отключить отображение заголовка:
1 #about h3 {
2 display: none;
3 }
После этой части заголовок будет в коде, но валидатор его увидит, а посетитель — нет.
За 3 действия удалось убрать все предупреждения, чтобы качество кода устроило валидатор. Это подтверждается зелёной строкой с надписью: “Document checking completed. No errors or warnings to show”.
Как исправить ошибку валидации
Всё зависит от того, какими техническими знаниями обладает владелец ресурса. Он может сделать это сам, вручную. Делать это нужно постепенно, разбирая ошибку за ошибкой. Но нужно понимать, что если при проверке валидатором было выявлено 100 проблем — все 100 нужно обязательно решить.
Поэтому если навыков и знаний не хватает, лучше привлечь сторонних специалистов для улучшения качества разметки. Это могут быть как фрилансеры, так и профессиональные веб-агентства. При выборе хорошего специалиста, результат будет гарантироваться в любом случае, но лучше, чтобы в договоре оказания услуг будут чётко прописаны цели проведения аудита и гарантии решения проблем с сайтом.
Если объём работ большой, выгоднее заказать профессиональный аудит сайта. С его помощью можно обнаружить разные виды ошибок, улучшить внешний вид и привлекательность интернет-ресурса для поисковых ботов, обычных пользователей, а также повысить скорость загрузки страниц, сделать качественную верстку и избавиться от переспама.
Плагины для браузеров, которые помогут найти ошибки в коде
Для поиска ошибок валидации можно использовать и встроенные в браузеры плагины. Они помогут быстро находить неточности еще на этапе создания кода.
Для каждого браузера есть свой адаптивный плагин:
- HTML Validator для браузера Firefox;
- HTML Validator for Chrome;
- HTML5 Editor для Opera.
С помощью этих инструментов можно не допускать проблем, которые помешают нормальному запуску сайта. Плагины помогут оценить качество внешней и внутренней оптимизации, контента и другие характеристики.
Коротко о главном
Валидация — процесс выявления проблем с HTML-разметкой сайта и ее соответствия стандартам W3C. Это унифицированные правила, с помощью которых сайт может нормально работать и отображаться и для поисковых роботов, и для пользователей.
Проверку ресурса можно проводить тремя путями: валидаторами, специалистам полномасштабного аудита и плагинами в браузере. В большинстве случаев валидатор — самое удобное и быстрое решение для поиска проблем. С его помощью можно выявить 2 типа проблем с разметкой — предупреждения и ошибки.
Работать необходимо сразу с двумя типами ошибок. Даже если предупреждение не приведет к неисправности сайта, оставлять без внимания проблемные блоки нельзя, так как это снизит привлекательность ресурса в глазах пользователя. Ошибки же могут привести к невозможности отображения блоков на сайте, понижению сайта в поисковой выдаче или полному игнорированию ресурса со стороны поискового бота.
Даже у крупных сайтов с миллионной аудиторией, например, Яндекс.Дзен или ВКонтакте, есть проблемы с кодом. Но комплексный подход к решению проблем помогает устранять серьёзные моменты своевременно. Нужно развивать сайт всесторонне, чтобы получить результат от его существования и поддержки. Если самостоятельно разобраться с проблемами не получается, не стоит “доламывать” — лучше обратиться за помощью к профессионалам, например, агентствам по веб-аудиту.
200
Ugh… (309, 400, 403, 409, 415, 422)… a lot of answers trying to guess, argue and standardize what is the best return code for a successful HTTP request but a failed REST call.
It is wrong to mix HTTP status codes and REST status codes.
However, I saw many implementations mixing them, and many developers may not agree with me.
HTTP return codes are related to the HTTP Request itself. A REST call is done using a Hypertext Transfer Protocol request and it works at a lower level than invoked REST method itself. REST is a concept/approach, and its output is a business/logical result, while HTTP result code is a transport one.
For example, returning «404 Not found» when you call /users/ is confuse, because it may mean:
- URI is wrong (HTTP)
- No users are found (REST)
«403 Forbidden/Access Denied» may mean:
- Special permission needed. Browsers can handle it by asking the user/password. (HTTP)
- Wrong access permissions configured on the server. (HTTP)
- You need to be authenticated (REST)
And the list may continue with ‘500 Server error» (an Apache/Nginx HTTP thrown error or a business constraint error in REST) or other HTTP errors etc…
From the code, it’s hard to understand what was the failure reason, a HTTP (transport) failure or a REST (logical) failure.
If the HTTP request physically was performed successfully it should always return 200 code, regardless is the record(s) found or not. Because URI resource is found and was handled by the HTTP server. Yes, it may return an empty set. Is it possible to receive an empty web-page with 200 as HTTP result, right?
Instead of this you may return 200 HTTP code with some options:
- «error» object in JSON result if something goes wrong
- Empty JSON array/object if no record found
- A bool result/success flag in combination with previous options for a better handling.
Also, some internet providers may intercept your requests and return you a 404 HTTP code. This does not means that your data are not found, but it’s something wrong at transport level.
From Wiki:
In July 2004, the UK telecom provider BT Group deployed the Cleanfeed
content blocking system, which returns a 404 error to any request for
content identified as potentially illegal by the Internet Watch
Foundation. Other ISPs return a HTTP 403 «forbidden» error in the same
circumstances. The practice of employing fake 404 errors as a means to
conceal censorship has also been reported in Thailand and Tunisia. In
Tunisia, where censorship was severe before the 2011 revolution,
people became aware of the nature of the fake 404 errors and created
an imaginary character named «Ammar 404» who represents «the invisible
censor».
Why not simply answer with something like this?
{
"result": false,
"error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}
Google always returns 200 as status code in their Geocoding API, even if the request logically fails: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes
Facebook always return 200 for successful HTTP requests, even if REST request fails: https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling
It’s simple, HTTP status codes are for HTTP requests. REST API is Your, define Your status codes.
Наличие ошибок в коде страницы сайта всегда влечет за собой негативные последствия – от ухудшения позиций в ранжировании до жалоб со стороны пользователей. Ошибки валидации могут наблюдаться как на главной, так и на иных веб-страницах, их наличие свидетельствует о том, что ресурс является невалидным. Некоторые проблемы замечают даже неподготовленные пользователи, другие невозможно обнаружить без предварительного аудита, анализа. О том, что такое ошибки валидации и как их обнаружить, мы сейчас расскажем.

Ошибка валидации, что это такое?
Для написания страниц используется HTML – стандартизированный язык разметки, применяемый в веб-разработке. HTML, как любой другой язык, имеет специфические особенности синтаксиса, грамматики и т. д. Если во время написания кода правила не учитываются, то после запуска сайта будут появляться различные виды проблем. Если HTML-код ресурса не соответствует стандарту W3C, то он является невалидным, о чем мы писали выше.
Почему ошибки валидации сайта оказывают влияние на ранжирование, восприятие?
Наличие погрешностей в коде – проблема, с которой необходимо бороться сразу после обнаружения. Поисковые системы «читают» HTML-код, если он некорректный, то процесс индексации и ранжирования может быть затруднен. Поисковые роботы должны понимать, каким является ресурс, что он предлагает, какие запросы использует. Особо критичны такие ситуации для ресурсов, имеющих большое количество веб-страниц.
Как проверить ошибки валидации?
Для этой работы используется либо технический аудит сайта, либо валидаторы, которые ищут проблемы автоматически. Одним из самых популярных является сервис The W3C Markup Validation Service, выполняющий сканирование с оглядкой на World Wide Web Consortium (W3C). Рассматриваемый валидатор предлагает три способа, с помощью которых можно осуществить проверку сайта:
- ввод URL-адреса страниц, которые необходимо просканировать;
- загрузка файла страницы;
- ввод части HTML-кода, нуждающегося в проверке.
После завершения проверки вы получите развернутый список выявленных проблем, дополненных описанием, ссылками на стандарты W3C. По ходу анализа вы увидите слабые места со ссылками на правила, что позволит самостоятельно исправить проблему.
Существуют другие сервисы, позволяющие выполнить проверку валидности кода:
- Dr. Watson. Проверяет скорость загрузки страниц, орфографию, ссылки, а также исходный код;
- InternetSupervision.com. Отслеживает производительность сайта, проверяет доступность HTML.
Плагины для браузеров, которые помогут найти ошибки в коде
Решить рассматриваемую задачу можно с помощью плагинов, адаптированных под конкретный браузер. Можно использовать следующие инструменты (бесплатные):
- HTML Validator для браузера Firefox;
- HTML Validator for Chrome;
- Validate HTML для Firefox.
После проверки нужно решить, будете ли вы устранять выявленные ошибки. Многие эксперты акцентируют внимание на том, что поисковые системы сегодня уделяют больше внимания качеству внешней/внутренней оптимизации, контенту, другим характеристикам. Однако валидность нельзя оставлять без внимания, ведь если даже обнаруженные проблемы не будут мешать поисковым ботам, то они точно начнут раздражать посетителей сайта.
Как исправить ошибку валидации?
В первую очередь нужно сосредоточить внимание на слабых местах, связанных с контентом – это то, что важно для поисковых систем. Если во время сканирования было выявлено более 25 проблем, то их нельзя игнорировать из-за ряда причин:
- частичная индексация;
- медленная загрузка;
- баги, возникающие во время непосредственной коммуникации пользователя с ресурсом.
Например, игнорирование ошибок может привести к тому, что некоторые страницы не будут проиндексированы. Для решения рассматриваемой проблемы можно привлечь опытного фрилансера, однако лучшее решение – заказ услуги в веб-агентстве, что позволит исправить, а не усугубить ситуацию.
Технический и SEO-аудит
Выявление ошибок – первый шаг, ведь их еще нужно будет устранить. При наличии большого пула проблем целесообразно заказать профессиональный аудит сайта. Он поможет найти разные виды ошибок, повысит привлекательность ресурса для поисковых ботов, обычных пользователей: скорость загрузки страниц, верстка, переспам, другое.
В заключение
На всех сайтах наблюдаются ошибки валидации – их невозможно искоренить полностью, но и оставлять без внимания не стоит. Например, если провести проверку сайтов Google или «Яндекс», то можно увидеть ошибки, однако это не означает, что стоит вздохнуть спокойно и закрыть глаза на происходящее. Владелец сайта должен ставить во главу угла комплексное развитие, при таком подходе ресурс будет наполняться, обновляться и «лечиться» своевременно. Если проблем мало, то можно попробовать устранить их своими силами или с помощью привлечения стороннего частного специалиста. В остальных случаях лучше заказать услугу у проверенного подрядчика.

Вступление
Laravel предлагает несколько разных подходов для проверки входящих данных вашего приложения. По умолчанию базовый класс контроллера Laravel использует ValidatesRequestsчерту, которая предоставляет удобный метод для проверки входящего HTTP-запроса с помощью множества мощных правил проверки.
Валидация Быстрый старт
Чтобы узнать о мощных функциях проверки Laravel, давайте рассмотрим полный пример проверки формы и отображения сообщений об ошибках пользователю.
Определение маршрутов
Сначала предположим, что в нашем файле определены следующие маршруты :routes/web.php
Route::get('post/create', 'PostController@create');
Route::post('post', 'PostController@store');
GETМаршрут будет отображать форму для пользователя , чтобы создать новое сообщение в блоге, в то время как POSTмаршрут будет хранить запись в блоге в базе данных.
Создание контроллера
Далее, давайте посмотрим на простой контроллер, который обрабатывает эти маршруты. Мы storeпока оставим метод пустым:
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppHttpControllersController;
class PostController extends Controller
{
/**
* Show the form to create a new blog post.
*
* @return Response
*/
public function create()
{
return view('post.create');
}
/**
* Store a new blog post.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// Validate and store the blog post...
}
}
Написание логики валидации
Теперь мы готовы заполнить наш storeметод логикой для проверки нового сообщения в блоге. Для этого мы будем использовать validateметод, предоставленный объектом. Если правила проверки пройдут, ваш код будет работать нормально; однако, если проверка не пройдена, будет выдано исключение, и правильный ответ об ошибке будет автоматически отправлен обратно пользователю. В случае традиционного HTTP-запроса будет сгенерирован ответ о перенаправлении, а JSON-ответ будет отправлен для AJAX-запросов.IlluminateHttpRequest
Чтобы лучше понять validateметод, давайте вернемся к storeметоду:
/**
* Store a new blog post.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$validatedData = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid...
}
Как видите, мы передаем в метод нужные правила валидации validate. Опять же, если проверка не пройдена, автоматически генерируется правильный ответ. Если проверка пройдена, наш контроллер продолжит нормально работать.
Остановка при первом сбое проверки
Иногда может потребоваться прекратить запуск правил проверки для атрибута после первого сбоя проверки. Для этого присвойте bailправило атрибуту:
$request->validate([
'title' => 'bail|required|unique:posts|max:255',
'body' => 'required',
]);
В этом примере, если uniqueправило для titleатрибута не выполнено, maxправило не будет проверено. Правила будут утверждены в порядке их назначения.
Примечание о вложенных атрибутах
Если ваш HTTP-запрос содержит «вложенные» параметры, вы можете указать их в правилах проверки, используя синтаксис «точка»:
$request->validate([
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
]);
Отображение ошибок валидации
Итак, что если параметры входящего запроса не соответствуют заданным правилам проверки? Как упоминалось ранее, Laravel автоматически перенаправит пользователя обратно на прежнее место. Кроме того, все ошибки проверки автоматически будут мигать в сеансе .
Опять же, обратите внимание, что нам не нужно было явно привязывать сообщения об ошибках к представлению нашего GETмаршрута. Это потому, что Laravel будет проверять ошибки в данных сеанса и автоматически связывать их с представлением, если они доступны. $errorsПеременная будет экземпляром . Для получения дополнительной информации о работе с этим объектом ознакомьтесь с его документацией .IlluminateSupportMessageBag
$errorsПеременная связана с видом со стороны промежуточного программного обеспечения , которое обеспечивается в группе промежуточного программного обеспечения . Когда применяется это промежуточное программное обеспечение, переменная всегда будет доступна в ваших представлениях , что позволяет вам удобно предполагать, что переменная всегда определена и ее можно безопасно использовать.IlluminateViewMiddlewareShareErrorsFromSessionweb$errors$errors
Таким образом, в нашем примере пользователь будет перенаправлен на createметод нашего контроллера при сбое проверки, что позволит нам отображать сообщения об ошибках в представлении:
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- Create Post Form -->
@errorДиректива
Вы также можете использовать директиву @error Blade, чтобы быстро проверить, существуют ли сообщения об ошибках валидации для данного атрибута. Внутри @errorдирективы вы можете вызвать $messageпеременную для отображения сообщения об ошибке:
<!-- /resources/views/post/create.blade.php -->
<label for="title">Post Title</label>
<input id="title" type="text" class="@error('title') is-invalid @enderror">
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
Примечание о необязательных полях
По умолчанию Laravel включает TrimStringsи ConvertEmptyStringsToNullпромежуточное ПО в глобальный стек промежуточного ПО вашего приложения. Эти промежуточные программы перечислены в стеке классом. Из-за этого вам часто нужно помечать ваши «необязательные» поля запроса так, как будто вы не хотите, чтобы валидатор считал значения недействительными. Например:AppHttpKernelnullablenull
$request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
'publish_at' => 'nullable|date',
]);
В этом примере мы указываем, что publish_atполе может быть либо nullдействительным представлением даты. Если nullableмодификатор не добавлен в определение правила, валидатор будет считать nullнедопустимую дату.
AJAX-запросы и валидация
В этом примере мы использовали традиционную форму для отправки данных в приложение. Однако многие приложения используют запросы AJAX. При использовании validateметода во время запроса AJAX, Laravel не будет генерировать ответ перенаправления. Вместо этого Laravel генерирует ответ JSON, содержащий все ошибки проверки. Этот ответ JSON будет отправлен с кодом состояния 422 HTTP.
Проверка запроса формы
Создание запросов формы
Для более сложных сценариев проверки вы можете создать «запрос формы». Запросы форм — это пользовательские классы запросов, которые содержат логику проверки. Чтобы создать класс запроса формы, используйте команду Artisan CLI:make:request
php artisan make:request StoreBlogPost
Сгенерированный класс будет помещен в каталог. Если этот каталог не существует, он будет создан при запуске команды. Давайте добавим несколько правил проверки в метод:app/Http/Requestsmake:requestrules
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
Вы можете напечатать любые зависимости, которые вам нужны, в
rulesсигнатуре метода. Они будут автоматически разрешены через сервисный контейнер Laravel .
Итак, как оцениваются правила валидации? Все, что вам нужно сделать, это напечатать запрос на метод вашего контроллера. Входящий запрос формы проверяется перед вызовом метода контроллера, что означает, что вам не нужно загромождать ваш контроллер какой-либо логикой проверки:
/**
* Store the incoming blog post.
*
* @param StoreBlogPost $request
* @return Response
*/
public function store(StoreBlogPost $request)
{
// The incoming request is valid...
// Retrieve the validated input data...
$validated = $request->validated();
}
Если проверка не пройдена, будет сгенерирован ответ о перенаправлении, чтобы отправить пользователя обратно в его предыдущее местоположение. Ошибки также будут мигать в сеансе, чтобы они были доступны для отображения. Если запрос был запросом AJAX, пользователю будет возвращен HTTP-ответ с кодом состояния 422, включая JSON-представление ошибок проверки.
Добавление после хуков для формирования запросов
Если вы хотите добавить хук «после» к запросу формы, вы можете использовать withValidatorметод. Этот метод получает полностью сконструированный валидатор, позволяющий вам вызвать любой из его методов до того, как правила валидации действительно будут оценены:
/**
* Configure the validator instance.
*
* @param IlluminateValidationValidator $validator
* @return void
*/
public function withValidator($validator)
{
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add('field', 'Something is wrong with this field!');
}
});
}
Запросы формы авторизации
Класс запроса формы также содержит authorizeметод. В рамках этого метода вы можете проверить, действительно ли аутентифицированный пользователь имеет полномочия на обновление данного ресурса. Например, вы можете определить, действительно ли пользователю принадлежит комментарий в блоге, который он пытается обновить:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
$comment = Comment::find($this->route('comment'));
return $comment && $this->user()->can('update', $comment);
}
Поскольку все запросы формы расширяют базовый класс запросов Laravel, мы можем использовать userметод для доступа к аутентифицированному в настоящее время пользователю. Также обратите внимание на вызов routeметода в примере выше. Этот метод предоставляет вам доступ к параметрам URI, определенным на вызываемом маршруте, таким как параметр в примере ниже:{comment}
Route::post('comment/{comment}');
Если authorizeметод возвращается false, HTTP-ответ с кодом состояния 403 будет автоматически возвращен, и ваш метод контроллера не будет выполнен.
Если вы планируете использовать логику авторизации в другой части вашего приложения, вернитесь trueиз authorizeметода:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
Вы можете напечатать любые зависимости, которые вам нужны, в
authorizeсигнатуре метода. Они будут автоматически разрешены через сервисный контейнер Laravel .
Настройка сообщений об ошибках
Вы можете настроить сообщения об ошибках, используемые запросом формы, переопределив messagesметод. Этот метод должен возвращать массив пар атрибут / правило и соответствующие им сообщения об ошибках:
/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function messages()
{
return [
'title.required' => 'A title is required',
'body.required' => 'A message is required',
];
}
Настройка атрибутов проверки
Если вы хотите, чтобы :attributeчасть вашего сообщения проверки была заменена именем настраиваемого атрибута, вы можете указать настраиваемые имена, переопределив attributesметод. Этот метод должен возвращать массив пар атрибут / имя:
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes()
{
return [
'email' => 'email address',
];
}
Создание валидаторов вручную
Если вы не хотите использовать validateметод в запросе, вы можете создать экземпляр валидатора вручную, используя Validator фасад . makeМетод на фасаде создает новый экземпляр валидатора:
<?php
namespace AppHttpControllers;
use Validator;
use IlluminateHttpRequest;
use AppHttpControllersController;
class PostController extends Controller
{
/**
* Store a new blog post.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
// Store the blog post...
}
}
Первым аргументом, переданным makeметоду, являются проверяемые данные. Второй аргумент — это правила проверки, которые должны применяться к данным.
После проверки, не прошла ли проверка запроса, вы можете использовать этот withErrorsметод для отправки сообщений об ошибках в сеанс. При использовании этого метода $errorsпеременная будет автоматически предоставлена вашим представлениям после перенаправления, что позволит вам легко отображать их обратно пользователю. withErrorsМетод принимает валидатор, а MessageBag, или PHP array.
Автоматическое перенаправление
Если вы хотите создать экземпляр валидатора вручную, но все же воспользоваться преимуществами автоматического перенаправления, предлагаемого методом запросов validate, вы можете вызвать validateметод в существующем экземпляре валидатора. Если проверка не пройдена, пользователь будет автоматически перенаправлен или, в случае запроса AJAX, будет возвращен ответ JSON:
Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
])->validate();
Именованные пакеты с ошибками
Если у вас есть несколько форм на одной странице, вы можете назвать имена MessageBagошибок, что позволит вам получать сообщения об ошибках для конкретной формы. Передайте имя в качестве второго аргумента withErrors:
return redirect('register')
->withErrors($validator, 'login');
Затем вы можете получить доступ к именованному MessageBagэкземпляру из $errorsпеременной:
{{ $errors->login->first('email') }}
После проверки крюк
Валидатор также позволяет вам добавлять обратные вызовы, которые будут выполняться после завершения проверки. Это позволяет вам легко выполнять дальнейшую проверку и даже добавлять больше сообщений об ошибках в коллекцию сообщений. Чтобы начать, используйте afterметод на экземпляре валидатора:
$validator = Validator::make(...);
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add('field', 'Something is wrong with this field!');
}
});
if ($validator->fails()) {
//
}
Работа с сообщениями об ошибках
После вызова errorsметода для Validatorэкземпляра вы получите экземпляр, который имеет множество удобных методов для работы с сообщениями об ошибках. Переменная , которая автоматически становится доступной для всех представлений также является экземпляром класса.IlluminateSupportMessageBag$errorsMessageBag
Получение первого сообщения об ошибке для поля
Чтобы получить первое сообщение об ошибке для данного поля, используйте firstметод:
$errors = $validator->errors();
echo $errors->first('email');
Получение всех сообщений об ошибках для поля
Если вам нужно получить массив всех сообщений для данного поля, используйте getметод:
foreach ($errors->get('email') as $message) {
//
}
Если вы проверяете поле формы массива, вы можете получить все сообщения для каждого из элементов массива, используя *символ:
foreach ($errors->get('attachments.*') as $message) {
//
}
Получение всех сообщений об ошибках для всех полей
Чтобы получить массив всех сообщений для всех полей, используйте allметод:
foreach ($errors->all() as $message) {
//
}
Определение наличия сообщений для поля
hasМетод может быть использован , чтобы определить , существуют ли какие — либо сообщения об ошибках для данного поля:
if ($errors->has('email')) {
//
}
Пользовательские сообщения об ошибках
При необходимости вы можете использовать пользовательские сообщения об ошибках для проверки вместо значений по умолчанию. Есть несколько способов указать пользовательские сообщения. Во-первых, вы можете передать пользовательские сообщения в качестве третьего аргумента методу:Validator::make
$messages = [
'required' => 'The :attribute field is required.',
];
$validator = Validator::make($input, $rules, $messages);
В этом примере :attributeзаполнитель будет заменен действительным именем проверяемого поля. Вы также можете использовать другие заполнители в сообщениях проверки. Например:
$messages = [
'same' => 'The :attribute and :other must match.',
'size' => 'The :attribute must be exactly :size.',
'between' => 'The :attribute value :input is not between :min - :max.',
'in' => 'The :attribute must be one of the following types: :values',
];
Указание пользовательского сообщения для данного атрибута
Иногда вам может потребоваться указать пользовательское сообщение об ошибке только для определенного поля. Вы можете сделать это, используя обозначение «точка». Сначала укажите имя атрибута, а затем правило:
$messages = [
'email.required' => 'We need to know your e-mail address!',
];
Указание пользовательских сообщений в языковых файлах
В большинстве случаев вы, вероятно, будете указывать свои пользовательские сообщения в языковом файле, а не передавать их непосредственно в Validator. Для этого добавьте ваши сообщения в customмассив в языковой файл.resources/lang/xx/validation.php
'custom' => [
'email' => [
'required' => 'We need to know your e-mail address!',
],
],
Указание пользовательских атрибутов в языковых файлах
Если вы хотите, чтобы :attributeчасть вашего сообщения проверки была заменена именем настраиваемого атрибута, вы можете указать это имя в attributesмассиве вашего языкового файла:resources/lang/xx/validation.php
'attributes' => [
'email' => 'email address',
],
Указание пользовательских значений в языковых файлах
Иногда вам может понадобиться :valueзаменить часть вашего сообщения для проверки пользовательским представлением значения. Например, рассмотрим следующее правило, которое указывает, что номер кредитной карты требуется, если значение payment_typeимеет cc:
$request->validate([
'credit_card_number' => 'required_if:payment_type,cc'
]);
Если это правило проверки не выполнено, оно выдаст следующее сообщение об ошибке:
The credit card number field is required when payment type is cc.
Вместо отображения ccв качестве значения типа платежа вы можете указать представление пользовательского значения в вашем validationязыковом файле, определив valuesмассив:
'values' => [
'payment_type' => [
'cc' => 'credit card'
],
],
Теперь, если правило проверки не выполнено, оно выдаст следующее сообщение:
The credit card number field is required when payment type is credit card.
Доступные правила проверки
Ниже приведен список всех доступных правил проверки и их функции:
- Accepted
- Active URL
- After (Date)
- After Or Equal (Date)
- Alpha
- Alpha Dash
- Alpha Numeric
- Array
- Bail
- Before (Date)
- Before Or Equal (Date)
- Between
- Boolean
- Confirmed
- Date
- Date Equals
- Date Format
- Different
- Digits
- Digits Between
- Dimensions (Image Files)
- Distinct
- Ends With
- Exists (Database)
- File
- Filled
- Greater Than
- Greater Than Or Equal
- Image (File)
- In
- In Array
- Integer
- IP Address
- JSON
- Less Than
- Less Than Or Equal
- Max
- MIME Types
- MIME Type By File Extension
- Min
- Not In
- Not Regex
- Nullable
- Numeric
- Present
- Regular Expression
- Required
- Required If
- Required Unless
- Required With
- Required With All
- Required Without
- Required Without All
- Same
- Size
- Sometimes
- Starts With
- String
- Timezone
- Unique (Database)
- URL
- UUID
accepted
Проверяемое поле должно быть yes , on , 1 или true . Это полезно для подтверждения принятия «Условий обслуживания».
active_url
Проверяемое поле должно иметь действительную запись A или AAAA в соответствии с dns_get_recordфункцией PHP.
after (Date)
Проверяемое поле должно быть значением после указанной даты. Даты будут переданы в strtotimeфункцию PHP:
'start_date' => 'required|date|after:tomorrow'
Вместо того, чтобы передавать строку даты для оценки strtotime, вы можете указать другое поле для сравнения с датой:
'finish_date' => 'required|date|after:start_date'
after_or_equal: date
Проверяемое поле должно быть значением после или равным указанной дате. Для получения дополнительной информации см. Правило после .
alpha
Проверяемое поле должно состоять исключительно из буквенных символов.
alpha_dash
Проверяемое поле может содержать буквенно-цифровые символы, а также тире и подчеркивания.
alpha_num
Проверяемое поле должно состоять из буквенно-цифровых символов.
array
Проверяемое поле должно быть PHP array.
bail
Прекратите запуск правил проверки после первого сбоя проверки.
before (Date)
Проверяемое поле должно быть значением, предшествующим данной дате. Даты будут переданы в strtotimeфункцию PHP . Кроме того, как afterправило, в качестве значения можно указать имя другого проверяемого поля date.
before Or Equal (Date)
Проверяемое поле должно быть значением, предшествующим или равным указанной дате. Даты будут переданы в strtotimeфункцию PHP . Кроме того, как afterправило, в качестве значения можно указать имя другого проверяемого поля date.
between:min,max
Проверяемое поле должно иметь размер от заданного минимального до максимального значения . Строки, числа, массивы и файлы оцениваются так же, как sizeправило.
boolean
Проверяемое поле должно быть в состоянии быть логическим. Принимаемые входные true, false, 1, 0, "1", и "0".
confirmed
Проверяемое поле должно иметь соответствующее поле foo_confirmation. Например, если проверяемое поле имеет значение password, соответствующее password_confirmationполе должно присутствовать во входных данных.
date
Проверяемое поле должно быть действительной, не относительной датой в соответствии с strtotimeфункцией PHP.
date_equals: date
Проверяемое поле должно быть равно заданной дате. Даты будут переданы в strtotimeфункцию PHP .
date_format: format
Проверяемое поле должно соответствовать заданному формату . Вы должны использовать либоdate или date_formatпри проверке поля, но не оба.
different:field
Проверяемое поле должно иметь значение, отличное от поля .
digits:value
Проверяемое поле должно быть числовым и иметь точную длину значения .
digits_between:min,max
Проверяемое поле должно иметь длину от заданного минимального до максимального значения .
dimensions
Проверяемый файл должен быть изображением, соответствующим ограничениям размеров, указанным в параметрах правила:
'avatar' => 'dimensions:min_width=100,min_height=200'
Доступны следующие ограничения: min_width , max_width , min_height , max_height , ширина , высота , коэффициент .
Отношение ограничение должно быть представлено в виде ширины , деленная на высоту. Это может быть указано либо с помощью оператора like или с плавающей точкой :3/21.5
'avatar' => 'dimensions:ratio=3/2'
Так как это правило требует нескольких аргументов, вы можете использовать метод для свободного создания правила:Rule::dimensions
use IlluminateValidationRule;
Validator::make($data, [
'avatar' => [
'required',
Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
],
]);
distinct
При работе с массивами проверяемое поле не должно иметь повторяющихся значений.
'foo.*.id' => 'distinct'
Проверяемое поле должно быть отформатировано как адрес электронной почты.
ends_with:foo,bar,…
Проверяемое поле должно заканчиваться одним из указанных значений.
exists:table,column
Проверяемое поле должно существовать в данной таблице базы данных.
Основное использование правила существования
'state' => 'exists:states'
Если columnопция не указана, будет использовано имя поля.
Указание пользовательского имени столбца
'state' => 'exists:states,abbreviation'
Иногда вам может потребоваться указать конкретное соединение с базой данных, которое будет использоваться для existsзапроса. Это можно сделать, добавив имя соединения к имени таблицы, используя синтаксис «точка»:
'email' => 'exists:connection.staff,email'
Если вы хотите настроить запрос, выполняемый правилом валидации, вы можете использовать Ruleкласс для свободного определения правила. В этом примере мы также указываем правила проверки в виде массива вместо использования |символа для их разделения:
use IlluminateValidationRule;
Validator::make($data, [
'email' => [
'required',
Rule::exists('staff')->where(function ($query) {
$query->where('account_id', 1);
}),
],
]);
file
Проверяемое поле должно быть успешно загруженным файлом.
filled
Проверяемое поле не должно быть пустым, если оно присутствует.
gt:field
Проверяемое поле должно быть больше указанного поля . Два поля должны быть одного типа. Строки, числа, массивы и файлы оцениваются с использованием тех же соглашений, что и sizeправило.
gte:field
Проверяемое поле должно быть больше или равно данному полю . Два поля должны быть одного типа. Строки, числа, массивы и файлы оцениваются с использованием тех же соглашений, что и sizeправило.
image
Проверяемый файл должен быть изображением (jpeg, png, bmp, gif или svg)
in:foo,bar,…
Проверяемое поле должно быть включено в данный список значений. Поскольку для этого правила часто требуется implodeмассив, метод может быть использован для свободного построения правила:Rule::in
use IlluminateValidationRule;
Validator::make($data, [
'zones' => [
'required',
Rule::in(['first-zone', 'second-zone']),
],
]);
in_array:anotherfield.*
Проверяемое поле должно существовать в значениях другого поля .
integer
Проверяемое поле должно быть целым числом.
ip
Проверяемое поле должно быть IP-адресом.
ipv4
Проверяемое поле должно быть адресом IPv4.
ipv6
Проверяемое поле должно быть адресом IPv6.
json
Проверяемое поле должно быть допустимой строкой JSON.
lt:field
Проверяемое поле должно быть меньше указанного поля . Два поля должны быть одного типа. Строки, числа, массивы и файлы оцениваются с использованием тех же соглашений, что и sizeправило.
lte:field
Проверяемое поле должно быть меньше или равно данному полю . Два поля должны быть одного типа. Строки, числа, массивы и файлы оцениваются с использованием тех же соглашений, что и sizeправило.
max:value
Проверяемое поле должно быть меньше или равно максимальному значению . Строки, числа, массивы и файлы оцениваются так же, как sizeправило.
mimetypes:text/plain,…
Проверяемый файл должен соответствовать одному из указанных типов MIME:
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'
Чтобы определить тип MIME загруженного файла, его содержимое будет прочитано, и платформа попытается угадать тип MIME, который может отличаться от типа MIME, предоставленного клиентом.
mimes:foo,bar,…
Проверяемый файл должен иметь тип MIME, соответствующий одному из перечисленных расширений.
Основное использование правила MIME
'photo' => 'mimes:jpeg,bmp,png'
Несмотря на то, что вам нужно только указать расширения, это правило фактически проверяет тип файла MIME, читая содержимое файла и угадывая его тип MIME.
Полный список типов MIME и их соответствующих расширений можно найти по следующему адресу : https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types.
min:value
Проверяемое поле должно иметь минимальное значение . Строки, числа, массивы и файлы оцениваются так же, как sizeправило.
not_in:foo,bar,…
Проверяемое поле не должно быть включено в данный список значений. Метод может быть использован для построения свободно правила:Rule::notIn
use IlluminateValidationRule;
Validator::make($data, [
'toppings' => [
'required',
Rule::notIn(['sprinkles', 'cherries']),
],
]);
not_regex:pattern
Проверяемое поле не должно соответствовать заданному регулярному выражению.
Внутренне это правило использует preg_matchфункцию PHP . Указанный шаблон должен соответствовать форматированию, требуемому для этого, preg_matchи, следовательно, также включать допустимые разделители. Например: .'email' => 'not_regex:/^.+$/i'
Примечание. При использовании шаблонов
regex/not_regexможет потребоваться указать правила в массиве вместо использования разделителей канала, особенно если регулярное выражение содержит символ канала.
nullable
Проверяемое поле может быть null. Это особенно полезно при проверке примитивов, таких как строки и целые числа, которые могут содержать nullзначения.
numeric
Проверяемое поле должно быть числовым.
present
Проверяемое поле должно присутствовать во входных данных, но может быть пустым.
regex:pattern
Проверяемое поле должно соответствовать заданному регулярному выражению.
Внутренне это правило использует preg_matchфункцию PHP . Указанный шаблон должен соответствовать форматированию, требуемому для этого, preg_matchи, следовательно, также включать допустимые разделители. Например: .'email' => 'regex:/^.+@.+$/i'
Примечание. При использовании шаблонов
regex/not_regexможет потребоваться указать правила в массиве вместо использования разделителей канала, особенно если регулярное выражение содержит символ канала.
required
Проверяемое поле должно присутствовать во входных данных и не быть пустым. Поле считается «пустым», если выполняется одно из следующих условий:
- Значение есть
null. - Значение является пустой строкой.
- Значением является пустой массив или пустой
Countableобъект. - Значением является загруженный файл без пути.
required_if:anotherfield,value,…
Проверяемое поле должно присутствовать и не быть пустым, если поле другого поля равно какому-либо значению .
Если вы хотите построить более сложное условие для required_ifправила, вы можете использовать метод. Этот метод принимает логическое значение или замыкание. Когда передано Закрытие, Закрытие должно возвратиться или указать, требуется ли проверяемое поле:Rule::requiredIftruefalse
use IlluminateValidationRule;
Validator::make($request->all(), [
'role_id' => Rule::requiredIf($request->user()->is_admin),
]);
Validator::make($request->all(), [
'role_id' => Rule::requiredIf(function () use ($request) {
return $request->user()->is_admin;
}),
]);
required_unless:anotherfield,value,…
Проверяемое поле должно присутствовать и не быть пустым, если поле другого поля не равно какому-либо значению .
required_with:foo,bar,…
Проверяемое поле должно присутствовать и не быть пустым, только если присутствуют какие-либо другие указанные поля.
required_with_all:foo,bar,…
Проверяемое поле должно присутствовать и не быть пустым, только если присутствуют все другие указанные поля.
required_without:foo,bar,…
Проверяемое поле должно присутствовать и не быть пустым, только если нет других указанных полей.
required_without_all:foo,bar,…
Проверяемое поле должно присутствовать и не быть пустым, только если все другие указанные поля отсутствуют.
same:field
Данное поле должно соответствовать проверяемому полю.
size:value
Проверяемое поле должно иметь размер, соответствующий заданному значению . Для строковых данных значение соответствует количеству символов. Для числовых данных значениесоответствует заданному целочисленному значению. Для массива размер соответствует countмассиву. Для файлов размер соответствует размеру файла в килобайтах.
starts_with:foo,bar,…
Проверяемое поле должно начинаться с одного из указанных значений.
string
Проверяемое поле должно быть строкой. Если вы хотите, чтобы поле также было null, вы должны назначить nullableправило для поля.
timezone
Проверяемое поле должно быть действительным идентификатором часового пояса в соответствии с timezone_identifiers_listфункцией PHP.
unique:table,column,except,idColumn
Проверяемое поле не должно существовать в данной таблице базы данных.
Указание пользовательского имени столбца:
columnВариант может быть использован для определения соответствующего столбца базы данных в полях. Если columnопция не указана, будет использовано имя поля.
'email' => 'unique:users,email_address'
Настраиваемое соединение с базой данных
Иногда вам может понадобиться установить пользовательское соединение для запросов к базе данных, выполняемых валидатором. Как показано выше, при настройке в качестве правила проверки будет использоваться соединение с базой данных по умолчанию для запроса к базе данных. Чтобы переопределить это, укажите соединение и имя таблицы, используя синтаксис «точка»:unique:users
'email' => 'unique:connection.users,email_address'
Принудительное уникальное правило игнорирования заданного идентификатора:
Иногда вы можете игнорировать данный идентификатор во время уникальной проверки. Например, рассмотрим экран «Обновить профиль», который включает имя пользователя, адрес электронной почты и местоположение. Возможно, вы захотите убедиться, что адрес электронной почты является уникальным. Однако, если пользователь изменяет только поле имени, а не поле электронной почты, вы не хотите, чтобы выдавалась ошибка проверки, поскольку пользователь уже является владельцем адреса электронной почты.
Чтобы поручить валидатору игнорировать идентификатор пользователя, мы будем использовать Ruleкласс для свободного определения правила. В этом примере мы также указываем правила проверки в виде массива вместо использования |символа для разделения правил:
use IlluminateValidationRule;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
Вы никогда не должны передавать какой-либо пользовательский ввод запроса в
ignoreметод. Вместо этого вы должны передавать только сгенерированный системой уникальный идентификатор, такой как идентификатор с автоматическим увеличением или UUID, из экземпляра модели Eloquent. В противном случае ваше приложение будет уязвимо для атаки SQL-инъекцией.
Вместо того, чтобы передавать значение ключа модели в ignoreметод, вы можете передать весь экземпляр модели. Laravel автоматически извлечет ключ из модели:
Rule::unique('users')->ignore($user)
Если ваша таблица использует имя столбца первичного ключа, отличное от id, вы можете указать имя столбца при вызове ignoreметода:
Rule::unique('users')->ignore($user->id, 'user_id')
По умолчанию uniqueправило проверяет уникальность столбца, совпадающего с именем проверяемого атрибута. Однако вы можете передать другое имя столбца в качестве второго аргумента uniqueметода:
Rule::unique('users', 'email_address')->ignore($user->id),
Добавление дополнительных предложений Where:
Вы также можете указать дополнительные ограничения запроса, настроив запрос с помощью whereметода. Например, давайте добавим ограничение , которое проверяет account_idIS 1:
'email' => Rule::unique('users')->where(function ($query) {
return $query->where('account_id', 1);
})
url
Проверяемое поле должно быть действительным URL.
uuid
Проверяемое поле должно быть действительным универсальным уникальным идентификатором (UUID) RFC 4122 (версия 1, 3, 4 или 5).
Условия добавления правил
Проверка при наличии
В некоторых ситуациях вам может потребоваться выполнить проверки правильности для поля, только если это поле присутствует во входном массиве. Чтобы быстро это сделать, добавьте sometimesправило в список правил:
$v = Validator::make($data, [
'email' => 'sometimes|required|email',
]);
В приведенном выше примере emailполе будет проверено, только если оно присутствует в $dataмассиве.
Если вы пытаетесь проверить поле, которое всегда должно присутствовать, но может быть пустым, ознакомьтесь с этим примечанием к дополнительным полям
Комплексная условная проверка
Иногда вы можете захотеть добавить правила проверки, основанные на более сложной условной логике. Например, вам может потребоваться указать данное поле только в том случае, если другое поле имеет значение больше 100. Или вам может потребоваться, чтобы два поля имели заданное значение только при наличии другого поля. Добавление этих правил проверки не должно быть проблемой. Сначала создайте Validatorэкземпляр со своими статическими правилами,которые никогда не меняются:
$v = Validator::make($data, [
'email' => 'required|email',
'games' => 'required|numeric',
]);
Давайте предположим, что наше веб-приложение предназначено для коллекционеров игр. Если коллекционер игр регистрируется в нашем приложении и им принадлежит более 100 игр, мы хотим, чтобы они объяснили, почему у них так много игр. Например, возможно, они управляют магазином перепродажи игр, или, возможно, им просто нравится коллекционировать. Чтобы условно добавить это требование, мы можем использовать sometimesметод в Validatorэкземпляре.
$v->sometimes('reason', 'required|max:500', function ($input) {
return $input->games >= 100;
});
Первым аргументом, переданным sometimesметоду, является имя поля, которое мы условно проверяем. Второй аргумент — это правила, которые мы хотим добавить. Если Closureпередано в качестве третьего аргумента true, правила будут добавлены. Этот метод позволяет легко создавать сложные условные проверки. Вы можете даже добавить условные проверки для нескольких полей одновременно:
$v->sometimes(['reason', 'cost'], 'required', function ($input) {
return $input->games >= 100;
});
$inputПараметр , переданный к вашемуClosureбудет экземпляром и может использоваться для доступа к вашему вводу и файлам.IlluminateSupportFluent
Проверка массивов
Проверка полей ввода на основе массива не должна быть проблемой. Вы можете использовать «точечную нотацию» для проверки атрибутов в массиве. Например, если входящий HTTP-запрос содержит поле, вы можете проверить его следующим образом:photos[profile]
$validator = Validator::make($request->all(), [
'photos.profile' => 'required|image',
]);
Вы также можете проверить каждый элемент массива. Например, чтобы проверить, что каждое электронное письмо в данном поле ввода массива уникально, вы можете сделать следующее:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
Аналогичным образом, вы можете использовать этот *символ при указании ваших сообщений проверки в ваших языковых файлах, что позволяет без труда использовать одно сообщение проверки для полей на основе массива:
'custom' => [
'person.*.email' => [
'unique' => 'Each person must have a unique e-mail address',
]
],
Пользовательские правила проверки
Использование объектов правил
Laravel предлагает множество полезных правил проверки; тем не менее, вы можете указать свои собственные. Одним из способов регистрации пользовательских правил проверки является использование объектов правил. Чтобы создать новый объект правила, вы можете использовать команду Artisan. Давайте использовать эту команду для генерации правила, которое проверяет строку в верхнем регистре. Laravel поместит новое правило в каталог:make:ruleapp/Rules
php artisan make:rule Uppercase
Как только правило было создано, мы готовы определить его поведение. Объект правила содержит два метода: passesи message. passesМетод получает значение атрибута и имя, и он должен возвращать trueили в falseзависимости от того, является ли или нет значение атрибута. messageМетод должен возвращать сообщение об ошибке проверки , которая должна использоваться при сбое проверки:
<?php
namespace AppRules;
use IlluminateContractsValidationRule;
class Uppercase implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return strtoupper($value) === $value;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The :attribute must be uppercase.';
}
}
Вы можете вызвать transпомощника из вашего messageметода, если хотите вернуть сообщение об ошибке из ваших файлов перевода:
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return trans('validation.uppercase');
}
Как только правило было определено, вы можете присоединить его к валидатору, передав экземпляр объекта правила с другими вашими правилами валидации:
use AppRulesUppercase;
$request->validate([
'name' => ['required', 'string', new Uppercase],
]);
Использование замыканий
Если вам требуется функциональность настраиваемого правила только один раз в приложении, вы можете использовать Closure вместо объекта правила. Замыкание получает имя атрибута, значение атрибута и $failобратный вызов, который должен быть вызван в случае сбоя проверки:
$validator = Validator::make($request->all(), [
'title' => [
'required',
'max:255',
function ($attribute, $value, $fail) {
if ($value === 'foo') {
$fail($attribute.' is invalid.');
}
},
],
]);
Использование расширений
Другой метод регистрации пользовательских правил проверки — использование extendметода на Validator фасаде . Давайте использовать этот метод в сервис-провайдере для регистрации пользовательского правила проверки:
<?php
namespace AppProviders;
use IlluminateSupportServiceProvider;
use IlluminateSupportFacadesValidator;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
return $value == 'foo';
});
}
}
Пользовательский валидатор Closure получает четыре аргумента: имя $attributeпроверяемого $valueобъекта, атрибута, массив, $parametersпередаваемый правилу, и Validatorэкземпляр.
Вы также можете передать класс и метод в extendметод вместо Closure:
Validator::extend('foo', 'FooValidator@validate');
Определение сообщения об ошибке
Вам также необходимо определить сообщение об ошибке для вашего пользовательского правила. Это можно сделать либо с помощью встроенного пользовательского массива сообщений, либо добавив запись в файл языка проверки. Это сообщение должно быть помещено в первый уровень массива, а не в customмассив, который предназначен только для сообщений об ошибках, относящихся к атрибуту:
"foo" => "Your input was invalid!",
"accepted" => "The :attribute must be accepted.",
// The rest of the validation error messages...
При создании пользовательского правила проверки иногда может потребоваться определить пользовательские замены заполнителей для сообщений об ошибках. Вы можете сделать это, создав пользовательский Validator, как описано выше, затем вызвав replacerметод на Validatorфасаде. Вы можете сделать это в рамках bootметода поставщика услуг :
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Validator::extend(...);
Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
return str_replace(...);
});
}
Неявные расширения
По умолчанию, когда проверяемый атрибут отсутствует или содержит пустую строку, обычные правила проверки, включая пользовательские расширения, не запускаются. Например, unique правило не будет запущено для пустой строки:
$rules = ['name' => 'unique:users,name'];
$input = ['name' => ''];
Validator::make($input, $rules)->passes(); // true
Чтобы правило запускалось, даже если атрибут пуст, правило должно подразумевать, что атрибут является обязательным. Чтобы создать такое «неявное» расширение, используйте метод:Validator::extendImplicit()
Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
return $value == 'foo';
});
«Неявное» расширение подразумевает, что атрибут является обязательным. Независимо от того, действительно ли он аннулирует отсутствующий или пустой атрибут, зависит от вас.
- 1. Введение
-
2. Краткое руководство по проверке ввода
- 2.1. Определение маршрутов
-
3. Создание контроллера
- 3.1. Написание логики проверки ввода
- 3.2. Вывод ошибок
-
4. Проверка запроса формы
- 4.1. Создание запроса формы
- 4.2. Авторизация запроса формы
- 4.3. Настройка формата ошибок
- 4.4. Настройка сообщений об ошибках
-
5. Создание валидаторов вручную
- 5.1. Автоматическая переадресация
- 5.2. Именованные наборы ошибок
- 5.3. Вебхук после проверки
-
6. Работа с сообщениями об ошибках
- 6.1. Изменение сообщений об ошибках
-
7. Доступные правила проверки
- 7.1. accepted
- 7.2. active_url
- 7.3. after:date
- 7.4. alpha
- 7.5. alpha_dash
- 7.6. alpha_num
- 7.7. array
- 7.8. before:date
- 7.9. between:min,max
- 7.10. boolean
- 7.11. confirmed
- 7.12. date
- 7.13. date_format:format
- 7.14. different:field
- 7.15. digits:value
- 7.16. digits_between:min,max
- 7.17. dimensions
- 7.18. distinct
- 7.19. email
- 7.20. exists:table,column
- 7.21. file
- 7.22. filled
- 7.23. image
- 7.24. in:foo,bar,…
- 7.25. in_array:anotherfield
- 7.26. integer
- 7.27. ip
- 7.28. json
- 7.29. max:value
- 7.30. mimetypes:text/plain,…
- 7.31. mimes:foo,bar,…
- 7.32. min:value
- 7.33. nullable
- 7.34. not_in:foo,bar,…
- 7.35. numeric
- 7.36. present
- 7.37. regex:pattern
- 7.38. required
- 7.39. required_if:anotherfield,value,…
- 7.40. required_unless:anotherfield,value,…
- 7.41. required_with:foo,bar,…
- 7.42. required_with_all:foo,bar,…
- 7.43. required_without:foo,bar,…
- 7.44. required_without_all:foo,bar,…
- 7.45. same:field
- 7.46. size:value
- 7.47. string
- 7.48. timezone
- 7.49. unique:table,column,except,idColumn
- 7.50. url
- 8. Условные правила
- 9. Проверка ввода массивов
- 10. Собственные правила проверки
Введение
Laravel предоставляет несколько разных подходов к проверке входящих в ваше приложение данных. По умолчанию базовый класс контроллера использует типаж ValidatesRequests, который предоставляет удобный метод проверки входящего HTTP-запроса с помощью различных мощных правил проверки.
Краткое руководство по проверке ввода
Для изучения мощных возможностей проверки ввода в Laravel, давайте рассмотрим полный пример проверки ввода через форму и вывода сообщений об ошибках.
Определение маршрутов
Сначала давайте предположим, что у нас есть следующие маршруты, определённые в файле routes/web.php:
PHP
Route::get('post/create', 'PostController@create');Route::post('post', 'PostController@store');
Очевидно, маршрут GET выведет пользователю форму для написания новой статьи, а маршрут POST сохранит её в БД.
Создание контроллера
Теперь давайте посмотрим на простой контроллер, который обрабатывает эти маршруты. Метод PHPstore() мы пока оставим пустым:
PHP
<?phpnamespace AppHttpControllers;use
IlluminateHttpRequest;
use AppHttpControllersController;class
PostController extends Controller
{
/**
* Вывод формы написания статьи.
*
* @return Response
*/
public function create()
{
return view('post.create');
}/**
* Сохранение новой статьи.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// Проверка и сохранение новой статьи.
}
}
Написание логики проверки ввода
Теперь мы готовы наполнить метод PHPstore() логикой для проверки новой статьи. Если вы посмотрите в базовый класс контроллера приложения (AppHttpControllersController), то увидите, что в нём используется типаж ValidatesRequests. Этот типаж предоставляет удобный метод PHPvalidate() всем вашим контроллерам.
Метод PHPvalidate() принимает входящий HTTP-запрос и набор правил для проверки. Если проверка успешна, ваш код продолжит нормально выполняться. Но если проверка провалится, возникнет исключение, и пользователю будет автоматически отправлен отклик с соответствующей ошибкой. Для обычных HTTP-запросов будет сгенерирован отклик-переадресация, а для AJAX-запросов — JSON-отклик.
Для лучшего понимания метода PHPvalidate() давайте вернёмся к методу PHPstore():
PHP
/**
* Сохранение новой статьи.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);// Статья прошла проверку, сохранение в БД...
}
Как видите, мы просто передали входящий HTTP-запрос и требуемые правила проверки в метод PHPvalidate(). Если проверка провалится, будет сгенерирован соответствующий отклик. Если проверка успешна, ваш контроллер продолжит нормально выполняться.
+
5.2
добавлено в
5.2
(08.12.2016)
Остановка после первой ошибки ввода
Иногда надо остановить выполнение правил проверки ввода для атрибута после первой ошибки. Для этого назначьте на атрибут правило bail:
PHP
$this->validate($request, [
'title' => 'bail|required|unique:posts|max:255',
'body' => 'required',
]);
Если правило required на атрибуте title не выполнится, то правило unique не будет проверяться. Правила будут проверены в порядке их назначения.
Замечание о вложенных атрибутах
Если ваш HTTP-запрос содержит «вложенные» параметры, вы можете указать их в правилах проверки с помощью «точечной» записи:
PHP
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
]);
Вывод ошибок
Что будет, если параметры входящего запроса не пройдут проверку? Как уже было сказано, Laravel автоматически перенаправит пользователя на предыдущую страницу. Вдобавок, все ошибки будут автоматически отправлены в сессию.
Заметьте, мы не привязывали сообщения об ошибках к представлению в нашем маршруте GET. Потому что Laravel проверяет наличие ошибок в данных сессии и автоматически привязывает их к представлению, если они доступны. Поэтому важно помнить, что переменная PHP$errors будет всегда доступна во всех ваших представлениях при каждом запросе, позволяя вам всегда рассчитывать на то, что она определена и может быть безопасно использована. Переменная PHP$errors будет экземпляром IlluminateSupportMessageBag. Более подробно о работе с этим объектом читайте в его документации.
Переменная PHP$errors привязывается к представлению посредником IlluminateViewMiddlewareShareErrorsFromSession, который входит в состав группы посредников web.
Итак, в нашем примере при неудачной проверке пользователь будет перенаправлен в метод PHPcreate() нашего контроллера, позволяя нам вывести сообщения об ошибках в представлении:
PHP
<!-- /resources/views/post/create.blade.php --><
h1>Написать статью</h1>@if (
count($errors) > 0)
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif<!--
Форма написания статьи -->
Настройка формата передачи ошибок
Чтобы настроить формат ошибок проверки, передаваемых в сессию при их возникновении, переопределите formatValidationErrors в базовом контроллере. Не забудьте импортировать класс IlluminateContractsValidationValidator (для Laravel 5.0 IlluminateValidationValidator) в начале файла:
PHP
<?phpnamespace AppHttpControllers;use
IlluminateFoundationBusDispatchesJobs;
use IlluminateContractsValidationValidator;
use IlluminateRoutingController as BaseController;
use IlluminateFoundationValidationValidatesRequests;abstract class
Controller extends BaseController
{
use DispatchesJobs, ValidatesRequests;/**
* {@inheritdoc}
*/
protected function formatValidationErrors(Validator $validator)
{
return $validator->errors()->all();
}
}
AJAX-запросы и проверка ввода
В этом примере мы использовали обычную форму для отправки данных в приложение. Но многие приложения используют AJAX-запросы. При использовании метода PHPvalidate() для AJAX-запросов Laravel не создаёт отклик-переадресацию. Вместо этого Laravel создаёт JSON-отклик, содержащий все возникшие при проверке ошибки. Этот JSON-отклик будет отправлен с HTTP-кодом состояния 422.
Проверка запроса формы
Создание запроса формы
Для более сложных сценариев проверки вам может понадобиться «запрос формы». Запросы формы — изменённые классы запросов, содержащие логику проверки. Для создания класса запроса формы используйте Artisan-команду shmake:request:
shphp artisan make:request StoreBlogPost
Сгенерированный класс будет помещён в папку app/Http/Requests. Если такой папки нет, она будет создана при запуске команды shmake:request. Давайте добавим несколько правил проверки в метод PHPrules():
PHP
/**
* Получить правила проверки для применения к запросу.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|unique|max:255',
'body' => 'required',
];
}
А как же запускаются правила проверки? Надо просто указать тип запроса в методе контроллера. Входящий запрос формы проверяется до вызова метода контроллера, это значит, что вам не надо захламлять ваш контроллер логикой проверки:
PHP
/**
* Сохранить входящую статью.
*
* @param StoreBlogPost $request
* @return Response
*/
public function store(StoreBlogPost $request)
{
// Входящий запрос прошёл проверку...
}
Если проверка неуспешна, будет сгенерирован отклик-переадресация для перенаправления пользователя на предыдущую страницу. Также в сессию будут переданы ошибки, и их можно будет отобразить. Если запрос был AJAX-запросом, то пользователю будет возвращён HTTP-отклик с кодом состояния 422, содержащий JSON-представление ошибок проверки.
Авторизация запроса формы
Класс запроса формы также содержит метод PHPauthorize(). Этим методом вы можете проверить, действительно ли у авторизованного пользователя есть право на изменение данного ресурса. Например, вы можете определить, является ли пользователь владельцем комментария, который он пытается изменить:
PHP
/**
* Определить, авторизован ли пользователь для этого запроса.
*
* @return bool
*/
public function authorize()
{
$comment = Comment::find($this->route('comment')); return
$comment && $this->user()->can('update', $comment);
}
Поскольку все запросы форм наследуют базовый класс запроса Laravel, мы можем использовать метод PHPuser() для получения текущего аутентифицированного пользователя. Также обратите внимание на вызов метода PHProute() в этом примере. Этот метод даёт вам доступ к параметрам URI, определённым в вызванном маршруте, таким как параметр PHP{comment} в примере ниже:
PHP
Route::post('comment/{comment}');
Если метод PHPauthorize() возвращает false, то будет автоматически возвращён HTTP-ответ с кодом состояния 403, и метод вашего контроллера не будет выполнен.
Если вы планируете разместить логику авторизации в другой части приложения, просто верните true из метода PHPauthorize():
PHP
/**
* Определить, авторизован ли пользователь для этого запроса.
*
* @return bool
*/
public function authorize()
{
return true;
}
Настройка формата ошибок
Если хотите настроить формат сообщений об ошибках ввода, передаваемых в сессию при их возникновении, переопределите PHPformatErrors() в вашем базовом запросе (AppHttpRequestsRequest). Не забудьте импортировать класс IlluminateContractsValidationValidator в начале файла:
PHP
/**
* {@inheritdoc}
*/
protected function formatErrors(Validator $validator)
{
return $validator->errors()->all();
}
Настройка сообщений об ошибках
Для настройки сообщений об ошибках, используемых запросом формы, переопределите метод PHPmessages(). Этот метод должен возвращать массив пар атрибут/правило и соответствующие им сообщения об ошибках:
PHP
/**
* Получить сообщения об ошибках для определённых правил проверки.
*
* @return array
*/
public function messages()
{
return [
'title.required' => 'Необходимо указать заголовок',
'body.required' => 'Необходимо написать статью',
];
}
Создание валидаторов вручную
Если вы не хотите использовать метод PHPvalidate() типажа ValidatesRequests, вы можете создать экземпляр валидатора вручную с помощью фасада Validator. Метод PHPmake() этого фасада создаёт новый экземпляр валидатора:
PHP
<?phpnamespace AppHttpControllers;use
Validator;
use IlluminateHttpRequest;
use AppHttpControllersController;class
PostController extends Controller
{
/**
* Сохранить новую статью.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]); if (
$validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}// Сохранить статью...
}
}
Первый аргумент метода PHPmake() — данные для проверки. Второй — правила, которые должны быть применены к этим данным.
Если запрос не пройдёт проверку, вы можете использовать метод PHPwithErrors(), чтобы передать сообщения об ошибках в сессию. При использовании этого метода переменная PHP$errors автоматически станет общей для ваших представлений после переадресации, позволяя вам легко выводить их пользователю. Метод PHPwithErrors() принимает валидатор, MessageBag или PHP-массив.
+
5.3
добавлено в
5.3
(28.01.2017)
Автоматическая переадресация
Если вы хотите создать экземпляр валидатора вручную, но при этом иметь возможность автоматической переадресации, предлагаемой типажом ValidatesRequest, то можете вызвать метод PHPvalidate() на существующем экземпляре валидатора. Если при проверке обнаружатся ошибки, пользователь будет автоматически переадресован, а в случае AJAX-запроса будет возвращён JSON-отклик:
PHP
Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
])->validate();
+
5.0
добавлено в
5.0
(08.02.2016)
Использование массивов для указания правил
Несколько правил могут быть разделены либо прямой чертой (|), либо быть отдельными элементами массива.
PHP
$validator = Validator::make(
['name' => 'Ваня'],
['name' => ['required', 'min:5']]
);
Проверка нескольких полей
PHP
$validator = Validator::make(
[
'name' => 'Ваня',
'password' => 'плохойпароль',
'email' => 'email@example.com'
],
[
'name' => 'required',
'password' => 'required|min:8',
'email' => 'required|email|unique:users'
]
);
Когда создан экземпляр PHPValidator, метод PHPfails() (или PHPpasses()) может быть использован для проведения проверки.
PHP
if ($validator->fails()) {
// Переданные данные не прошли проверку
}
Если валидатор нашёл ошибки, вы можете получить его сообщения таким образом:
PHP
$messages = $validator->messages();
Вы также можете получить массив правил, по которым данные не прошли проверку, без самих сообщений — с помощью метода PHPfailed():
PHP
$failed = $validator->failed();
Именованные наборы ошибок
Если у вас несколько форм на одной странице, вы можете дать имена наборам ошибок MessageBag, и получать сообщения об ошибках для конкретной формы. Просто передайте имя вторым аргументом метода PHPwithErrors():
PHP
return redirect('register')
->withErrors($validator, 'login');
Теперь вы можете обращаться к экземпляру MessageBag из переменной PHP$errors:
PHP
{{ $errors->login->first('email') }}
Вебхук после проверки
Валидатор также позволяет прикрепить обратные вызовы, которые будут запущены после завершения проверки. Это позволяет легко выполнять последующие проверки, а также добавлять сообщения об ошибках в коллекцию сообщений. Для начала используйте метод PHPafter() на экземпляре класса PHPValidator:
PHP
$validator = Validator::make(...);$validator->after(function($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add('field', 'В этом поле что-то не так!');
}
});if (
$validator->fails()) {
//
}
Работа с сообщениями об ошибках
После вызова метода PHPerrors() (для Laravel 5.0 PHPmessages()) на экземпляре Validator вы получите объект PHPIlluminateSupportMessageBag, который имеет набор полезных методов для работы с сообщениями об ошибках. Переменная PHP$errors, которая автоматически становится доступной всем представлениям, также является экземпляром класса MessageBag.
Получение первого сообщения для поля
Для получения первого сообщения об ошибке для данного поля используйте метод PHPfirst():
PHP
$errors = $validator->errors();echo
$errors->first('email');
Получение всех сообщений для одного поля
Для получения массива всех сообщений для данного поля используйте метод PHPget():
PHP
foreach ($errors->get('email') as $message) {
//
}
+
5.3
добавлено в
5.3
(28.01.2017)
При проверке массива из поля вы можете получить все сообщения по каждому элементу массива с помощью символа PHP*:
PHP
foreach ($errors->get('attachments.*') as $message) {
//
}
Получение всех сообщений для всех полей
Для получения массива всех сообщения для всех полей используйте метод PHPall():
PHP
foreach ($errors->all() as $message) {
//
}
Проверка наличия сообщения для поля
Для определения наличия сообщений об ошибках для определённого поля служит метод PHPhas():
PHP
if ($messages->has('email')) {
//
}
+
5.2 5.1 5.0
добавлено в
5.2
(08.12.2016)
5.1
(19.06.2016)
5.0
(08.02.2016)
Получение ошибки в заданном формате
PHP
echo $messages->first('email', '<p>:message</p>');
По умолчанию сообщения форматируются в вид, который подходит для Bootstrap.
Получение всех сообщений в заданном формате
PHP
foreach ($messages->all('<li>:message</li>') as $message) {
//
}
Изменение сообщений об ошибках
При необходимости вы можете задать свои сообщения об ошибках проверки ввода вместо изначальных. Для этого есть несколько способов. Во-первых, вы можете передать свои сообщения третьим аргументом метода PHPValidator::make():
PHP
$messages = [
'required' => 'Необходимо указать :attribute.',
];$validator = Validator::make($input, $rules, $messages);
В этом примере обозначение :attribute будет заменено именем проверяемого поля. Вы можете использовать и другие обозначения. Например:
PHP
$messages = [
'same' => ':attribute и :other должны совпадать.',
'size' => ':attribute должен быть равен :size.',
'between' => ':attribute должен быть между :min и :max.',
'in' => ':attribute должен иметь один из следующих типов: :values',
];
Указание своего сообщения для конкретного атрибута
Иногда вам может понадобиться указать своё сообщения только для конкретного поля. Вы можете сделать это с помощью «точечной» записи. Сначала укажите имя атрибута, а затем правило:
PHP
$messages = [
'email.required' => 'Нам надо знать ваш e-mail!',
];
Указание своих сообщений в языковых файлах
В большинстве случаев вы будете указывать свои сообщения в языковом файле, а не передавать их напрямую в Validator. Для этого добавьте свои сообщения в массив custom в языковом файле resources/lang/xx/validation.php:
PHP
'custom' => [
'email' => [
'required' => 'Нам надо знать ваш e-mail!',
],
],
+
5.3
добавлено в
5.3
(28.01.2017)
Указание своих атрибутов в языковых файлах
Если вы хотите заменить часть PHP:attribute в своём сообщении о проверке ввода на своё имя атрибута, вы можете указать своё имя в массиве attributes в языковом файле resources/lang/xx/validation.php:
PHP
'attributes' => [
'email' => 'email address',
],
Доступные правила проверки
accepted
Поле должно быть в значении yes, on, 1 или true. Это полезно для проверки принятия правил и лицензий.
active_url
after:date
Поле должно быть датой, более поздней, чем date. Строки приводятся к датам функцией strtotime:
PHP
'start_date' => 'required|date|after:tomorrow'
Вместо того, чтобы передавать строку-дату в strtotime, вы можете указать другое поле для сравнения с датой:
PHP
'finish_date' => 'required|date|after:start_date'
alpha
Поле должно содержать только латинские символы.
alpha_dash
Поле должно содержать только латинские символы, цифры, знаки подчёркивания (_) и дефисы (-).
alpha_num
Поле должно содержать только латинские символы и цифры.
array
Поле должно быть PHP-массивом (тип array).
before:date
Поле должно быть датой, более ранней, чем date. Строки приводятся к датам функцией strtotime.
between:min,max
Поле должно быть числом в диапазоне от min до max. Строки, числа и файлы трактуются аналогично правилу PHPsize.
boolean
Поле должно соответствовать логическому типу. Доступные значения: true, false, 1, 0, "1" и "0".
confirmed
Значение поля должно соответствовать значению поля с этим именем, плюс _confirmation. Например, если проверяется поле password, то на вход должно быть передано совпадающее по значению поле password_confirmation.
date
Поле должно быть правильной датой в соответствии с PHP-функцией strtotime.
date_format:format
Поле должно подходить под заданный формат. При проверке поля вы должны использовать либо date, либо date_format, но не оба сразу.
different:field
Значение проверяемого поля должно отличаться от значения поля field.
digits:value
Поле должно быть числовым и иметь длину, равную value.
digits_between:min,max
Поле должно иметь длину в диапазоне между min и max.
+
5.3 5.2
добавлено в
5.3
(28.01.2017)
5.2
(08.12.2016)
dimensions
Файл должен быть изображением с подходящими под ограничения размерами, которые указаны в параметрах правила:
PHP
'avatar' => 'dimensions:min_width=100,min_height=200'
Доступные ограничения: min_width, max_width, min_height, max_height, width, height, ratio.
Ограничение ratio должно быть задано в виде ширины, поделённой на высоту. Это можно указать выражением вида PHP3/2 или в виде нецелого числа PHP1.5:
PHP
'avatar' => 'dimensions:ratio=3/2'
distinct
При работе с массивами поле не должно содержать дублирующих значений.
PHP
'foo.*.id' => 'distinct'
email
Поле должно быть корректным адресом e-mail.
exists:table,column
Поле должно существовать в заданной таблице базы данных.
Простое использование
PHP
'state' => 'exists:states'
Указание имени поля в таблице
PHP
'state' => 'exists:states,abbreviation'
+
5.2
добавлено в
5.2
(08.12.2016)
Вы также можете указать больше условий, которые будут добавлены к запросу WHERE:
PHP
'email' => 'exists:staff,email,account_id,1'
Это условие можно обратить с помощью знака ! :
PHP
'email' => 'exists:staff,email,role,!admin'
Если передать значение NULL/NOT_NULL в запрос WHERE, то это добавит проверку значения БД на совпадение с NULL/NOT_NULL:
PHP
'email' => 'exists:staff,email,deleted_at,NULL''email'
=> 'exists:staff,email,deleted_at,NOT_NULL'
+
5.3 5.2
добавлено в
5.3
(28.01.2017)
5.2
(08.12.2016)
Иногда бывает необходимо указать конкретное подключение к базе данных для запроса PHPexists. Это можно сделать, подставив имя подключения перед именем таблицы с помощью «точечного» синтаксиса:
PHP
'email' => 'exists:connection.staff,email'
+
5.3
добавлено в
5.3
(28.01.2017)
Если вы хотите изменить запрос, выполняемый правилом проверки, то можете использовать класс Rule, чтобы задать правило гибко. В этом примере мы также укажем правила проверки в виде массива, вместо использования символа PHP| для разделения правил:
PHP
use IlluminateValidationRule;Validator::make($data, [
'email' => [
'required',
Rule::exists('staff')->where(function ($query) {
$query->where('account_id', 1);
}),
],
]);
file
Поле должно быть успешно загруженным файлом.
filled
Поле не должно быть пустым, если оно есть.
image
Загруженный файл должен быть изображением в формате JPEG, PNG, BMP, GIF или SVG.
in:foo,bar,…
Значение поля должно быть одним из перечисленных (foo, bar и т.д.).
+
5.2
добавлено в
5.2
(08.12.2016)
in_array:anotherfield
Значение в поле должно быть одним из значений поля anotherfield.
integer
Поле должно иметь корректное целочисленное значение.
ip
Поле должно быть корректным IP-адресом.
json
Поле должно быть JSON-строкой.
max:value
Значение поля должно быть меньше или равно value. Строки, числа и файлы трактуются аналогично правилу PHPsize.
+
5.2
добавлено в
5.2
(08.12.2016)
mimetypes:text/plain,…
Файл должен быть одного из перечисленных MIME-типов:
PHP
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'
Для определения MIME-типа загруженного файла фреймворк прочитает его содержимое и попытается определить MIME-тип, который может отличаться от указанного клиентом.
mimes:foo,bar,…
MIME-тип загруженного файла должен быть одним из перечисленных.
Простое использование
PHP
'photo' => 'mimes:jpeg,bmp,png'
Несмотря на то, что вы просто указываете расширение файла, это правило проверяет MIME-тип файла, обращаясь к его содержимому и распознавая его MIME-тип.
Полный список MIME-типов и соответствующих им расширений можно найти по ссылке [https://svn.apache.org].
min:value
Значение поля должно быть более или равно value. Строки, числа и файлы трактуются аналогично правилу PHPsize.
+
5.3
добавлено в
5.3
(28.01.2017)
nullable
Поле может иметь значение PHPnull. Это особенно полезно при проверке таких примитивов, как строки и числа, которые могут содержать значения PHPnull.
not_in:foo,bar,…
Значение поля не должно быть одним из перечисленных (foo, bar и т.д.).
numeric
Поле должно иметь корректное числовое или дробное значение.
+
5.2
добавлено в
5.2
(08.12.2016)
present
Поле должно быть в данных ввода, но может быть пустым.
regex:pattern
Поле должно соответствовать заданному регулярному выражению.
При использовании этого правила может быть необходимо указать другие правила в виде элементов массива, вместо разделения их с помощью символа вертикальной черты, особенно если выражение содержит этот символ вертикальной черты (|).
required
Проверяемое поле должно иметь непустое значение. Поле считается «пустым», при выполнении одного из следующих условий:
- Значение поля — NULL
- Значение поля — пустая строка
- Значение поля — пустой массив или пустой Countable-объект
- Значение поля — файл для загрузки без пути
required_if:anotherfield,value,…
Проверяемое поле должно иметь непустое значение, если другое поле anotherfield имеет любое значение value.
required_unless:anotherfield,value,…
Проверяемое поле должно иметь непустое значение, если другое поле anotherfield не имеет значение value.
required_with:foo,bar,…
Проверяемое поле должно иметь непустое значение, но только если присутствует любое из перечисленных полей (foo, bar и т.д.).
required_with_all:foo,bar,…
Проверяемое поле должно иметь непустое значение, но только если присутствуют все перечисленные поля (foo, bar и т.д.).
required_without:foo,bar,…
Проверяемое поле должно иметь непустое значение, но только если не присутствует любое из перечисленных полей (foo, bar и т.д.).
required_without_all:foo,bar,…
Проверяемое поле должно иметь непустое значение, но только если не присутствуют все перечисленные поля (foo, bar и т.д.).
same:field
Поле должно иметь то же значение, что и поле field.
size:value
Поле должно иметь совпадающий с value размер. Для строк это обозначает длину, для чисел — число, для массивов — число элементов массива, для файлов — размер в килобайтах.
string
Поле должно быть строкового типа. Если вы хотите разрешить для поля значение PHPnull, назначьте на поле правило PHPnullable.
timezone
Поле должно содержать корректный идентификатор временной зоны в соответствии с PHP-функцией PHPtimezone_identifiers_list.
unique:table,column,except,idColumn
Значение поля должно быть уникальным в заданной таблице базы данных. Если column не указано, то будет использовано имя поля.
Указание имени столбца в таблице
PHP
'email' => 'unique:users,email_address'
Указание соединения с БД
Иногда вам может потребоваться задать собственное соединение для запросов к базе данных от PHPValidator. Как видно выше, правило проверки PHPunique:users будет использовать соединение с базой данных по умолчанию для запроса к базе данных. Чтобы изменить это, укажите соединение и имя таблицы, используя «точечную» запись:
PHP
'email' => 'unique:connection.users,email_address'
+
5.0
добавлено в
5.0
(08.02.2016)
PHP
$verifier = App::make('validation.presence');$verifier->setConnection('connectionName');$validator = Validator::make($input, [
'name' => 'required',
'password' => 'required|min:8',
'email' => 'required|email|unique:users',
]);$validator->setPresenceVerifier($verifier);
Игнорирование определённого ID
Иногда бывает необходимо игнорировать конкретный ID при проверке на уникальность. Например, представим экран «изменения профиля», который содержит имя пользователя, адрес e-mail и местоположение. Разумеется, вы захотите проверить уникальность e-mail. Но если пользователь изменит только поле с именем, и не изменит e-mail, вам надо избежать возникновения ошибки из-за того, что пользователь сам уже является владельцем этого e-mail.
+
5.3
добавлено в
5.3
(28.01.2017)
Чтобы валидатор игнорировал ID пользователя, мы используем класс Rule для гибкого задания правила. В этом примере мы также укажем правила проверки в виде массива, вместо использования символа PHP| для разделения правил:
PHP
use IlluminateValidationRule;Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
Если в вашей таблице используется первичный ключ с именем, отличающимся от id, укажите его при вызове метода PHPignore():
PHP
'email' => Rule::unique('users')->ignore($user->id, 'user_id')
+
5.2 5.1 5.0
добавлено в
5.2
(08.12.2016)
5.1
(19.06.2016)
5.0
(08.02.2016)
Вам надо, чтобы ошибка возникла только в том случае, когда пользователь укажет e-mail, который уже был использован другим пользователем. Чтобы правило проверки на уникальность игнорировало ID пользователя, передайте ID третьим параметром:
PHP
'email' => 'unique:users,email_address,'.$user->id
Если в вашей таблице используется первичный ключ с именем, отличающимся от id, укажите его четвёртым параметром:
PHP
'email' => 'unique:users,email_address,'.$user->id.',user_id'
Добавление дополнительных условий
+
5.3
добавлено в
5.3
(28.01.2017)
Вы также можете указать дополнительные условия запроса, изменив запрос методом PHPwhere(). Например, давайте добавим условие, которое проверяет, что PHPaccount_id равно PHP1:
PHP
'email' => Rule::unique('users')->where(function ($query) {
$query->where('account_id', 1);
})
+
5.2 5.1 5.0
добавлено в
5.2
(08.12.2016)
5.1
(19.06.2016)
5.0
(08.02.2016)
Вы также можете указать больше условий, которые будут добавлены к запросу WHERE:
PHP
'email' => 'unique:users,email_address,NULL,id,account_id,1'
В правиле выше только строки с account_id равным 1 будут включены в проверку.
url
Поле должно быть корректным URL.
Условные правила
Проверять при наличии
В некоторых случаях вам нужно запускать проверки поля, только если оно есть во входном массиве. Чтобы быстро это сделать, добавьте правило sometimes в ваш список правил:
PHP
$v = Validator::make($data, [
'email' => 'sometimes|required|email',
]);
В этом примере поле email будет проверено, только если оно есть в массиве $data.
Сложные условные проверки
Иногда вам может быть нужно, чтобы поле имело какое-либо значение, только если другое поле имеет значение, скажем, больше 100. Или вы можете требовать наличия двух полей, только когда также указано третье. Это легко достигается условными правилами. Сперва создайте объект PHPValidator с набором статичных правил, которые никогда не изменяются:
PHP
$v = Validator::make($data, [
'email' => 'required|email',
'games' => 'required|numeric',
]);
Теперь предположим, что ваше приложения написано для коллекционеров игр. Если регистрируется коллекционер с более, чем 100 играми, то мы хотим его спросить, зачем ему такое количество. Например, у него может быть магазин игр, или может ему просто нравится их собирать. Итак, для добавления такого условного правила мы используем метод PHPsometimes() на экземпляре PHPValidator:
PHP
$v->sometimes('reason', 'required|max:500', function ($input) {
return $input->games >= 100;
});
Первый аргумент этого метода — имя поля, которое мы проверяем. Второй аргумент — правило, которое мы хотим добавить, если переданная функция-замыкание (третий аргумент) вернёт true. Этот метод позволяет легко создавать сложные правила проверки ввода. Вы можете даже добавлять условные правила для нескольких полей одновременно:
PHP
$v->sometimes(['reason', 'cost'], 'required', function ($input) {
return $input->games >= 100;
});
Параметр PHP$input, передаваемый замыканию — объект IlluminateSupportFluent и может использоваться для чтения проверяемого ввода и файлов.
+
5.3 5.2
добавлено в
5.3
(28.01.2017)
5.2
(08.12.2016)
Проверка ввода массивов
Проверка ввода массива из полей ввода не должна быть сложной. Например, чтобы проверить, что каждый e-mail в данном поле ввода массива уникален, можно сделать так:
PHP
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
Также вы можете использовать символ * при задании сообщений об ошибках ввода в языковых файлах, что позволяет легко использовать одно сообщение для полей на основе массивов:
PHP
'custom' => [
'person.*.email' => [
'unique' => 'Каждый пользователь должен иметь уникальный адрес e-mail',
]
],
Собственные правила проверки
Laravel содержит множество полезных правил, однако вам может понадобиться создать собственные. Один из способов зарегистрировать произвольное правило — через метод PHPValidator::extend(). Давайте используем этот метод в сервис-провайдере для регистрации своего правила:
PHP
<?phpnamespace AppProviders;use
IlluminateSupportFacadesValidator;
//для версии 5.2 и ранее:
//use Validator;
use IlluminateSupportServiceProvider;class
AppServiceProvider extends ServiceProvider
{
/**
* Загрузка любых сервисов приложения.
*
* @return void
*/
public function boot()
{
Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
return $value == 'foo';
});
}/**
* Регистрация сервис-провайдера.
*
* @return void
*/
public function register()
{
//
}
}
Переданная функция-замыкание получает четыре аргумента: имя проверяемого поля PHP$attribute, значение поля PHP$value, массив параметров PHP$parameters, переданных правилу, и объект Validator.
Вместо замыкания в метод PHPextend() также можно передать метод класса:
PHP
Validator::extend('foo', 'FooValidator@validate');
Определение сообщения об ошибке
Вам также понадобится определить сообщение об ошибке для нового правила. Вы можете сделать это либо передавая его в виде массива строк в PHPValidator, либо вписав в языковой файл. Это сообщение необходимо поместить на первом уровне массива, а не в массив custom, который используется только для сообщений по конкретным полям:
PHP
"foo" => "Your input was invalid!","accepted" => "The :attribute must be accepted.",// Остальные сообщения об ошибках...
+
5.0
добавлено в
5.0
(08.02.2016)
Расширение класса PHPValidator
Вместо использования функций-замыканий для расширения набора доступных правил вы можете расширить сам класс PHPValidator. Для этого создайте класс, который наследует IlluminateValidationValidator. Вы можете добавить новые методы проверок, начав их имя с validate:
PHP
<?phpclass CustomValidator extends IlluminateValidationValidatorpublic function validateFoo($attribute, $value, $parameters)
{
return $value == 'foo';
}}
Регистрация нового класса PHPValidator
Затем вам нужно зарегистрировать собственное расширение:
PHP
Validator::resolver(function($translator, $data, $rules, $messages)
{
return new CustomValidator($translator, $data, $rules, $messages);
});
Иногда при создании своего правила вам может понадобиться определить собственные строки-переменные для замены в сообщениях об ошибках. Это делается путём создания класса, как было описано выше, и вызовом метода PHPValidator::replacer(). Это можно сделать в методе PHPboot() сервис-провайдера:
PHP
/**
* Загрузка любых сервисов приложения.
*
* @return void
*/
public function boot()
{
Validator::extend(...);Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
return str_replace(...);
});
}
+
5.0
добавлено в
5.0
(08.02.2016)
Это делается путём создания класса, как было описано выше, и добавлением функций с именами вида PHPreplaceXXX().
PHP
protected function replaceFoo($message, $attribute, $rule, $parameters)
{
return str_replace(':foo', $parameters[0], $message);
}
Неявное наследование
По умолчанию, если проверяемое поле отсутствует или имеет пустое значение по правилу required, обычные правила не запускаются, в том числе собственные правила. Например, правило unique не будет запущено для значения null:
PHP
$rules = ['name' => 'unique'];$input = ['name' => null];Validator::make($input, $rules)->passes(); // true
Чтобы применять правило даже для пустых полей, правило должно считать, что поле обязательное. Для создания такого «неявного» наследования используйте метод PHPValidator::extendImplicit():
PHP
Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
return $value == 'foo';
});
«Неявное» наследование только указывает на обязательность поля. А будет ли правило пропускать пустое или отсутствующее поле или нет, зависит от вас.
Как проверить CSS и HTML-код на валидность и зачем это нужно.
В статье:
-
Что такое валидность кода
-
Чем ошибки в HTML грозят сайту
-
Как проверить код на валидность
-
HTML и CSS валидаторы — онлайн-сервисы для проверки кода
Разберем, насколько критическими для работы сайта и его продвижения могут быть ошибки в HTML-коде, и зачем нужны общие стандарты верстки.
Что такое валидность кода
После разработки дизайна программисты верстают страницы сайта — приводят их к единой структуре в формате HTML. Задача верстальщика — сделать так, чтобы страницы отображались корректно у всех пользователей на любых устройствах и браузерах. Такая верстка называется кроссплатформенной и кроссбраузерной — это обязательное требование при разработке любых сайтов.
Для этого есть специальные стандарты: если им следовать, страницу будут корректно распознавать все браузеры и гаджеты. Такой стандарт разработал Консорциумом всемирной паутины — W3C (The World Wide Web Consortium). HTML-код, который ему соответствует, называют валидным.
Валидность также касается файлов стилей — CSS. Если в CSS есть ошибки, визуальное отображение элементов может нарушиться.
Разработчикам рекомендуется следовать критериям этих стандартов при верстке — это поможет избежать ошибок в коде, которые могут навредить сайту.
Чем ошибки в HTML грозят сайту
Типичные ошибки кода — незакрытые или дублированные элементы, неправильные атрибуты или их отсутствие, отсутствие кодировки UTF-8 или указания типа документа.
Какие проблемы могут возникнуть из-за ошибок в HTML-коде
- страницы загружаются медленно;
- сайт некорректно отображается на разных устройствах или в браузерах;
- посетители видят не весь контент;
- программист не замечает скрытую рекламу и вредоносный код.
Как валидность кода влияет на SEO
Валидность не является фактором ранжирования в Яндекс или Google, так что напрямую она не влияет на позиции сайта в выдаче поисковых систем. Но она влияет на мобилопригодность сайта и на то, как поисковые боты воспринимают разметку, а от этого косвенно могут пострадать позиции или трафик.
Почитать по теме:
Главное о микроразметке: подборка знаний для веб-мастеров
Представитель Google Джон Мюллер говорил о валидности кода:
«Мы упомянули использование правильного HTML. Является ли фактором ранжирования валидность HTML стандарту W3C?
Это не прямой фактор ранжирования. Если ваш сайт использует HTML с ошибками, это не значит, что мы удалим его из индекса — я думаю, что тогда у нас будут пустые результаты поиска.
Но есть несколько важных аспектов:— Если у сайта действительно битый HTML, тогда нам будет очень сложно его отсканировать и проиндексировать.
— Иногда действительно трудно подобрать структурированную разметку, если HTML полностью нарушен, поэтому используйте валидатор разметки.
— Другой аспект касается мобильных устройств и поддержки кроссбраузерности: если вы сломали HTML, то сайт иногда очень трудно рендерить на новых устройствах».
Итак, критические ошибки в HTML мешают
- сканированию сайта поисковыми ботами;
- определению структурированной разметки на странице;
- рендерингу на мобильных устройствах и кроссбраузерности.
Даже если вы уверены в своем коде, лучше его проверить — ошибки могут возникать из-за установки тем, сторонних плагинов и других элементов, и быть незаметными. Не все программисты ориентируются на стандарт W3C, так что среди готовых решений могут быть продукты с ошибками, особенно среди бесплатных.
Как проверить код на валидность
Не нужно вычитывать код и считать символы — для этого есть сервисы и инструменты проверки валидности HTML онлайн.
Что они проверяют:
- Синтаксис
Синтаксические ошибки: пропущенные символы, ошибки в написании тегов. - Вложенность тэгов
Незакрытые и неправильно закрытые теги. По правилам теги закрываются также, как их открыли, но в обратном порядке. Частая ошибка — нарушенная вложенность.
- DTD (Document Type Definition)
Соответствие кода указанному DTD, правильность названий тегов, вложенности, атрибутов. Наличие пользовательских тегов и атрибутов — то, чего нет в DTD, но есть в коде.
Обычно сервисы делят результаты на ошибки и предупреждения. Ошибки — опечатки в коде, пропущенные или лишние символы, которые скорее всего создадут проблемы. Предупреждения — бессмысленная разметка, лишние символы, какие-то другие ошибки, которые скорее всего не навредят сайту, но идут вразрез с принятым стандартом.
Валидаторы не всегда правы — некоторые ошибки не мешают браузерам воспринимать код корректно, зато, к примеру, минификация сокращает длину кода, удаляя лишние пробелы, которые не влияют на его отображение.
Почитать по теме:
Уменьшить вес сайта с помощью gzip, brotli, минификации и других способов
Поэтому анализируйте предложения сервисов по исправлениям и ориентируйтесь на здравый смысл.
Перед исправлением ошибок не забудьте сделать резервное копирование. Если вы исправите код, но что-то пойдет не так и он перестанет отображаться, как должен, вы сможете откатить все назад.
HTML и CSS валидаторы — онлайн-сервисы для проверки кода
Есть довольно много валидаторов, выберите тот, в котором вам удобнее работать. Мы рекомендуем использовать известные сервисы от создателей стандартов. Если пояснения на английском воспринимать сложно, можно использовать автоматический перевод страницы.
Валидатор от W3C
Англоязычный сервис, онлайн проверяет соответствие HTML стандартам: можно проверить код по URL, залить файл или вставить код в окошко.
Инструмент покажет список ошибок и предупреждений с пояснениями — описанием ошибки и ее типом, а также укажет номер строки, в которой нужно что-то исправить. Цветом отмечены типы предупреждений и строчки с кодом.
Валидатор CSS от W3C
Инструмент от W3C для проверки CSS, есть русский язык. Работает по такому же принципу, анализирует стили на предмет ошибок и предупреждений. Первым идет блок ошибок, предупреждения собраны ниже отдельно.
Исправления ошибок и валидации HTML и CSS может быть недостаточно: всегда есть другие возможности испортить отображение сайта. Если что-то не работает, как надо, проведите полноценный аудит, чтобы найти ошибки.
С другой стороны, не зацикливайтесь на поиске недочетов в HTML — если код работает, а контент отображается корректно, лучше направить ресурсы на что-то другое — оптимизацию и ускорение загрузки, например.
Краткий пример
Пример валидации формы и вывод сообщений об ошибках для пользователя.
Определение роутов
Создадим роуты в файле routes/web.php:
Route::get('post/create', 'PostController@create');
Route::post('post', 'PostController@store');
Роут GET отображает форму для создания нового поста в блоге, POST будет сохранять новую запись в базе данных.
Создание контроллера
Контроллер, который обрабатывает эти роуты. Метод store пока остался пустым:
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppHttpControllersController;
class PostController extends Controller
{
/**
* Показать форму для создания новой записи в блоге.
*
* @return Response
*/
public function create()
{
return view('post.create');
}
/**
* Хранить новую запись в блоге.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// Validate and store the blog post...
}
}
Написание логики валидации
Заполняем метод store валидацией при создания нового поста. Если проанализировать базовый контроллер (AppHttpControllersController), видно, что он включает в себя трейт ValidatesRequests, который обеспечивает все контроллеры удобным методом validate.
Метод validate принимает два параметра экземпляр HTTP запроса и правила валидации. Если все правила не нарушены, код будет выполняться далее. Однако, если проверка не пройдена, будет выброшено исключение и сообщение об ошибке автоматически отправится обратно пользователю. В HTTP запросе ответ будет перенаправлен обратно с заполненными flash-переменными, в то время как на AJAX запрос отправится JSON.
Для понимания метода validate, пример store:
/**
* Store a new blog post.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid, store in database...
}
Остановка после первой неудачной проверки
Если нужно остановить выполнение остальных правил после первой неудачной проверки. Для этого используется атрибут bail:
$this->validate($request, [
'title' => 'bail|unique:posts|max:255',
'body' => 'required',
]);
В этом примере, если для атрибута title не выполняется правило required, следующие правило unique проверяться не будет.
Проверка вложенных атрибутах (массив)
Если данные HTTP запроса содержат «вложенные» параметры, можно указать их, используя синтаксис с точкой:
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
]);
Отображение ошибок валидации
В примере пользователь будет перенаправлен в метод create контроллера и можно отобразить сообщения об ошибках в шаблоне:
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- Create Post Form -->
Дополнительные поля
По умолчанию в Laravel включены глобальные посредники TrimStrings и mptConvertEyStringsToNull. Они перечислены в свойстве $middleware класса AppHttpKernel. Из-за этого нужно часто помечать дополнительные поля как nullable, если не нужно, чтобы валидатор считал не действительным значение null. Например:
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
'publish_at' => 'nullable|date',
]);
В этом примере указано что поле publish_at может быть null или должно содержать дату. Если модификатор nullable не добавляется в правило, проверяющий элемент будет рассматривать null как недопустимую дату.
Настройка формата вывода ошибок валидации
Для настройки вывода ошибок валидации, которые будут во flash-переменных после нарушений правил, нужно переопределить метод formatValidationErrors в базовом контроллере и подключить класс IlluminateContractsValidationValidator:
<?php
namespace AppHttpControllers;
use IlluminateFoundationBusDispatchesJobs;
use IlluminateContractsValidationValidator;
use IlluminateRoutingController as BaseController;
use IlluminateFoundationValidationValidatesRequests;
abstract class Controller extends BaseController
{
use DispatchesJobs, ValidatesRequests;
/**
* {@inheritdoc}
*/
protected function formatValidationErrors(Validator $validator)
{
return $validator->errors()->all();
}
}
AJAX запросы и валидация
При использовании метода validate во время запроса AJAX, Laravel не будет генерировать ответ с перенаправлением. Вместо этого Laravel генерирует ответ с JSON данными, содержащий в себе все ошибки проверки. Этот ответ будет отправлен с кодом состояния HTTP 422.
Валидация form request
Создание Form Request
# php artisan make:request StoreBlogPost
Сгенерированный класс будет размещен в каталоге app/Http/Requests
Для проверки используется метод rules:
/**
* Получить правила валидации, применимые к запросу.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
Для проверки валидации необходимо в методе контроллера для входящей переменной указать класс как тип переменной
/**
* Store the incoming blog post.
*
* @param StoreBlogPost $request
* @return Response
*/
public function store(StoreBlogPost $request)
{
// The incoming request is valid...
}
Если проверка не пройдена, то при традиционном запросе ошибки будут записываться в сессию и будут доступны в шаблонах, иначе, если запрос был AJAX, HTTP-ответ с кодом 422 будет возвращен пользователю, включая JSON с ошибками валидации.
Добавление хуков в Form Request
Если необходимо добавить хук «after» в Form Requests, можно использовать метод withValidator. Этот метод получает полностью сформированный валидатор, позволяя вызвать любой из его методов, прежде чем фактически применяются правила:
/**
* Настройка экземпляра валидатора.
*
* @param IlluminateValidationValidator $validator
* @return void
*/
public function withValidator($validator)
{
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add('field', 'Something is wrong with this field!');
}
});
}
Авторизация Form Request
Класс Form Request содержит в себе метод authorize. В этом методе можно проверить, имеет ли аутентифицированный пользователь права на выполнение данного запроса. Например, можно проверить, есть ли у пользователя право для добавления комментариев в блог:
/**
* Определить авторизован ли пользователь делать такой запрос.
*
* @return bool
*/
public function authorize()
{
$comment = Comment::find($this->route('comment'));
return $comment && $this->user()->can('update', $comment);
}
Form Request расширяет базовый класс Request, и можно использовать метод user, чтобы получить доступ к текущему пользователю. Вызов метода route предоставляет доступ к параметрам URI, определенным в роуте (в приведенном ниже примере это {comment}):
Route::post('comment/{comment}');
Если метод authorize возвращает false, автоматически генерируется ответ с кодом 403 и метод контроллера не выполняется.
Если же логика авторизации организована в другом месте приложения, просто достаточно вернуть true из метода authorize:
/**
* Определить авторизован ли пользователь делать такой запрос.
*
* @return bool
*/
public function authorize()
{
return true;
}
Настройка формата вывода ошибок
Если нужно настроить формат вывода ошибок валидации, которые будут заполнять flash-переменные при неудачном выполнении, необходимо переопредилить метод formatErrors в базовом request (AppHttpRequestsRequest). Должен быт подключен класс IlluminateContractsValidationValidator:
/**
* {@inheritdoc}
*/
protected function formatErrors(Validator $validator)
{
return $validator->errors()->all();
}
Настройка сообщений об ошибках
Для кастомизации сообщений об ошибках, используется в form request метод messages. Этот метод должен возвращать массив атрибутов/правил и их соответствующие сообщения об ошибках:
/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function messages()
{
return [
'title.required' => 'A title is required',
'body.required' => 'A message is required',
];
}
Создание валидаторов вручную
<?php
namespace AppHttpControllers;
use Validator;
use IlluminateHttpRequest;
use AppHttpControllersController;
class PostController extends Controller
{
/**
* Store a new blog post.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
// Store the blog post...
}
}
Первый аргумент, передаваемый в метод make, получает данные для проверки. Вторым аргументом идут правилами проверки, которые должны применяться к данным.
После проверки, если валидация не будет пройдена, можно использовать метод withErrors для загрузки ошибок во flash-переменные. При использовании этого метода переменная $errors будет автоматически передаваться в макеты, после перенаправления, что позволяет легко отображать данные пользователю. Метод withErrors принимает экземпляр валидатора и MessageBag или простой массив.
Автоматическое перенаправление
Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
])->validate();
MessageBag
Если есть несколько форм на одной страницы, которые необходимо провалидировать, понадобится MessageBag — он позволяет получать сообщения об ошибках для определенной формы. Нужно передайть имя в качестве второго аргумента withErrors:
return redirect('register')
->withErrors($validator, 'login');
Затем можно получить доступ к именованному экземпляру MessageBag из переменной $errors:
{{ $errors->login->first('email') }}
Хук после валидации
Валидатор также позволяет использовать функции обратного вызова после завершения всех проверок. Это позволяет легко выполнять дальнейшие проверки и даже добавить больше сообщений об ошибках в коллекции сообщений. Для начала работы нужно использовать метод after в экземпляре валидатора:
$validator = Validator::make(...);
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add('field', 'Something is wrong with this field!');
}
});
if ($validator->fails()) {
//
}
Работа с сообщениями об ошибках
После вызова метода errors в экземпляре валидатора, получаем экземпляр IlluminateSupportMessageBag, который имеет целый ряд удобных методов для работы с сообщениями об ошибках. Переменная $errors, которая автоматически становится доступной для всех макетов, также является экземпляром класса MessageBag.
Извлечение первого для поля сообщения об ошибке
$errors = $validator->errors();
echo $errors->first('email');
Извлечение всех сообщений об ошибках для одного поля
foreach ($errors->get('email') as $message) {
//
}
Если выполняется проверка поля формы с массивом, можно получить все сообщения для каждого из элементов массива с помощью символа *:
foreach ($errors->get('attachments.*') as $message) {
//
}
Получение всех сообщений об ошибках для всех полей
foreach ($errors->all() as $message) {
//
}
Определить наличие сообщения для определенного поля
if ($errors->has('email')) {
//
}
Пользовательские сообщения об ошибках
При необходимости, можно использовать свои сообщения об ошибках вместо значений по умолчанию. Существует несколько способов для указания кастомных сообщений. Можно передать сообщения в качестве третьего аргумента в метод Validator::make:
$messages = [
'required' => 'The :attribute field is required.',
];
$validator = Validator::make($input, $rules, $messages);
В этом примере :attributeбудет заменен на имя проверяемого поля. Можено использовать и другие строки-переменные. Пример:
$messages = [
'same' => 'The :attribute and :other must match.',
'size' => 'The :attribute must be exactly :size.',
'between' => 'The :attribute must be between :min - :max.',
'in' => 'The :attribute must be one of the following types: :values',
];
Указание пользовательского сообщения для заданного атрибута
$messages = [
'email.required' => 'We need to know your e-mail address!',
];
Указание собственных сообщений в файлах локализации
Также можно определять сообщения в файле локализации вместо того, чтобы передавать их в валидатор напрямую. Для этого нужно добавить сообщения в массив custom файла локализации resources/lang/xx/validation.php.
'custom' => [
'email' => [
'required' => 'We need to know your e-mail address!',
],
],
Указание пользовательских атрибутов в файлах локализации
Если необходимо, чтобы :attribute был заменен на кастомное имя, можно указать в массиве attributes файле локализации resources/lang/xx/validation.php:
'attributes' => [
'email' => 'email address',
],
Доступные правила валидации
accepted — поле должно быть в значении yes, on или 1. Это полезно для проверки принятия правил и лицензий.
active_url — поле должно иметь действительную A или AAAA DNS-запись согласно функции PHP dns_get_record.
after:date — поле проверки должно быть после date. Строки приводятся к датам функцией strtotime:
'start_date' => 'required|date|after:tomorrow'
Вместо того чтобы приводить строки к датам, вы можете указать другое поле для сравнения даты:
'finish_date' => 'required|date|after:start_date'
after_or_equal:date — поле проверки должно быть после или равно date. Для получения дополнительной информации смотрите правило after
alpha — поле должно содержать только алфавитные символы.
alpha_dash — поле можно содержать только алфавитные символы, цифры, знаки подчёркивания _ и дефисы -.
alpha_num — поле можно содержать только алфавитные символы и цифры.
array — поле должно быть PHP-массивом.
before:date — поле должно быть датой более ранней, чем заданная дата. Строки приводятся к датам функцией strtotime.
before_or_equal:date — поле должно быть более ранней или равной заданной дате. Строки приводятся к датам функцией strtotime.
between:min,max — поле должно быть числом в диапазоне от min до max. Размеры строк, чисел и файлов трактуются аналогично правилу size.
boolean — поле должно быть логическим (булевым). Разрешенные значения: true, false, 1, 0, «1», и «0».
confirmed — значение поля должно соответствовать значению поля с этим именем, плюс foo_confirmation. Например, если проверяется поле password, то на вход должно быть передано совпадающее по значению поле password_confirmation.
date — поле должно быть правильной датой в соответствии с PHP функцией strtotime.
date_format:format — поле должно соответствовать заданному формату. Необходимо использовать функцию date или date_format при проверке поля, но не обе.
different:field — значение проверяемого поля должно отличаться от значения поля field.
digits:value — поле должно быть числовым и иметь точную длину значения.
digits_between:min,max — длина значения поля проверки должна быть между min и max.
dimensions — файл изображения должен иметь ограничения согласно параметрам:
'avatar' => 'dimensions:min_width=100,min_height=200'
Доступные ограничения: _min_width_, _max_width_, _min_height_, _max_height_, width, height, ratio.
Ограничение ratio должно быть представлено как ширина к высоте. Это может быть обыкновенная (3/2) или десятичная (1.5) дробь:
'avatar' => 'dimensions:ratio=3/2'
Поскольку это правило требует несколько аргументов, вы можете использовать метод Rule::dimensions:
use IlluminateValidationRule;
Validator::make($data, [
'avatar' => [
'required',
Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
],
]);
distinct — при работе с массивами, поле не должно иметь повторяющихся значений.
'foo.*.id' => 'distinct'
email — поле должно быть корректным адресом e-mail.
exists:table,column — поле должно существовать в указанной таблице базы данных.
базовое использование правила Exists
'state' => 'exists:states'
указание пользовательского названия столбца
'state' => 'exists:states,abbreviation'
Иногда может потребоваться подключение к базе данных и использование в запросе exists, этого можно добиться путем добавления к соединению название таблицы, используя синтаксис с точкой:
'email' => 'exists:connection.staff,email'
Если бы вы хотите модифицировать запрос, можно использовать класс Rule, в данном примере мы будем использовать массив вместо знака |:
use IlluminateValidationRule;
Validator::make($data, [
'email' => [
'required',
Rule::exists('staff')->where(function ($query) {
$query->where('account_id', 1);
}),
],
]);
file — поле должно быть успешно загруженным файлом.
filled — поле не должно быть пустым.
image — загруженный файл должен быть в формате jpeg, png, bmp, gif или svg.
in:foo,bar,… -значение поля должно быть одним из перечисленных. Поскольку это правило иногда вынуждает вас использовать функцию implode, для этого случая есть метод Rule::in:
use IlluminateValidationRule;
Validator::make($data, [
'zones' => [
'required',
Rule::in(['first-zone', 'second-zone']),
],
]);
in_array:anotherfield — в массиве должны существовать значения anotherfield.
integer — поле должно иметь корректное целочисленное значение.
ip — поле должно быть корректным IP-адресом.
ipv4 — поле должно быть IPv4-адресом.
ipv6 — поле должно быть IPv6-адресом.
json — поле должно быть валидной строкой JSON.
max:value — значение поля должно быть меньше или равно value. Размеры строк, чисел и файлов трактуются аналогично правилу size.
mimetypes:text/plain,… — MIME-тип загруженного файла должен быть одним из перечисленных:
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'
Чтобы определить MIME-тип загруженного файла, фреймворк будет читать содержимое и пытаться угадать MIME-тип, который может отличаться от того, что указал пользователь.
mimes:foo,bar,… — MIME-тип загруженного файла должен быть одним из перечисленных.
Основное использование MIME-правила
'photo' => 'mimes:jpeg,bmp,png'
Даже если необходимо только указать расширение, это правило проверяет MIME-тип файла, читая содержимое файла и пытаясь угадать его.
Полный список MIME-типов и соответствующие им расширения можно найти в: https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
min:value — Значение поля должно быть больше value. Размеры строк, чисел и файлов трактуются аналогично правилу size.
nullable — поле может быть равно null. Это особенно полезно при проверке примитивов, такие как строки и целые числа, которые могут содержать null значения.
not_in:foo,bar,… — поле не должно быть включено в заданный список значений. Метод Rule::notIn можно использовать для конструирования этого правила:
use IlluminateValidationRule;
Validator::make($data, [
'toppings' => [
'required',
Rule::notIn(['sprinkles', 'cherries']),
],
]);
numeric — поле должно иметь корректное числовое или дробное значение.
present — поле для проверки должно присутствовать во входных данных, но может быть пустым.
regex:pattern — поле должно соответствовать заданному регулярному выражению.
Примечание: Для использования regex может быть необходимо определить правила в виде массива вместо использования разделителя, особенно если регулярное выражение содержит символ разделителя.
required — проверяемое поле должно иметь непустое значение. Поле считается пустым, если одно из следующих значений верно:
- если значение равно null.
- если значение — пустая строка.
- если значение является пустым массивом или пустым объектом Countable.
- если значение это загруженный файл без пути.
required_if:anotherfield,value,… — поле должно присутствовать и не быть пустым, если anotherfield равно любому value.
required_unless:anotherfield,value,… — поле должно присутствовать и не быть пустым, за исключением случая, когда anotherfield равно любому value.
required_with:foo,bar,… — проверяемое поле должно иметь непустое значение, но только если присутствует хотя бы одно из перечисленных полей (foo, bar и т.д.).
required_with_all:foo,bar,… — проверяемое поле должно иметь непустое значение, но только если присутствуют все перечисленные поля (foo, bar и т.д.).
required_without:foo,bar,… — проверяемое поле должно иметь непустое значение, но только если не присутствует хотя бы одно из перечисленных полей (foo, bar и т.д.).
required_without_all:foo,bar,… — проверяемое поле должно иметь непустое значение, но только если не присутствуют все перечисленные поля (foo, bar и т.д.).
same:field — поле должно иметь то же значение, что и поле field.
size:value — поле должно иметь совпадающий с value размер. Для строковых данных value соответствует количество символов, для массива size соответствует количеству элементов массива, для чисел — число, для файлов — размер в килобайтах.
string — поле должно быть строкой. Если вы хотите, чтобы поле было null, следует доолнитель указать это полю правило nullable.
timezone — поле должно содержать идентификатор часового пояса (таймзоны), один из перечисленных в php-функции timezone_identifiers_list.
unique:table,column,except,idColumn — значение поля должно быть уникальным в заданной таблице базы данных. Если column не указано, то будет использовано имя поля.
указание пользовательского названия столбца:
'email' => 'unique:users,email_address'
пользовательское подключение к БД
иногда может понадобиться установить собственное соединение с базой данных, как замечено выше, параметр unique:users, будет использовать соединение по умолчанию. Чтобы переопределить это, нужно указать подключение и имя таблицы через синтаксис с точкой:
'email' => 'unique:connection.users,email_address'
игнорирование ID при проверке на уникальность:
иногда потребуется игнорировать ID при проверке на уникальность. Например, рассмотрим обновление профиля пользователя, который включает в себя имя пользователя, адрес электронной почты и местоположение. Конечно, вы хотите убедиться, что адрес электронной почты является уникальным. Однако, если пользователь изменяет только имя и не изменяет электронную почту, нам не требуется вывод ошибки, но тем не менее возникнет исключение, поскольку пользователь уже является владельцем адреса электронной почты.
Для того, чтобы игнорировать ID пользователя, мы будем использовать класс Rule который позволяет гибко строить наши правила в таком случае. В примере, мы укажем правила в качестве массива вместо | символа-разделителя:
use IlluminateValidationRule;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
Если таблица использует имя столбца первичного ключа помимо id, можно указать имя столбца при вызове метода ignore:
'email' => Rule::unique('users')->ignore($user->id, 'user_id')
Добавление дополнительных условий Where:
Вы также можете указать дополнительные условия, используя метод where. Например, давайте добавим ограничение, которое проверяет, что account_id равно 1:
'email' => Rule::unique('users')->where(function ($query) {
$query->where('account_id', 1);
})
url — поле должно быть корректным URL.
Добавление правил с условиями
Валидация при наличии поля
Иногда нужно проверить некое поле только тогда, когда оно присутствует во входных данных. Для этого добавьте правило sometimes:
$v = Validator::make($data, [
'email' => 'sometimes|required|email',
]);
В примере выше для поля email будет запущена валидация только, когда оно присутствует в массиве $data.
Сложная составная проверка
Иногда возникает необходимость добавить правила с более сложной логикой проверки. Например, потребовать поле, только если другое поле имеет значение большее, чем 100. Или понадобится два поля, когда другое поле присутствует. Добавление этих правил не должно вызывать затруднения. Создается экземпляр Validator с постоянными правилами, которые никогда не изменятся:
$v = Validator::make($data, [
'email' => 'required|email',
'games' => 'required|numeric',
]);
Предположим, что веб-приложение для коллекционеров игр. Если коллекционер регистрирует в приложении игру и он владеет больше чем 100 играми в данный момент, нужно, чтобы он объяснил, почему он владеет таким количеством игр. Возможно, он управляет магазином игр, или возможно, он просто любит их собирать. Чтобы добавить это требование, можно использовать метод sometimes в экземпляре валидатора:
$v->sometimes('reason', 'required|max:500', function ($input) {
return $input->games >= 100;
});
Первый аргумент, переданный в метод sometimes это имя поля, которое условно проверяется. Второй аргумент — правила, которые нужно добавить. Если анонимная функция передается как третий аргумент, и возвращает значение true, то правила будут добавлены. Этот метод универсален для того, чтобы строить целый комплекс условных проверок. Можно даже добавить условные проверки на нескольких полях одновременно:
$v->sometimes(['reason', 'cost'], 'required', function ($input) {
return $input->games >= 100;
});
Параметр $input переданный в анонимную функцию, будет экземпляром IlluminateSupportFluent и может быть использован для доступа к полям и файлам.
Валидация массивов
Чтобы проверить, что каждая последующая электронная почта является уникальной, вы можете сделать следующее:
$validator = Validator::make($request->all(), [
'photos.profile' => 'required|image',
]);
* — использовать одно сообщение для проверки массива полей:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
Можно использовать символ * при указании сообщений валидации в языковых файлах, значительно упрощая использование одного сообщения валидации для полей, основанных на массивах:
'custom' => [
'person.*.email' => [
'unique' => 'Each person must have a unique e-mail address',
]
],
Собственные правила валидации
Laravel предоставляет разнообразные и полезные правила для валидации. Однако, возможно, потребуется определить некоторые из своих собственных. Один из методов регистрации своих правил метод extend фасада Validator. Пример регистрации этого метода в сервис-провайдере:
<?php
namespace AppProviders;
use IlluminateSupportServiceProvider;
use IlluminateSupportFacadesValidator;
class AppServiceProvider extends ServiceProvider
{
/**
* Предварительная загрузка любых сервисов приложения.
*
* @return void
*/
public function boot()
{
Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
return $value == 'foo';
});
}
/**
* Регистрация нового сервис-провайдера.
*
* @return void
*/
public function register()
{
//
}
}
Анонимная функция получает четыре аргумента: имя проверяемого поля ($attribute), значение поля ($value), массив дополнительных параметров ($parameters) и экземпляр валидатора ($validator).
Класс и метод также можно передать методу extend вместо анонимной функции:
Validator::extend('foo', 'FooValidator@validate');
Определение сообщения об ошибки
Правила сообщений об ошибке можно передавть в виде массива строк в валидатор, либо добавив в файл локализации. Это сообщение должно помещаться на первом уровне массива, но не в массиве custom, который появляется только для сообщения об ошибке конкретного атрибута:
"foo" => "Your input was invalid!",
"accepted" => "The :attribute must be accepted.",
// The rest of the validation error messages...
При создании своих правил проверки, может потребоваться определить места замены для сообщений об ошибках. Можно сделать это, реализовав через метод replacer в фасаде Validator. Действие необходимо определить внутри метода boot сервис-провайдера:
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Validator::extend(...);
Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
return str_replace(...);
});
}
Скрытые расширения
По умолчанию, когда проверяемый атрибут отсутствует или содержит пустое значение, как в правиле required, валидация не выполняется, в том числе и для расширений. Например, unique не будет выполнено для значения null:
$rules = ['name' => 'unique'];
$input = ['name' => null];
Validator::make($input, $rules)->passes(); // true
Правило должно подразумевать, что атрибут обязателен, даже, если он пуст. Для создания «скрытых» расширений используйте метод Validator::extendImplicit():
Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
return $value == 'foo';
});
«Скрытое» расширение лишь подразумевает, что атрибут является обязательным.
В прошлых статьях был рассмотрен механизм валидации принимаемых данных. Рекомендуем посмотреть эти статьи:
- Проверка принимаемых данных в Laravel
- Проверка принимаемых данных в Laravel (часть 2)
В этой статье будет подробнее описан способ изменения сообщений, которые выдаются в процессе обработки ошибок.
Изменение сообщений об ошибках
Существует несколько способов для задания своих текстов сообщений об ошибках валидации. Первый — можно передать текст сообщения третьим аргументом для метода «make» класса «Validator»:
<?php
$messages = [
'required' => 'Необходимо заполнить поле :attribute.',
];
$validator = Validator::make($input, $rules, $messages);
?>
Обратите внимание на «:attribute» в тексте сообщения. Оно будет заменено на имя передаваемого поля. Приведём другие примеры автоматической подстановки таких значений:
<?php
$messages = [
'same' => ':attribute и :other должны совпадать.',
'size' => ':attribute должен быть равен :size.',
'between' => ':attribute должен быть между :min и :max.',
'in' => ':attribute должен иметь один из следующих типов: :values',
];
?>
Если нужно установить текст ошибки только для конкретного поля, а не для всех подобных ошибок во всех полях, то необходимо записать его через точку «имя_атрибута.правило»:
<?php
$messages = [
'email.required' => 'Нам надо знать ваш e-mail!',
];
?>
Сообщения на разных языках
Ситуация с передачей текста сообщения напрямую в «validator» встречается довольно редко. Обычно сообщения записываются в языковом файле resources/lang/xx/validation.php. Там они записываются
<?php
'custom' => [
'email' => [
'required' => 'Пожалуйста, введите свой e-mail',
],
],
?>
Кроме того в этом файле файле можно указывать свои шаблоны для замены (как с «:attribute»):
<?php
'attributes' => [
'email' => 'адрес электронной почты',
],
?>
Была ли эта статья полезна?
Есть вопрос?
Закажите недорогой хостинг
Заказать
всего от 290 руб












