Наличие ошибок в коде страницы сайта всегда влечет за собой негативные последствия – от ухудшения позиций в ранжировании до жалоб со стороны пользователей. Ошибки валидации могут наблюдаться как на главной, так и на иных веб-страницах, их наличие свидетельствует о том, что ресурс является невалидным. Некоторые проблемы замечают даже неподготовленные пользователи, другие невозможно обнаружить без предварительного аудита, анализа. О том, что такое ошибки валидации и как их обнаружить, мы сейчас расскажем.
Ошибка валидации, что это такое?
Для написания страниц используется 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 типа проблем с разметкой — предупреждения и ошибки.
Работать необходимо сразу с двумя типами ошибок. Даже если предупреждение не приведет к неисправности сайта, оставлять без внимания проблемные блоки нельзя, так как это снизит привлекательность ресурса в глазах пользователя. Ошибки же могут привести к невозможности отображения блоков на сайте, понижению сайта в поисковой выдаче или полному игнорированию ресурса со стороны поискового бота.
Даже у крупных сайтов с миллионной аудиторией, например, Яндекс.Дзен или ВКонтакте, есть проблемы с кодом. Но комплексный подход к решению проблем помогает устранять серьёзные моменты своевременно. Нужно развивать сайт всесторонне, чтобы получить результат от его существования и поддержки. Если самостоятельно разобраться с проблемами не получается, не стоит “доламывать” — лучше обратиться за помощью к профессионалам, например, агентствам по веб-аудиту.
Ошибки валидации – это ошибки в коде страниц сайта, при этом ошибки на главной странице и на внутренних страницах сайта могут отличаться друг от друга. Сайт считается валидным, если у него отсутствуют ошибки в коде страниц сайта. Ошибки могут появляться в ходе разработки сайта, например, когда неверно закрыты html-теги или не закрыты вовсе, когда используются устаревшие теги, не задан тип документа (<!DOCTYPE html>), некорректно организована вложенность элементов и другие. Часть ошибок могут быть видимыми, и пользователь сможет заметить их при посещении страниц сайта, часть ошибок может быть скрытой от глаз.
Наиболее популярный и зарекомендовавший себя валидатор, на наш взгляд, – validator.w3.org, он сканирует сайт на наличие ошибок в соответствии с принятыми Консорциумом Всемирной паутины стандартами. Данный валидатор имеет 3 способа проверки на ошибки: ввести URL конкретной страницы вашего сайта, загрузить файл страницы сайта и ввести часть кода сайта, которую необходимо проверить.

После выполнения проверки вам будет предоставлен список ошибок на странице с указанием описания ошибки, номер строки с ошибкой и в какой части строки содержится ошибка.

Присутствует функция фильтрации ошибок, с помощью которой вы можете исправлять по очереди конкретные группы ошибок, кроме этого для каждой ошибки предоставляется ссылка на w3c стандарты, где можно ознакомиться с причиной появления данной ошибки.
Также существуют плагины для браузеров для поиска ошибок на страницах сайта.
http://users.skynet.be/mgueury/mozilla/ – плагин для Mozilla

https://chrome.google.com/webstore/detail/html-tidy-browser-extensi/gljdonhfjnfdklljmfaabfpjlonflfnm – плагин для Chrome

https://addons.opera.com/en/extensions/details/validator/ – плагин для Opera

После того как сайт проверили на ошибки, встает вполне резонный вопрос: нужно ли их немедленно удалять и чем это чревато при SEO-продвижении?
Поисковые системы при ранжировании сайтов в поисковой выдаче все же уделяют больше внимания другим аспектам, таким как внутренняя оптимизация сайта, ссылочный профиль, контент. Но и валидацию полностью игнорировать все же не стоит.
В первую очередь рекомендую обратить внимание на ошибки, связанные с контентом, т.к. для поисковиков данный фактор является важным при ранжировании сайтов. Если ошибок на страницах сайта достаточно много (более 25), то настоятельно рекомендуется устранять ошибки в коде, т.к. сайты с большим количеством ошибок дольше загружаются, а также их сложнее проиндексировать, что может привести к отсутствию части страниц сайта в индексе поисковой системы.
Давайте проанализируем, сколько ошибок присутствует в коде страниц у крупных ресурсов.
Яндекс:


Google:


ОАО «РЖД»:


Как вы уже заметили, даже у сайтов поисковых систем присутствуют ошибки в коде страниц, что лишний раз подтверждает, что устранение ошибок носит скорее рекомендательный характер, при этом стоит упомянуть, что не нужно пренебрегать этим фактором и «запускать» ваш сайт. Развивайте сайт комплексно, всесторонне, тогда и результат будет соответствовать вашим ожиданиям.
Кстати, проверка сайта на ошибки, которые действительно влияют на продвижение, проходит в рамках SEO-аудита. Если сомневаетесь, что можете адекватно оценить свой сайт на наличие ошибок, обращайтесь.
Как правило, многие вебмастера загружают свои сайты на хост сразу-же после их создания. При этом они большей частью ориентируются на правильность составления смысла текстового содержания, чем на правильность внутреннего кода страниц.

Валидация сайта
Но есть и другие факторы, которые могут и влияют на позиции сайта. И к ним относятся, в том числе, и технические факторы. Ну а к техническим относятся и валидация сайта. Так что же это такое?
Если простыми словами, то валидация сайта — это проверка кода сайта на техническое соответствие и ошибки. Ну например, вы забыли использовать закрывающий тег — /html. В последнем HTML5, визуально ничего не поменяется. Однако, это ошибка кода.
При написании кода, возможны и другие ошибки. И опять-таки, современный язык гипер разметки «стерпит» многое. Например, «забытие» закрывающего тега /head. И снова вы не увидите разницу. Но она есть))
На самом деле, при написании сайта, ошибок может быть довольно много. И что хуже, некоторые из этих ошибок, могут проявиться и визуально. Ну может блоки поплывут, может выравнивание, а может и еще что-то. Потенциальных ошибок, тысячи. И далеко не все из них, бросаются в глаза.
В чем опасность?
Ну казалось-бы, ну и что тут такого? Да, нужно сказать, что зачастую такие ошибки не видимы. Точнее, невидимы человеком. А ведь страницы нашего сайта могут посетить не только люди, но и поисковые пауки, которые полностью просматривают сайт. И каждую ошибку, которую они находят на сайте, они передают на сервера поисковиков, таких как Яндекс или Гугл.
А поисковики, в свою очередь, видя что на сайте много ошибок кода, вполне могут сделать вывод о том, что сайт плохой. И значит, не будут поднимать его в поиске. Ну а это уже будет означать, что прощай посетители с поиска.
Да, надо признать, определенная пессимизация сайта из-за ошибок валидации, это довольно редкое явление. Но это вполне возможно, а значит, над валидацией обязательно нужно работать. А что для этого нужно сделать? Понятное дело, вначале ошибки нужно найти.
Но поскольку вручную это очень трудоёмкое и ненадежное дело, то для поиска ошибок, используются специальные сервисы, так называемые «Валидаторы».
Валидатор Markup Validation Service.

Этот сервис проверяет правильность кодов HTML и XHTML, которые являются основой большей части страниц при создании практически любого сайта и определяют его внутреннюю структуру. На этот сервис валидатора можно попасть, если пройти по ссылке http://validator.w3.org
Но здесь есть обязательное условие, которое также относится и к другим валидаторам: проверяемый сайт или его проверяемые страницы должны быть закачаны на хостинг. В противном случае, валидатор не будет «знать» адрес сайта и не сможет ничего проверить. Вот сейчас можно уже рассмотреть, как работать на этом валидаторе.
После захода на страницу этого сервиса, отобразиться вся его функциональная картинка. Но большая часть изображённого и написанного к основной проверке не относится и всё своё внимание надо обратить только на окно ввода адреса проверяемой страницы:
![]()
Вот именно с него и надо начинать.
Вообще-то, проверка валидации сайта чрезвычайно проста, как и весь наш бренный мир: в адресном окне сервиса надо написать адрес сайта, т.е. его URL и затем нажать «Check». После такого простого действия, валидатор «попыхтит» несколько секунд и выдаст следующее:
![]()
Это означает, что никаких ошибок в коде страницы нет и Вы можете быть абсолютно спокойны.
Но также может быть и такой нежелательный вариант:

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

Кроме того, валидатор не только перечислит найденные ошибки, но и точно покажет, на какой строке внутреннего кода эти ошибки расположены. Так что долго их искать не придётся. Здесь, ничего не преувеличивая, можно твёрдо сказать, что этот валидор работает прекрасно.
Но это ещё не всё: валидатор не только указывает местоположение обнаруженной ошибки кода, но и даёт достаточно полные рекомендации, каким образом можно устранить эти ошибки. Конечно, для этого не надо лениться и внимательно прочитать всё написанное.
В качестве краткого и обобщенного вывода, можно сказать следующее:
- данный сервис валидатора работает прекрасно и может очень быстро провести проверку сайта.
- Ну и небольшое, но очень приятное дополнение: валидация сайта производиться бесплатно.
- Сейчас можно перейти к следующему этапу: это проверка кода CSS.
Валидатор CSS Validation Service

В общем это вторая функция вышеописанного сервиса, но она «заточена» не для проверки кода HTML и XHTML, а конкретно для проверки правильности кода стиля CSS, расположенного на внешней таблице. А чтобы попасть на страницу сервиса, надо пройти по ссылке http://jigsaw.w3.org/css-validator.
Кстати, здесь стоит отметить нечто приятное: проверка на этом сервисе абсолютно бесплатна. Так что не надо вытаскивать деньги из своего кошелька — пусть они лежат до нужного момента. Однако перейдём к методике работы на этом втором сервисе.
В общем-то вся работа на валидаторе CSS абсолютно идентична проверке на чистоту кода. Поэтому, приводить отдельную картинку адресной строки валидатора нет необходимости. Просто чуть ниже кратко рассмотрим непосредственно порядок самой проверки и всё.
Для этого надо в адресной строке записать URL таблицы CSS, типа «http://мой сайт/style.css» и после этого нажать кнопку с русской надписью «Проверить». Соответственно, этот валидатор тоже несколько секунд «попыхтит» и выдаст искомый результат:
![]()
Это значит, что таблица CSS написана правильно и никаких ошибок в ней не обнаружено.
И здесь также есть приятная неожиданность: если прокрутить страницу несколько ниже, то там будет написан оптимизированный код для Вашей таблицы CSS, из которого убраны все лишние надписи и все теги кода будут расставлены в той последовательности, которая соответствует оптимальным рабочим требованиям всех поисковых систем. Остаётся только скопировать этот идеальный образец кода и вставить его в таблицу CSS.
Вполне может быть, что случиться и такой вариант:

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

И конечно, после этого закачать исправленную таблицу стиля на хост и при наличии зелёной строки можно с удовольствием скопировать оптимизированный код стиля таблицы CSS. Вполне понятно, что затем лучше всего поменять старый код на новый и оптимизированный.
Краткое резюме.
Выше были рассмотрены две самых основных и обязательных проверки валидации сайта. Без этих проверок даже не стоит открывать индексацию для поисковых систем в robots.txt В противном случае, сайт может быть проигнорирован для индексации поисковыми машинами и будет считаться неисправным с соответствующими санкциями.
Чтобы этого не произошло, надо затратить всего несколько минут, чтобы быть абсолютно спокойным и полностью уверенным в техническом состоянии своего сайта и всех его страниц. Конечно, необходимо ещё произвести дополнительные проверки ссылок и анкоров, видимости сайта на мобильных устройствах и параметры других кодов. Только тогда сайт можно считать готовым для его полного функционирования и для удачного и быстрого продвижению в ТОП.
Заранее хочется сказать, что все остальные проверки проходят также быстро и просто, как и рассмотренные выше — надо только внимательно прочитать порядок работы с валидатором.
Добавлено 19.04.2018г.
Распространенные ошибки валидности при проверке html кода
Решил дополнить статью ошибками HTML кода, которые часто встречаются на сайтах. Во всяком случае у меня их было много)). Сами ошибки валидатор подсвечивает желтым цветом.
1) Error: Character reference was not terminated by a semicolon.

Ошибка: символ не был прерван точкой с запятой — соответственно надо добавить.
2) Warning: Section lacks heading. Consider using h2-h6 elements to add identifying headings to all sections.

Предупреждение: Раздел не имеет заголовка. Рассмотрите возможность использования элементов h2-h6 для добавления идентифицирующих заголовков ко всем разделам. Тут все понятно, надо добавить хотя бы один подзаголовок. Это даже не ошибка, а рекомендация.
3) Error: Element noindex not allowed as child of element p in this context.

Ошибка: элемент noindex не разрешен как дочерний элемент элемента p в этом контексте. (Подавление дальнейших ошибок из этого поддерева.)
Решение простое, надо закомментировать тег ноиндекс, вид будет таким:

4) Error: The center element is obsolete.

Ошибка: тег «center» устарел — надо заменить, если речь про img то можно использовать атрибут align. Если что-то другое центрировали, то заменить на div.
5) An img element must have an alt attribute, except under certain

Ошибка: Элемент img должен иметь атрибут alt -тут все понятно, надо добавить атрибут альт, даже если он будет незаполненный, то ошибка уйдет.
6) The width attribute on the td element is obsolete. Use CSS instead.
Ошибка: Атрибут «width» на элементе «td» устарел

7) The type attribute is unnecessary for javascript resources

Ошибка: атрибут type не нужен для ресурсов javascript. Решение просто удаляем все лишнее и оставляем только тег «script».
8) The align attribute on the img element is obsolete.

Ошибка: Атрибут align для элемента img устарел. Сделайте выравнивание изображений дивами.
Ошибка: Неправильное использование тега «li»: отсутствует тег «ul», «ol» . Нужно проверить вложенность элементов списка.
10) End tag for «div» omitted, but OMITTAG NO was specified
Ошибка: Не хватает закрывающего тега div. Решение — добавляем элемент
11) End tag for element «div» which is not open
Ошибка: закрывающий тег div лишний. Соответственно удаляем.
Жду ваших комментариев, а у вас на сайтах валидный код?
Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером
Валидация HTTP запросов
—
Веб-разработка на Go
Представим, что мы разрабатываем социальную сеть, и нам нужно реализовать функцию публикации поста. Если не проверять данные, которые вводит пользователь, то мы можем получить пост с пустым или слишком длинным текстом. Обычно такие ошибки приводят к некорректному поведению в приложениях. Это не хорошо, потому что пользователь не сможет понять, что произошло, и нам придется разбираться, почему пост не опубликовался.
В этом уроке мы разберем, как проверять HTTP-запросы в Go. Это важно, потому что проверки позволяют избежать ошибок и обеспечить безопасность нашего приложения.
Ручная проверка запросов в Go
Процесс проверки запросов на корректность перед последующей обработкой называется валидацией:
У разработчиков есть несколько вариантов реализации валидации в Go. В некоторых проектах придерживаются идеологии простоты чтения кода и реализуют валидацию вручную.
Например, валидация запроса на сохранение поста может выглядеть следующим образом:
package main
import (
"errors"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/sirupsen/logrus"
)
type CreatePostRequest struct {
UserID int64 `json:"user_id"`
Text string `json:"text"`
}
func (req *CreatePostRequest) Validate() error {
if req.UserID < 0 {
return errors.New("user ID cannot be less than 0")
}
if req.Text == "" {
return errors.New("text is empty")
}
if len(req.Text) > 140 {
return errors.New("text is too long")
}
return nil
}
func main() {
webApp := fiber.New()
webApp.Post("/posts", func(ctx *fiber.Ctx) error {
// Парсинг JSON-строки из тела запроса в объект.
var req CreatePostRequest
if err := ctx.BodyParser(&req); err != nil {
return fmt.Errorf("body parser: %w", err)
}
// Проверка запроса на корректность.
err := req.Validate()
if err != nil {
return ctx.Status(fiber.StatusUnprocessableEntity).SendString(err.Error())
}
// @TODO Сохранение поста в хранилище.
return ctx.SendStatus(fiber.StatusOK)
})
logrus.Fatal(webApp.Listen(":80"))
}
Запускаем веб-приложение и отправляем запрос на создание поста с некорректными данными:
curl --location --request POST 'http://localhost/posts'
--header 'Content-Type: application/json'
--data-raw '{"user_id": -1, "text": ""}'
В данном запросе мы указали некорректный идентификатор пользователя и пустой текст поста. В ответ получаем сообщение об ошибке:
HTTP/1.1 422 Unprocessable Entity
user ID cannot be less than 0%
Попробуем отправить корректные значения:
curl --location --request POST 'http://localhost/posts'
--header 'Content-Type: application/json'
--data-raw '{"user_id": 100, "text": "Hello, World!"}'
В ответ приходит статус 200 OK, что означает успешное прохождение проверок.
Таким образом, мы настроили проверку запросов, которые приходят в наше веб-приложение. Если запрос на создание поста содержит некорректные данные, то мы возвращаем ошибку. В случае успешной валидации запроса мы возвращаем ответ со статусом 200 OK.
Со стороны кода в данной реализации все проверки описаны явно и легко читаются. Когда новый разработчик присоединится к проекту, он быстро поймет логику приложения, и как проверяются запросы.
У этого подхода также есть один значимый недочет: этот подход плохо масштабируется. Если у нас будет много различных методов с множеством полей, которые нужно проверить, то код станет громоздким. В итоге со временем может возникнуть много повторяющегося кода.
Второй недочет — мы выводим по одной ошибке в одном ответе. Например, структура запроса состоит из пяти полей. Все поля заполнены неверно. В текущей реализации пользователю придется сделать пять запросов, при этом исправлять по одному полю после каждого ответа. Это неудобно, поэтому мы бы хотели возвращать все ошибки в одном ответе.
Чтобы решить эти недочеты, следует использовать готовую библиотеку для валидации запросов. Мы рассмотрим самую часто используемую библиотеку в Go — go-playground/validator. Далее будем ее называть Validator.
Валидация запросов с помощью Validator
Библиотека Validator позволяет реализовать валидацию запросов с помощью аннотаций полей структур. Для каждого поля структуры мы описываем список правил проверок, которые необходимо осуществить. Например, валидация запроса на публикацию поста может выглядеть следующим образом:
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
"github.com/sirupsen/logrus"
)
type CreatePostRequest struct {
// Описываем правила валидации в аннотациях полей структуры.
UserID int64 `json:"user_id" validate:"required,min=0"`
Text string `json:"text" validate:"required,max=140"`
}
func main() {
webApp := fiber.New()
validate := validator.New()
webApp.Post("/posts", func(ctx *fiber.Ctx) error {
// Парсинг JSON-строки из тела запроса в объект.
var req CreatePostRequest
if err := ctx.BodyParser(&req); err != nil {
return fmt.Errorf("body parser: %w", err)
}
// Проверка запроса на корректность.
err := validate.Struct(req)
if err != nil {
return ctx.Status(fiber.StatusUnprocessableEntity).SendString(err.Error())
}
// @TODO Сохранение поста в хранилище.
return ctx.SendStatus(fiber.StatusOK)
})
logrus.Fatal(webApp.Listen(":80"))
}
Запускаем веб-приложение и отправляем запрос на создание поста с некорректными данными:
curl --location --request POST 'http://localhost/posts'
--header 'Content-Type: application/json'
--data-raw '{"user_id": -1, "text": ""}'
В данном запросе мы указали некорректный идентификатор пользователя и пустой текст поста. В ответ получаем сообщение об ошибке:
HTTP/1.1 422 Unprocessable Entity
Key: 'CreatePostRequest.UserID' Error:Field validation for 'UserID' failed on the 'min' tag
Key: 'CreatePostRequest.Text' Error:Field validation for 'Text' failed on the 'required' tag
Попробуем отправить корректные значения:
curl --location --request POST 'http://localhost/posts'
--header 'Content-Type: application/json'
--data-raw '{"user_id": 100, "text": "Hello, World!"}'
В ответ приходит статус 200 OK, что означает успешное прохождение проверок.
Так мы реализовали валидацию запросов с помощью библиотеки Validator. Когда мы передаем некорректные данные, то в ответ получаем сообщение об ошибке. Оно позволяет понять, какие данные необходимо исправить. Если все данные заполнены правильно, то мы получаем статус 200 OK.
Мы видим, что в данном случае код стал намного короче и легче читается. Мы можем описывать новые правила валидации и не добавлять новых функций и логики.
Однозначное преимущество по сравнению с ручной валидацией — библиотека уже содержит в себе множество готовых правил проверок, которые можно использовать в своих проектах. Например, мы можем проверить, что поле является корректной электронной почтой:
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
type User struct {
Email string `validate:"required,email"`
}
func main() {
v := validator.New()
// Вывод: Key: 'User.Email' Error:Field validation for 'Email' failed on the 'required' tag
fmt.Println(v.Struct(&User{}))
// Вывод: Key: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag
fmt.Println(v.Struct(&User{Email: "test"}))
// Пустой вывод, так как ошибки нет.
fmt.Println(v.Struct(&User{Email: "test@gmail.com"}))
}
Полный список правил проверок можно смотреть в документации.
Пользовательские валидаторы
Готовые правила обычно покрывают большинство нужд в валидации запросов. Но иногда нужно добавить свои правила с пользовательской логикой. Для этого можно использовать функцию validate.RegisterValidation().
Например, мы хотим проверить, что в публикуемом посте отсутствуют слова-фильтры. Для этого мы напишем следующий код:
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
"github.com/sirupsen/logrus"
"log"
"strings"
)
type CreatePostRequest struct {
// Описываем правила валидации в аннотациях полей структуры.
UserID int64 `json:"user_id" validate:"required,min=0"`
Text string `json:"text" validate:"required,max=140,allowable_text"`
}
var forbiddenWords = []string{
"umbrella",
"shinra",
}
func main() {
webApp := fiber.New()
validate := validator.New()
vErr := validate.RegisterValidation("allowable_text", func(fl validator.FieldLevel) bool {
// Проверяем, что текст не содержит запрещенных слов.
text := fl.Field().String()
for _, word := range forbiddenWords {
if strings.Contains(strings.ToLower(text), word) {
return false
}
}
return true
})
if vErr != nil {
log.Fatal("register validation ", vErr)
}
webApp.Post("/posts", func(ctx *fiber.Ctx) error {
// Парсинг JSON-строки из тела запроса в объект.
var req CreatePostRequest
if err := ctx.BodyParser(&req); err != nil {
return fmt.Errorf("body parser: %w", err)
}
// Проверка запроса на корректность.
err := validate.Struct(req)
if err != nil {
return ctx.Status(fiber.StatusUnprocessableEntity).SendString(err.Error())
}
// @TODO Сохранение поста в хранилище.
return ctx.SendStatus(fiber.StatusOK)
})
logrus.Fatal(webApp.Listen(":80"))
}
Запускаем веб-приложение и отправляем запрос на создание поста с текстом, который содержит слово-фильтр:
curl --location --request POST 'http://localhost/posts'
--header 'Content-Type: application/json'
--data-raw '{"user_id": 100, "text": "Hello Umbrella corp!"}'
В ответ получаем валидационную ошибку:
HTTP/1.1 422 Unprocessable Entity
Key: 'CreatePostRequest.Text' Error:Field validation for 'Text' failed on the 'allowable_text' tag
Если же отправить запрос с текстом без запрещенных слов, то получим успешный ответ:
curl --location --request POST 'http://localhost/posts'
--header 'Content-Type: application/json'
--data-raw '{"user_id": 100, "text": "Hello Good corp!"}'
HTTP/1.1 200 OK
В итоге мы описали пользовательское правило валидации по тегу allowable_text. Оно проверяет, что текстовое поле не содержит запрещенных слов.
Когда приходит запрос с запрещенным словом, валидация не проходит, а клиенту возвращается ошибка. Если в запросе передать корректный текст, то валидация пройдет успешно, и клиент получит ответ со статусом 200 OK.
Выводы
- В веб-приложениях следует проверять все запросы на корректность, чтобы избежать ошибок и уязвимостей
Хочешь в ТОП-3 Google? Оставляй заявку и получи предложение!
Хочешь в ТОП-3 Google? Оставляй заявку и получи предложение!
Ошибками валидации считаются выявленные при проверке кода веб-страниц несоответствия общеустановленным стандартам, которые могут влиять на корректность работы и отображения отдельных элементов или всего сайта в целом.
К часто встречающимся ошибкам валидации относятся:
- отсутствие тега Doctype, который нужен для того, чтобы браузер мог корректно определить тип загружаемого им документа;
- проблемы с конвертацией специальных символов;
- использование блочных элементов внутри строчных;
- незакрытые элементы (нарушение вложенности), неверное количество кавычек;
- отсутствие атрибута alt у присутствующих на странице изображений;
- HTML-элемент в неправильном разделе;
- отсутствие обязательных тегов в структуре элементов;
- теги, которые должны быть в единичном виде в пределах отдельной веб-страницы, повторяются несколько раз.
Не все ошибки валидации являются критическими и требуют исправления. Корректно работающий сайт при проверке валидности кода вполне может получить десяток-другой замечаний, наличие которых вполне допустимо, если они не оказывают влияния на его отображение и уровень юзабилити.
Чувствуете что бизнесу нужен апгрейд?
Хочешь в ТОП-3 Google? Оставляй заявку и получи предложение!
Да, хочу!

33047
Рассказываем, как валидатор помогает избавиться от ошибок, которые мешают пользователям, браузерам и поисковикам.
Ошибки HTML-кода создают вагон проблем: поисковики отказываются продвигать сайт, а пользователи грустно закрывают вкладку браузера, потому что ничего не работает. Профессиональные программисты всегда проверяют код на ошибки, причем находят их за несколько секунд.
Рассказываем, как самостоятельно проверить сайт и что с ним случится, если код невалидный.
Что такое HTML-валидация и зачем она нужна
Валидация — это проверка HTML-кода: соответствует ли он общепринятым правилам и нет ли в нём ошибок. Хороший код называют валидным. Он быстро загружается, браузеры корректно обрабатывают его синтаксис, а поисковикам кажется, что сайт просто замечательный, и его позиции растут.
Стандарты качества кода придумала и поддерживает W3C. Эта организация предлагает унифицировать сайты: сделать их быстрыми, одинаково удобными и доступными для всех.

Тим Бернерс-Ли — помимо прочего, создатель HTML, Всемирной паутины и стандартов качества разметки. (Фото: w3.org)
Чем опасны ошибки в разметке
Ошибки портят впечатление о сайте, мешают ему нормально работать и продвигаться в поисковых системах. Вот конкретные примеры:
- Страницы загружаются слишком медленно. По данным Unbounce, почти 27% пользователей закрывают страницу, если она грузится больше трех секунд. Еще 32,3% уходят после шести секунд загрузки.
- Посетители видят только часть текстов и иллюстраций. А значит, контент для них почти бесполезный — и посетитель, скорее всего, уйдет к конкуренту.
- Если поисковый робот запнется хотя бы об одну ошибку — битую ссылку, пропущенный знак в коде или неправильную верстку, — он может не проиндексировать страницу.
- Сайт некорректно отображается на разных устройствах. Он может хорошо выглядеть на экране компьютера, а с телефона не будут видны тексты, кнопки или весь контент «съедет».
- На сайте много скрытой рекламы и вирусов, а разработчик или владелец сайта не в курсе.
В результате пользователь не может нормально взаимодействовать с сайтом и закрывает вкладку браузера. Сайт теряет посетителя, а поисковик отмечает ухудшение поведенческих факторов и понижает позиции в выдаче.
Почему в коде появляются ошибки. Ошибки в разметке появляются, если разработчик, например, забыл закрыть тег, случайно продублировал элемент или указал неправильный атрибут.
В валидном коде не бывает лишних скобок или знаков препинания, но сложно уследить за всем самому. Поэтому придумали валидатор, который поможет найти все ошибки за несколько секунд.
Как пользоваться валидатором
Валидатор — это сервис проверки валидности HTML, который быстро находит ошибки в коде и помогает их исправить. Подобных сервисов несколько, но разработчики часто используют официальный валидатор W3C. В нём можно найти ошибки тремя способами: указать URL сайта, загрузить HTML-документ или HTML-код.
Валидатор не сделает сайт идеальным, но поможет избавиться от ошибок, которые мешают пользователям, браузерам и поисковикам.
Что проверяет валидатор
Сервис проверяет синтаксис кода: например, верно ли указаны тип документа и кодировка, нет ли в коде пропущенных элементов. Также происходит проверка соответствию DTD (Document Type Definition) — валидатор смотрит, соответствует ли код типу документа.
DTD — это инструкция для браузера, которая помогает ему правильно отображать HTML-документ.
Как интерпретировать результат
Валидатор делит проблемные части кода на предупреждения и ошибки. Для удобства они выделены разными цветами, чтобы сразу было понятно, каким проблемам стоит уделить особое внимание.

Пример результатов проверки, который наглядно показывает, что такое ошибка валидации. Предупреждения выделены желтым, ошибки — красным. (Скриншот: validator.w3.org)
Предупреждения
Незначительные проблемы. Сайт, скорее всего, не сломается, но всё равно не соответствует спецификациям W3C.
Это означает, что при прочих равных сайты конкурентов будут лучше работать на разных устройствах и эффективнее продвигаться в поисковых системах.
Ошибки
Серьезные проблемы. Есть риск, что сайт будет отображаться некорректно, часть контента окажется скрытой или пользователь вообще не сможет просматривать страницы.
Ошибки следует исправлять в первую очередь, но хорошим тоном будет избавиться вообще от всех проблем: это поможет сайту работать нормально.

Зеленая строка — то, что хочет увидеть разработчик, когда проверяет качество кода. (Скриншот: validator.w3.org)
Как проверять верстку с помощью хинтера
Хинтер — инструмент, который подсвечивает проблемный синтаксис прямо в редакторе кода.
Проверять верстку можно прямо во время разработки сайта. В этом поможет хинтер, который будет подчеркивать проблемные элементы, пока вы пишете код.
Обычно хинтер выглядит как плагин для текстового редактора, в котором вы пишете код. Это как проверка орфографии в Word, только для HTML и CSS.

Проблемный код подсвечивается красным в режиме онлайн. По желанию можно отключить автопроверку и запускать валидацию вручную. (Скриншот: github.com)
Заключение
Перед тем как сдать сайт заказчику или опубликовать в интернете, следует проверить код на валидность. Что нужно запомнить:
- Код бывает валидным и невалидным. Нужен валидный.
- Добиться валидности бывает непросто даже опытному разработчику, потому что кода много. Профессионалы используют валидатор.
- В валидаторе можно проверить сайт, HTML-документ или кусок кода.
- В помощь валидатору можно установить хинтер — подсветку проблемного синтаксиса прямо в вашем текстовом редакторе.
- Сайт с хорошим кодом лучше продвигается в поисковиках и радует пользователей скоростью и функционалом, с какого устройства они бы ни заходили.
Поговорим о том, как валидировать данные, которые отправляют пользователи нашему веб-приложению. Это — третья статья из цикла о том, как разработать коммерческое веб-приложение с нуля (Часть 1, Часть 2).
Алексей Соломонов
СТО подписки «Огонь»
- Вводная.
- Требования к валидации проекта.
- Валидатор.
- Middleware.
- Правила валидации запросов
- Тестирование.
- Итоги.
Валидировать данные запросов необходимо потому что:
- Пользователи могут не вводить обязательные данные без которых работа приложения невозможна.
- Пользователи могут вводить неверные данные из-за невнимательности.
- Злоумышленники могут целенаправленно вводить неверные данные.
Итог всех этих действий один — приложение может работать неверно, данные могут быть не консистентны.
Требования к валидации проекта
Когда команда разрабатывает приложение, создается единый набор правил валидации для разных типов данных, например:
- Имя должно содержать только буквы и иметь длину не более 30 символов.
- Дата должна соответствовать формату RFC3339.
- Телефонный номер должен соответствовать международным рекомендациям.
Следовать стандартам и рекомендациям хорошо, потому что:
- Под стандарты пишутся библиотеки кода, которые позволять работать с этими типами данных.
- Если необходимо интегрировать несколько серверных приложений, то интеграция будет проще, когда приложения работают с данными, отвечающим каким-либо стандартам.
Теперь, когда мы поняли что валидация необходима и она должна опираться на стандарты, давайте добавим ее в наше приложение.
Валидировать данные можно двумя путями:
- На уровне описания протокола.
- На уровне приложения.
Валидация на уровне описания протокола
Наше приложение использует protobuf, поэтому было бы заманчиво описать все правила валидации на уровне протокола. К тому уже есть готовые плагины для protoc, которые позволяют добавить правила валидации в описание сообщений:
- github.com/mwitkow/go-proto-validators
- github.com/envoyproxy/protoc-gen-validate
У валидации на уровне протокола есть три проблемы:
- Одни и те же правила (например дата должна быть в формате RFC3339) необходимо добавлять в разные сообщения. Соответственно есть риск, что разработчик ошибется, и валидация будет работать неверно или не будет работать вообще.
- Для какого то типа данных необходимо изменить валидацию. Если вы не нашли способ, как не дублировать правила валидации, тогда ее изменение превратится в проблему.
- Допустим вы решили первые две проблемы, но в какой то момент времени ваше приложение будет интегрироваться с другим, которое умеет отдавать данные только в xml. Соответственно вам не удастся переиспользовать правила валидации и надо будет что то придумывать.
Валидацию на уровне протокола можно использовать, когда вы пишете узкоспециализированное приложение, которое никогда ни с кем ни при каких условиях не будет интегрироваться. Для всего остального есть валидация на уровне приложения.
Валидация на уровне приложения
В golang большое количество библиотек, осуществляющих валидацию данных, поэтому можно выбрать любую понравившуюся и добавить в проект. Стоит сказать, что со всеми подобными библиотеками есть одна проблема — они не умеют работать с архитектурой grpc «из коробки», поэтому придется писать адаптеры над ними.
Для написания адаптеров к нам на помощь приходят:
- google.golang.org/protobuf/reflect/protoreflect поможет нам итеративно получить значения по всем полям сообщения.
- github.com/go-playground/validator станет фундаментом, на котором мы построим механизм валидации.
Архитектура валидации будет иметь следующую логику:
- Запрос перехватывается middleware.
- Middleware получает правила валидации из MethodDescriptor.
- Если правила есть, выполняет проверку свойств сообщения.
- Если нет, передает обработку запроса дальше.
Валидатор
Для начала давайте опишем сам валидатор и форму:
package validator
import (
"context"
"github.com/go-playground/validator/v10"
"google.golang.org/protobuf/reflect/protoreflect"
)
var (
validate = validator.New()
)
// конкретная реализация для какого либо типа данных запроса
type Validator interface {
Validate(ctx context.Context, value protoreflect.Value) error
}
// структура, позволяющая описывать валидаторы для всего запроса
type Form map[string]Validator
func (f Form) Validate(ctx context.Context, message protoreflect.Message) error {
fields := message.Descriptor().Fields()
for i := 0; i < fields.Len(); i++ {
field := fields.Get(i)
v, ok := f[string(field.Name())]
if !ok {
continue
}
err := v.Validate(ctx, message.Get(field))
if err != nil {
return err
}
}
return nil
}
Данный подход позволит нам использовать правила валидации как в middleware, так и в другом месте приложения.
Теперь давайте определимся с типами данных, которые будем валидировать:
- uuid — строка в формате UUID v4.
- телефонный номер — строка с префиксом «+» и длиной не более 15 символов.
- адрес доставки — строка длиной 255 символов.
- дата доставки — дата в формате RFC3339 не раньше сегодняшнего дня.
- сумма заказа — положительное число с плавающей точкой.
- перечисление — значение enum больше нуля и меньше или равно максимальному.
- сообщение — вложенное сообщение.
- массив сообщений — вложенный массив сообщений.
Теперь давайте реализуем валидаторы для разных форматов строк:
package validator
import (
"context"
"fmt"
"google.golang.org/protobuf/reflect/protoreflect"
)
func NewString(condition string) Validator {
return &stringValidator{
condition: condition,
}
}
func NewUUID() Validator {
return NewString("uuid4")
}
func NewPhoneNumber() Validator {
return NewString("e164")
}
func NewStringWithMaxLen(l int) Validator {
return NewString(fmt.Sprintf("required,max=%d", l))
}
func NewReqString() Validator {
return NewString("required")
}
func NewAlphanumeric() Validator {
return NewString("alphanum")
}
type stringValidator struct {
condition string
}
func (v stringValidator) Validate(ctx context.Context, value protoreflect.Value) error {
return validate.VarCtx(ctx, value.String(), v.condition)
}
Протестируем получившиеся валидаторы:
package validator_test
import (
"context"
"github.com/Pallinder/go-randomdata"
"github.com/byorty/enterprise-application/pkg/common/adapter/validator"
"github.com/google/uuid"
"github.com/stretchr/testify/suite"
"google.golang.org/protobuf/reflect/protoreflect"
"testing"
)
func TestStringValidatorSuite(t *testing.T) {
suite.Run(t, new(StringValidatorSuite))
}
type StringValidatorSuite struct {
suite.Suite
}
func (s *StringValidatorSuite) TestUUID() {
v := validator.NewUUID()
s.NotNil(v.Validate(context.Background(), protoreflect.ValueOf("")))
s.NotNil(v.Validate(context.Background(), protoreflect.ValueOf(randomdata.Alphanumeric(32))))
s.Nil(v.Validate(context.Background(), protoreflect.ValueOf(uuid.NewString())))
}
func (s *StringValidatorSuite) TestPhoneNumber() {
v := validator.NewPhoneNumber()
s.NotNil(v.Validate(context.Background(), protoreflect.ValueOf("")))
s.NotNil(v.Validate(context.Background(), protoreflect.ValueOf(randomdata.Alphanumeric(32))))
s.Nil(v.Validate(context.Background(), protoreflect.ValueOf("+79008007060")))
}
func (s *StringValidatorSuite) TestMaxLen() {
v := validator.NewStringWithMaxLen(10)
s.NotNil(v.Validate(context.Background(), protoreflect.ValueOf("")))
s.NotNil(v.Validate(context.Background(), protoreflect.ValueOf(randomdata.Alphanumeric(32))))
s.Nil(v.Validate(context.Background(), protoreflect.ValueOf(randomdata.Alphanumeric(9))))
}
func (s *StringValidatorSuite) TestAlphanumeric() {
v := validator.NewAlphanumeric()
s.NotNil(v.Validate(context.Background(), protoreflect.ValueOf("")))
s.NotNil(v.Validate(context.Background(), protoreflect.ValueOf("qazwsx!@#%%^")))
s.Nil(v.Validate(context.Background(), protoreflect.ValueOf(randomdata.Alphanumeric(32))))
}
По аналогии реализуем другие валидаторы:
- Целые числа
- Числа с плавающей точкой
- Даты
- Перечисления
- Сообщения
- Массивы
Мы создали единый набор правил валидации, который мы будем переиспользовать в разных доменах.
Middleware
Теперь необходимо вписать наши валидаторы в архитектуру grpc.
Расширяем MethodDescriptor:
type MethodDescriptor struct {
…
Form validator.Form
}
Реализуем новую middleware, которая будет брать форму из описания метода и валидировать запрос:
package grpc_option
import (
"context"
"github.com/byorty/enterprise-application/pkg/common/adapter/server/grpc"
gRPC "google.golang.org/grpc"
"google.golang.org/protobuf/reflect/protoreflect"
)
func NewFxValidatorOption(
methodDescriptorMap grpc.MethodDescriptorMap,
) grpc.MiddlewareOut {
return grpc.MiddlewareOut{
GrpcMiddleware: grpc.Middleware{
Priority: 97,
GrpcOption: func(ctx context.Context, req interface{}, info *gRPC.UnaryServerInfo, handler gRPC.UnaryHandler) (resp interface{}, err error) {
protoMessage, ok := req.(protoreflect.ProtoMessage)
if !ok {
return handler(ctx, req)
}
methodDescriptor, ok := methodDescriptorMap.GetByFullName(info.FullMethod)
if !ok {
return handler(ctx, req)
}
if len(methodDescriptor.Form) == 0 {
return handler(ctx, req)
}
err = methodDescriptor.Form.Validate(ctx, protoMessage.ProtoReflect())
if err != nil {
return nil, grpc.ErrInvalidArgument(err)
}
return handler(ctx, req)
},
},
}
}
Теперь наши запросы будут валидироваться в middleware, не захламляйте бизнес-код.
Правила валидации запросов
Все подготовительные работы окончены, и мы можем описать правила валидации для конкретных запросов. Давайте опишем правила для создании заказа.
package form
import "github.com/byorty/enterprise-application/pkg/common/adapter/validator"
var (
CreateOrder = validator.Form{
// идентификатором пользователя должен быть UUID v4
"user_uuid": validator.NewUUID(),
// параметрами запроса должнобыть сообщение
"params": validator.NewMessage(validator.Form{
// массив продуктов должен иметь хотя бы один элемент
"products": validator.NewReqList(
// элементом массива должно быть сообщение
validator.NewMessage(validator.Form{
// идентификатором продукта должен быть UUID v4
"product_uuid": validator.NewUUID(),
// пользователь должен добавить в заказ хотя бы одну единицу продукта
"count": validator.NewUint32Min(1),
}),
),
// любая строка не длиннее 255-ти символов
"address": validator.NewStringWithMaxLen(255),
// дата равная текущей + двое суток
"delivered_at": validator.NewDeliveredAt(),
}),
}
)
По аналогии опишем правила для других запросов:
- Запросы продуктов
- Запросы пользователей
Тестирование
Доработки кода приложения и инфраструктуры завершены, самое время протестировать наше приложение. Поднимаем приложение:
make up
Открываем https://enterprise.application.local
Давайте зарегистрируем пользователя с невалидным телефоном.

Получили ошибку валидации запроса.

Теперь возьмем валидный номер телефона.

Пользователь зарегистрирован.

А теперь создадим заказ без отложенных товаров.

Получили ошибку валидации запроса.

Отложим товары и создадим заказ.

Заказ создан.

Тесты прошли успешно, валидация запросов отрабатывает, как требуется.
Итоги
Итак, в этой статье мы научились:
- Разрабатывать архитектуру валидации protobuf сообщений.
- Реализовывать единый набор правил валидации.
- Вписывать правила валидации в архитектуру grpc.
- Описывать правила валидации для конкретных запросов.
Как и в предыдущей статье, код представлен в репозитории.
В следующей статье мы обсудим следующие темы:
- Выбор драйвера СУБД.
- Репозиторный слой приложения.
- Моки в тестах.
Обновлено: 29.01.2023
Почти все разработчики так или иначе постоянно работают с api по http, клиентские разработчики работают с api backend своего сайта или приложения, а бэкендеры «дергают» бэкенды других сервисов, как внутренних, так и внешних. И мне кажется, одна из самых главных вещей в хорошем API это формат передачи ошибок. Ведь если это сделано плохо/неудобно, то разработчик, использующий это API, скорее всего не обработает ошибки, а клиенты будут пользоваться молчаливо ломающимся продуктом.
За 7 лет я как поддерживал множество legacy API, так и разрабатывал c нуля. И я поработал, наверное, с большинством стратегий по возвращению ошибок, но каждая из них создавала дискомфорт в той или иной мере. В последнее время я нащупал оптимальный вариант, о котором и хочу рассказать, но с начала расскажу о двух наиболее популярных вариантах.
Если у вас примитивная бизнес-логика или API из 5 url, то в принципе это нормальный подход. Однако как-только бизнес-логика станет сложнее, то начнется ряд проблем.
REST скорее концепция, чем формат общения из чего следует неоднозначность использования статусов. Разработчики используют статусы как им заблагорассудится. Например, некоторые API при отсутствии сущности возвращают 404 и текст ошибки, а некоторые 200 и пустое тело.
Бэкенд разработчику в проекте непросто выбрать статус для ошибки, а клиентскому разработчику неочевидно какой статус предназначен для того или иного типа ошибок бизнес-логики. По-хорошему в проекте придется держать enum для того, чтобы описать какие ошибки относятся к тому или иному статусу.
Когда бизнес-логика приложения усложняется, начинают делать как-то так:
Принудительный вызов валидации
Для принудительного вызова проверки, без использования Spring Boot, создайте валидатор вручную.
Тем не менее, Spring Boot предоставляет предварительно сконфигурированный экземпляр валидатора. Внедрив этот экземпляр в сервис не придется создавать его вручную.
Когда этот сервис внедряется Spring, в конструктор автоматически вставляется экземпляр валидатора.
Группы валидаций
Некоторые объекты участвуют в разных вариантах использования.
Возьмем типичные операции CRUD: при обновлении и создании, скорее всего, будет использоваться один и тот же класс. Тем не менее, некоторые валидации должны срабатывать при различных обстоятельствах:
- только перед созданием
- только перед обновлением
- или в обоих случаях
Функция Bean Validation, которая позволяет нам внедрять такие правила проверки, называется «Validation Groups».
Все аннотации ограничений должны иметь поле groups . Это поле быть использовано для передачи любых классов, каждый из которых определяет группу проверки.
Для нашего примера CRUD определим два маркерных интерфейса OnCreate и OnUpdate :
Затем используем эти интерфейсы с любой аннотацией ограничения:
Это позволит убедиться, что id пуст при создании и заполнен при обновлении.
Spring поддерживает группы проверки только с аннотацией @Validated
Обратите внимание, что аннотация @Validated применяется ко всему классу. Чтобы определить, какая группа проверки активна, она также применяется на уровне метода.
Использование групп проверки может легко стать анти-паттерном. При использовании групп валидации сущность должна знать правила валидации для всех случаев использования (групп), в которых она используется.
Сначала нужно определить эту структуру данных. Назовем ее ValidationErrorResponse и она содержит список объектов Violation :
Затем создадим глобальный ControllerAdvice , который обрабатывает все ConstraintViolationExventions , которые пробрасываются до уровня контроллера. Чтобы отлавливать ошибки валидации и для тел запросов, мы также будем работать с MethodArgumentNotValidExceptions :
Здесь информацию о нарушениях из исключений переводится в нашу структуру данных ValidationErrorResponse .
Обратите внимание на аннотацию @ControllerAdvice , которая делает методы обработки исключений глобально доступными для всех контроллеров в контексте приложения.
Валидация сущностей JPA
Persistence Layer это последняя линия проверки данных. По умолчанию Spring Data использует Hibernate, который поддерживает Bean Validation из коробки.
Обычно мы не хотим делать проверку так поздно, поскольку это означает, что бизнес-код работал с потенциально невалидными объектами, что может привести к непредвиденным ошибкам.
Допустим, необходимо хранить объекты нашего класса Input в базе данных. Сначала добавляем нужную JPA аннотацию @Entity , а так же поле id :
Когда репозиторий пытается сохранить невалидный Input , чьи аннотации ограничений нарушаются, выбрасывается ConstraintViolationException .
Bean Validation запускается Hibernate только после того как EntityManager вызовет flush.
Чтобы отключить Bean Validation в репозиториях Spring, достаточно установить свойство Spring Boot spring.jpa.properties.javax.persistence.validation.mode равным null .
№2: На все 200
Есть другой подход, даже более старый, чем REST, а именно: на все ошибки связанные с бизнес-логикой возвращать 200, а уже в теле ответа есть информация об ошибке. Например:
На самом деле формат зависит от вас или от выбранной библиотеки для реализации коммуникации, например JSON-API.
В некоторых случаях, если есть библиотека десериализации данных, она может взять часть работы на себя. Писать SDK вокруг такого подхода проще нежели вокруг той или иной имплементации REST, ведь реализация зависит от того, как это видел автор. Кроме того, теперь никто не вызовет случайное срабатывание alert в мониторинге из-за того, что выбрал неудачный код ошибки.
Но неудобства тоже есть:
Избыточность полей при передаче данных, т.е. нужно всегда передавать 2 поля: для данных и для ошибки. Это усложняет чтение логов и написание документации.
При использовании средств отладки (Chrome DevTools) или других подобных инструментов вы не сможете быстро найти ошибочные запросы бизнес логики, придется обязательно заглянуть в тело ответа (ведь всегда 200)
нельзя делать повторы для неудавшихся GET запросов (на backend) на реверс-прокси (например, nginx) по указанной выше причине
имеются проблемы с документированием – swagger и ApiDoc не подходят, а удобных аналогов я не нашел
Итог: Для сложной бизнес-логики с большим количеством типов ошибок такой подход лучше, чем расплывчатый REST, не зря в проектах c “разухабистой” бизнес-логикой часто именно такой подход и используют.
№3: Смешанный
400 – ошибка бизнес логики
остальное ошибки в транспорте
Мы можем расширять объект ошибки для детализации проблемы, если хотим. С мониторингом все как во втором варианте, дописывать парсинг придется, но и риска “стрельбы” некорректными alert нету. Для документирования можем спокойно использовать Swagger и ApiDoc. При этом сохраняется удобство использования инструментов разработчика, таких как Chrome DevTools, Postman, Talend API.
Итог: Использую данный подход уже в нескольких проектах, где множество типов ошибок и все крайне довольны, как клиентские разработчики, так и бэкендеры. Внедрение новой ошибки не вызывает споров, проблем и противоречий. Данный подход объединяет преимущества первого и второго варианта, при этом код более читабельный и структурированный.
Самое главное какой бы формат ошибок вы бы не выбрали лучше обговорить его заранее и следовать ему. Если эту вещь пустить на “самотек”, то очень скоро обработка ошибок в проекте станет невыносимо сложной для всех.
P.S. Иногда ошибки любят передавать массивом
Но это актуально в основном в двух случаях:
Когда наш API выступает в роли сервиса без фронтенда (нет сайта/приложения). Например, сервис платежей.
Когда в API есть url для загрузки какого-нибудь длинного отчета в котором может быть ошибка в каждой строке/колонке. И тогда для пользователя удобнее, чтобы ошибки в приложении сразу показывались все, а не по одной.




Когда захожу на вашу почту support. вобще происходит что-то непонятное, есть скрин

Антонина, У Вас открывается настройка почты? Видимо, Вам необходимо что-то настроить или обновить настройки почты.
Уточните, какая версия операционной системы и браузера у Вас, данная ошибка появляется, если версии не обновлены. Обновите, пожалуйста, операционную систему, Если это необходимо, и главное обновите до последней версии браузер.

SMM planner, здравствуйте. Сильно упали охваты после атвопостинга. Речь идёт о инстаграме. Возможно из-за сммпланера?
Добавьте возможность отмечать на видео для ленты в инстаграме. А то несерьезно как-то. В самой инсте уже около года это возможно.



Произошла ошибка валидации.
Ни один сайт с автопостингом и тд не могу подключить.
Что я сделал до этого?
Создал бота по правилам , токен отправил на сайт вместе с ссылкой на канал (был новый канал для проверки и нужный мой канал) ни один не смог подключиться.
Пересоздал бота и добавил его в ManyBot (не знаю зачем) , все равно ошибка.

Лепить такой код в каждый метод, у данного метода множество недостатоков, подойдет для супер мелких проектов.
Хоть и сделал пока рабочий вариант костыляво, хотелось бы что-то постабильнее.

Andrew Stark, ну а если связать эти две вещи и вынести? Вы же программист симфони)
Правда это slim. Но на симфони можно сделать так, чтобы вообще этот метод убрать из контроллера.
Нередко пользователи пытаются передать в приложение некорректные данные. Это происходит либо из злого умысла, либо по ошибке. Поэтому стоит проверять данные на соответствие бизнес-требованиям.
Эту задачу решает Bean Validation. Он интегрирован со Spring и Spring Boot. Hibernate Validator считается эталонной реализацией Bean Validation.
Добавление пользовательского валидатора
Если имеющихся аннотаций ограничений недостаточно, то создайте новые.
В классе Input использовалось регулярное выражение для проверки того, что строка является IP адресом. Регулярное выражение не является полным: оно позволяет сокеты со значениями больше 255, таким образом «111.111.111.333» будет считаться действительным.
Давайте напишем валидатор, который реализует эту проверку на Java. Потому что как говорится, до решения проблемы регулярным выражением у вас была одна проблема, а теперь стало двe 🙂
Сначала создаем пользовательскую аннотацию @IpAddress :
Реализация валидатора выглядит следующим образом:
Теперь можно использовать аннотацию @IpAddress , как и любую другую аннотацию ограничения.
Валидация в Spring MVC Controller
- тело запроса
- переменные пути (например, id в /foos/)
- параметры запроса
Рассмотрим каждый из них подробнее.
Валидация тела запроса
Тело запроса POST и PUT обычно содержит данные в формате JSON. Spring автоматически сопоставляет входящий JSON с объектом Java.
Проверяем соответствует ли входящий Java объект нашим требованиям.
- Поле numberBetweenOneAndTen должно быть от 1 до 10, включительно.
- Поле ipAddress должно содержать строку в формате IP-адреса.
Контроллер REST принимает объект Input и выполняет проверку:
Достаточно добавить в параметр input аннотацию @Valid , чтобы сообщить спрингу передать объект Валидатору, прежде чем делать с ним что-либо еще.
Если класс содержит поле с другим классом, который тоже необходимо проверить — это поле необходимо пометить аннотацией Valid.
Проверка переменных пути и параметров запроса
Проверка переменных пути и параметров запроса работает по-другому.
Не проверяются сложные Java-объекты, так как path-переменные и параметры запроса являются примитивными типами, такими как int , или их аналогами: Integer или String .
Вместо аннотации поля класса, как описано выше, добавляют аннотацию ограничения (в данном случае @Min ) непосредственно к параметру метода в контроллере Spring:
Обратите внимание, что необходимо добавить @Validated Spring в контроллер на уровне класса, чтобы сказать Spring проверять ограничения на параметрах метода.
В этом случае аннотация @Validated устанавливается на уровне класса, даже если она присутствует на методах.
Позже рассмотрим, как вернуть структурированный ответ об ошибке, содержащий подробности обо всех неудачных подтверждениях для проверки клиентом.
Валидация в сервисном слое
Можно проверять данные на любых компонентах Spring. Для этого используется комбинация аннотаций @Validated и @Valid .
Аннотация @Validated устанавливается только на уровне класса, так что не ставьте ее на метод в данном случае.
Основы валидации Bean
Для проверки данных используются аннотации над полями класса. Это декларативный подход, который не загрязняет код.
При передаче размеченного таким образом объекта класса в валидатор, происходит проверка на ограничения.
Настройка
Добавьте следующие зависимости в проект:
Стандартные ограничения
Каждая аннотация имеет следующие поля:
Рассмотрим популярные ограничения.
@NotNull и @Null
@NotNull — аннотированный элемент не должен быть null. Принимает любой тип.
@Null — аннотированный элемент должен быть null. Принимает любой тип.
@NotBlank и @NotEmpty
@NotBlank — аннотированный элемент не должен быть null и должен содержать хотя бы один непробельный символ. Принимает CharSequence .
@NotEmpty — аннотированный элемент не должен быть null или пустым. Поддерживаемые типы:
- CharSequence
- Collection . Оценивается размер коллекции
- Map . Оценивается размер мапы
- Array . Оценивается длина массива
@NotBlank применяется только к строкам и проверяет, что строка не пуста и не состоит только из пробелов.
@NotNull применяется к CharSequence , Collection , Map или Array и проверяет, что объект не равен null . Но при этом он может быть пуст.
@NotEmpty применяется к CharSequence , Collection , Map или Array и проверяет, что он не null имеет размер больше 0.
Аннотация @Size(min=6) пропустит строку состоящую из 6 пробелов и/или символов переноса строки, а @NotBlank не пропустит.
Размер аннотированного элемента должен быть между указанными границами, включая сами границы. null элементы считаются валидными.
- CharSequence . Оценивается длина последовательности символов
- Collection . Оценивается размер коллекции
- Map . Оценивается размер мапы
- Array . Оценивается длина массива
Валидация конфигурации приложения
Spring Boot аннотация @ConfigurationProperties используется для связывания свойств из application.properties с Java объектом.
Данные из application необходимы для стабильной работы приложения. Bean Validation поможет обнаружить ошибку в этих данных при старте приложения.
Допустим имеется следующий конфигурационный класс:
При попытке запуска с недействительным адресом электронной почты получаем ошибку:
Читайте также:
- Fortnite ошибка 0xc000007b normaliz dll
- Medal of honor above and beyond системные требования
- Как установить game guardian на nox
- Как установить dlc dark souls 3
- Highfleet вылетает в редакторе
![]()
ПРЕДУПРЕЖДЕНИЕ Вы просматриваете документацию к старой версии Laravel.
Рассмотрите возможность обновления Вашего проекта до Laravel 9.x.
Валидация
- Введение
-
Быстрый старт валидации
- Определение маршрутов
- Создание контроллера
- Написание логики валидации
- Отображение ошибок валидации
- Перезаполнение форм
- Примечание о необязательных полях
-
Валидация запроса формы
- Создание запросов формы
- Авторизация запросов формы
- Настройка сообщений об ошибках
- Подготовка ввода для валидации
-
Создание валидаторов вручную
- Автоматическое перенаправление
- Именованные пакеты ошибки
- Настройка сообщений об ошибках
- После проверки
- Работа с проверенным вводом
-
Работа с сообщениями об ошибке
- Указание пользовательских сообщений в языковых файлах
- Указание атрибутов в языковых файлах
- Указание значений в языковых файлах
- Доступные правила валидации
- Условное добавление правил
-
Валидация массивов
- Исключение непроверенных ключей массива
- Проверка ввода вложенного массива
- Валидация паролей
-
Пользовательские правила проверки
- Использование объектов правила
- Использование замыканий
- Неявные правила
Введение
Laravel предоставляет несколько различных подходов для проверки входящих данных вашего приложения. Чаще всего используется метод validate, доступный для всех входящих HTTP-запросов. Однако мы обсудим и другие подходы к валидации.
Laravel включает в себя широкий спектр удобных правил проверки, которые вы можете применять к данным, даже предоставляя возможность проверять, являются ли значения уникальными в данной таблице базы данных. Мы подробно рассмотрим каждое из этих правил проверки, чтобы вы были знакомы со всеми функциями проверки Laravel.
Быстрый старт валидации
Чтобы узнать о мощных функциях проверки Laravel, давайте рассмотрим полный пример проверки формы и отображения сообщений об ошибках обратно пользователю. Прочитав этот общий обзор, вы сможете получить хорошее общее представление о том, как проверять данные входящего запроса с помощью Laravel:
Определение маршрутов
Во-первых, предположим, что в нашем файле routes/web.php определены следующие маршруты:
use AppHttpControllersPostController;
Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);
Маршрут GET отобразит форму для пользователя для создания нового сообщения в блоге, а маршрут POST сохранит новое сообщение в базе данных.
Создание контроллера
Далее давайте посмотрим на простой контроллер, который обрабатывает входящие запросы на эти маршруты. Пока оставим метод store пустым:
<?php
namespace AppHttpControllers;
use AppHttpControllersController;
use IlluminateHttpRequest;
class PostController extends Controller
{
/**
* Show the form to create a new blog post.
*
* @return IlluminateViewView
*/
public function create()
{
return view('post.create');
}
/**
* Store a new blog post.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
public function store(Request $request)
{
// Validate and store the blog post...
}
}
Написание логики валидации
Теперь мы готовы заполнить наш метод store логикой для проверки нового поста в блоге. Для этого мы будем использовать метод validate, предоставляемый объектом IlluminateHttpRequest. Если правила проверки пройдены, ваш код продолжит нормально выполняться; однако, если проверка не пройдена, будет выдано исключение IlluminateValidationValidationException, и пользователю будет автоматически отправлен правильный ответ об ошибке.
Если проверка не выполняется во время традиционного HTTP-запроса, будет сгенерирован ответ перенаправления на предыдущий URL-адрес. Если входящий запрос является запросом XHR, будет возвращен ответ JSON, содержащий сообщения об ошибках проверки.
Чтобы лучше понять метод validate, давайте вернемся к методу store:
/**
* Store a new blog post.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid...
}
Как видите, правила проверки передаются в метод validate. Не волнуйтесь — все доступные правила проверки задокументированы. Опять же, если проверка не удалась, автоматически будет сгенерирован правильный ответ. Если проверка пройдет успешно, наш контроллер продолжит работу в обычном режиме.
В качестве альтернативы, правила проверки могут быть указаны как массивы правил вместо одной строки с разделителями |:
$validatedData = $request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
]);
Кроме того, вы можете использовать метод validateWithBag для проверки запроса и сохранения любых сообщений об ошибках в именованном пакете ошибок:
$validatedData = $request->validateWithBag('post', [
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
]);
Остановка при первой ошибке проверки
Иногда может потребоваться прекратить выполнение правил проверки для атрибута после первого сбоя проверки. Для этого присвойте атрибуту правило 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',
]);
С другой стороны, если ваше имя поля содержит буквальную точку, вы можете явно запретить ее интерпретацию как синтаксис «точка», экранировав точку с помощью обратной косой черты:
$request->validate([
'title' => 'required|unique:posts|max:255',
'v1.0' => 'required',
]);
Отображение ошибок валидации
Итак, что, если поля входящего запроса не проходят заданные правила проверки? Как упоминалось ранее, Laravel автоматически перенаправит пользователя обратно в его предыдущее местоположение. Кроме того, все ошибки проверки и запрос ввода будут автоматически перенесены в сеанс.
Переменная $errors используется для всех представлений вашего приложения мидлвар IlluminateViewMiddlewareShareErrorsFromSession, который предоставляется группой мидлваров web. Когда применяется этот мидлвар, в ваших представлениях всегда будет доступна переменная $errors, что позволяет вам удобно предполагать, что переменная $errors всегда определена и может безопасно использоваться. Переменная $errors будет экземпляром IlluminateSupportMessageBag. Для получения дополнительной информации о работе с этим объектом ознакомьтесь с его документацией.
Итак, в нашем примере пользователь будет перенаправлен на метод нашего контроллера 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 содержит сообщение об ошибке, которое находится в файле resources/lang/en/validation.php вашего приложения. В этом файле вы найдете запись перевода для каждого правила проверки. Вы можете изменять или модифицировать эти сообщения в зависимости от потребностей вашего приложения.
Кроме того, вы можете скопировать этот файл в каталог другого языка перевода, чтобы переводить сообщения на язык вашего приложения. Чтобы узнать больше о локализации Laravel, ознакомьтесь с полной документацией по локализации.
XHR запросы и валидация
В этом примере мы использовали традиционную форму для отправки данных в приложение. Однако многие приложения получают запросы XHR от внешнего интерфейса на базе JavaScript. При использовании метода validate во время запроса XHR Laravel не генерирует ответ перенаправления. Вместо этого Laravel генерирует ответ JSON, содержащий все ошибки проверки. Этот ответ JSON будет отправлен с кодом состояния 422 HTTP.
Директива @error
Вы можете использовать директиву @error Blade, чтобы быстро определить, существуют ли сообщения об ошибках проверки для данного атрибута. В директиве @error вы можете повторить переменную $message, чтобы отобразить сообщение об ошибке:
<!-- /resources/views/post/create.blade.php -->
<label for="title">Post Title</label>
<input id="title" type="text" name="title" class="@error('title') is-invalid @enderror">
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
Если вы используете именованные пакеты ошибок, вы можете передать имя пакета ошибок в качестве второго аргумента директиве @error:
<input ... class="@error('title', 'post') is-invalid @enderror">
Перезаполнение форм
Когда Laravel генерирует ответ перенаправления из-за ошибки проверки, фреймворк автоматически все флеш входные данные запроса в сессию. Это сделано для того, чтобы вы могли удобно получить доступ к вводу во время следующего запроса и повторно заполнить форму, которую пользователь пытался отправить.
Чтобы получить флэш-ввод из предыдущего запроса, вызовите метод old для экземпляра IlluminateHttpRequest. Метод old извлечет ранее записанные входные данные из сессии:
$title = $request->old('title');
Laravel также предоставляет глобального помощника old. Если вы показываете старый ввод в шаблоне Blade, удобнее использовать помощник old для повторного заполнения формы. Если для данного поля нет старого ввода, будет возвращен null:
<input type="text" name="title" value="{{ old('title') }}">
Примечание о необязательных полях
По умолчанию Laravel включает мидлвары TrimStrings и ConvertEmptyStringsToNull в глобальный стек мидлваров вашего приложения. Эти мидлвары перечислены в стеке классом AppHttpKernel. Из-за этого вам часто нужно будет помечать ваши «необязательные» поля запроса как nullable если вы не хотите, чтобы валидатор считал значения null недействительными. Например:
$request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
'publish_at' => 'nullable|date',
]);
В этом примере мы указываем, что поле publish_at может иметь значение null или допустимое представление даты. Если модификатор nullable не добавлен в определение правила, валидатор сочтет null недопустимой датой.
Валидация запроса формы
Создание запросов формы
Для более сложных сценариев проверки вы можете создать «запрос формы». Запросы формы — это настраиваемые классы запросов, которые инкапсулируют свою собственную логику проверки и авторизации. Чтобы создать класс запроса формы, вы можете использовать команду Artisan CLI make:request:
php artisan make:request StorePostRequest
Сгенерированный класс запроса формы будет помещен в каталог app/Http/Requests. Если этот каталог не существует, он будет создан, когда вы запустите команду make:request. Каждый запрос формы, сгенерированный Laravel, имеет два метода: authorize и rules.
Как вы могли догадаться, метод authorize отвечает за определение того, может ли текущий аутентифицированный пользователь выполнить действие, представленное запросом, в то время как метод rules возвращает правила проверки, которые должны применяться к данным запроса:
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
{tip} Вы можете указать любые зависимости, которые вам нужны, в сигнатуре метода
rules. Они будут автоматически разрешены через Laravel сервисный контейнер.
Итак, как оцениваются правила проверки? Все, что вам нужно сделать, это ввести подсказку запроса к методу вашего контроллера. Входящий запрос формы проверяется перед вызовом метода контроллера, что означает, что вам не нужно загромождать контроллер какой-либо логикой проверки:
/**
* Store a new blog post.
*
* @param AppHttpRequestsStorePostRequest $request
* @return IlluminateHttpResponse
*/
public function store(StorePostRequest $request)
{
// The incoming request is valid...
// Retrieve the validated input data...
$validated = $request->validated();
// Retrieve a portion of the validated input data...
$validated = $request->safe()->only(['name', 'email']);
$validated = $request->safe()->except(['name', 'email']);
}
Если проверка не удалась, будет сгенерирован ответ перенаправления, чтобы отправить пользователя обратно в его предыдущее местоположение. Ошибки также будут перенесены в сеанс, чтобы они были доступны для отображения. Если запрос был запросом XHR, пользователю будет возвращен 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!');
}
});
}
Остановка при первой ошибке проверки атрибута
Добавляя свойство stopOnFirstFailure к вашему классу запроса, вы можете сообщить валидатору, что он должен прекратить проверку всех атрибутов после того, как произошла единственная ошибка валидации:
/**
* Indicates if the validator should stop on the first rule failure.
*
* @var bool
*/
protected $stopOnFirstFailure = true;
Настройка местоположения перенаправления
Как обсуждалось ранее, будет сгенерирован ответ перенаправления, чтобы отправить пользователя обратно в его предыдущее местоположение, если проверка формы не пройдена. Однако вы можете настроить это поведение. Для этого определите свойство $redirect в запросе формы:
/**
* The URI that users should be redirected to if validation fails.
*
* @var string
*/
protected $redirect = '/dashboard';
Или, если вы хотите перенаправить пользователей на именованный маршрут, вместо этого вы можете определить свойство $redirectRoute:
/**
* The route that users should be redirected to if validation fails.
*
* @var string
*/
protected $redirectRoute = 'dashboard';
Авторизация запросов формы
Класс запроса формы также содержит метод authorize. В этом методе вы можете определить, действительно ли аутентифицированный пользователь имеет право обновлять данный ресурс. Например, вы можете определить, действительно ли пользователь владеет комментарием в блоге, который он пытается обновить. Скорее всего, вы будете взаимодействовать со своими шлюзами и политиками авторизации в этом методе:
use AppModelsComment;
/**
* 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}');
Поэтому, если ваше приложение использует привязку модели маршрута, ваш код можно сделать еще более кратким, если вы получите доступ к разрешенной модели как к свойству запрос:
return $this->user()->can('update', $this->comment);
Если метод authorize возвращает false, ответ HTTP с кодом состояния 403 будет автоматически возвращен, и метод вашего контроллера не будет выполняться.
Если вы планируете обрабатывать логику авторизации для запроса в другой части вашего приложения, вы можете просто вернуть true из метода authorize:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
{tip} You may type-hint any dependencies you need within the
authorizemethod’s signature. They will automatically be resolved via the Laravel service container.
Настройка сообщений об ошибках
Вы можете настроить сообщения об ошибках, используемые в запросе формы, переопределив метод 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',
];
}
Настройка атрибутов проверки
Многие сообщения об ошибках встроенных правил проверки Laravel содержат плейсхолдер :attribute. Если вы хотите, чтобы заполнитель :attribute вашего сообщения проверки был заменен именем настраиваемого атрибута, вы можете указать настраиваемые имена, переопределив метод attributes. Этот метод должен возвращать массив пар атрибут / имя:
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes()
{
return [
'email' => 'email address',
];
}
Подготовка ввода для валидации
Если вам нужно подготовить или очистить какие-либо данные из запроса перед применением правил проверки, вы можете использовать метод prepareForValidation:
use IlluminateSupportStr;
/**
* Prepare the data for validation.
*
* @return void
*/
protected function prepareForValidation()
{
$this->merge([
'slug' => Str::slug($this->slug),
]);
}
Создание валидаторов вручную
Если вы не хотите использовать метод validate в запросе, вы можете создать экземпляр валидатора вручную, используя Validator фасад. Метод make на фасаде генерирует новый экземпляр валидатора:
<?php
namespace AppHttpControllers;
use AppHttpControllersController;
use IlluminateHttpRequest;
use IlluminateSupportFacadesValidator;
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();
}
// Retrieve the validated input...
$validated = $validator->validated();
// Retrieve a portion of the validated input...
$validated = $validator->safe()->only(['name', 'email']);
$validated = $validator->safe()->except(['name', 'email']);
// Store the blog post...
}
}
Первый аргумент, переданный методу make— это проверяемые данные. Второй аргумент — это массив правил проверки, которые должны применяться к данным.
После определения того, не прошла ли проверка запроса, вы можете использовать метод withErrors для передачи сообщений об ошибках в сеанс. При использовании этого метода переменная $errors будет автоматически передана вашим представлениям после перенаправления, что позволит вам легко отображать их обратно пользователю. Метод withErrors принимает валидатор, MessageBag, или PHP array.
Остановка при первой ошибке проверки
Метод stopOnFirstFailure проинформирует валидатор о том, что он должен прекратить проверку всех атрибутов после того, как произошла единственная ошибка валидации:
if ($validator->stopOnFirstFailure()->fails()) {
// ...
}
Автоматическое перенаправление
Если вы хотите создать экземпляр валидатора вручную, но по-прежнему пользуетесь преимуществами автоматического перенаправления, предлагаемого методом validate HTTP-запроса, вы можете вызвать метод validate для существующего экземпляра валидатора. Если проверка не удалась, пользователь будет автоматически перенаправлен или, в случае запроса XHR, будет возвращен ответ JSON:
Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
])->validate();
Вы можете использовать метод validateWithBag для сохранения сообщений об ошибках в именованный пакет ошибок, если проверка не удалась:
Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
])->validateWithBag('post');
Именованные пакеты ошибки
Если у вас есть несколько форм на одной странице, вы можете захотеть назвать MessageBag, содержащий ошибки проверки, что позволит вам получать сообщения об ошибках для конкретной формы. Для этого передайте имя в качестве второго аргумента в withErrors:
return redirect('register')->withErrors($validator, 'login');
Затем вы можете получить доступ к именованному экземпляру MessageBag из переменной $errors:
{{ $errors->login->first('email') }}
Настройка сообщений об ошибках
При необходимости вы можете предоставить настраиваемые сообщения об ошибках, которые должен использовать экземпляр валидатора вместо сообщений об ошибках по умолчанию, предоставляемых Laravel. Есть несколько способов указать собственные сообщения. Во-первых, вы можете передать пользовательские сообщения в качестве третьего аргумента методу Validator::make:
$validator = Validator::make($input, $rules, $messages = [
'required' => 'The :attribute field is required.',
]);
В этом примере плейсхолдер :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 email address!',
];
Указание значений настраиваемых атрибутов
Многие из встроенных сообщений об ошибках Laravel включают плейсхолдер :attribute, который заменяется именем проверяемого поля или атрибута. Чтобы настроить значения, используемые для замены этих заполнителей для определенных полей, вы можете передать массив настраиваемых атрибутов в качестве четвертого аргумента методу Validator::make:
$validator = Validator::make($input, $rules, $messages, [
'email' => 'email address',
]);
После проверки
Вы также можете прикрепить обратные вызовы, которые будут запускаться после завершения проверки. Это позволяет легко выполнять дальнейшую проверку и даже добавлять сообщения об ошибках в коллекцию сообщений. Для начала вызовите метод after на экземпляре валидатора:
$validator = Validator::make(...);
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add(
'field', 'Something is wrong with this field!'
);
}
});
if ($validator->fails()) {
//
}
Работа с проверенным вводом
После проверки данных входящего запроса с помощью формы запроса или экземпляра валидатора, созданного вручную, вы можете получить данные входящего запроса, которые фактически прошли проверку. Это может быть достигнуто несколькими способами. Во-первых, вы можете вызвать метод validated для запроса формы или экземпляра валидатора. Этот метод возвращает массив проверенных данных:
$validated = $request->validated();
$validated = $validator->validated();
В качестве альтернативы вы можете вызвать безопасный метод safe для запроса формы или экземпляра валидатора. Этот метод возвращает экземпляр IlluminateSupportValidatedInput. Этот объект предоставляет методы only, except и all для извлечения подмножества проверенных данных или всего массива проверенных данных:
$validated = $request->safe()->only(['name', 'email']);
$validated = $request->safe()->except(['name', 'email']);
$validated = $request->safe()->all();
Кроме того, экземпляр IlluminateSupportValidatedInput можно повторять и обращаться к нему как к массиву:
// Validated data may be iterated...
foreach ($request->safe() as $key => $value) {
//
}
// Validated data may be accessed as an array...
$validated = $request->safe();
$email = $validated['email'];
Если вы хотите добавить дополнительные поля к проверенным данным, вы можете вызвать метод merge:
$validated = $request->safe()->merge(['name' => 'Taylor Otwell']);
Если вы хотите получить проверенные данные в виде экземпляра коллекции, вы можете вызвать метод collect:
$collection = $request->safe()->collect();
Работа с сообщениями об ошибке
После вызова метода errors для экземпляра Validator вы получите экземпляр IlluminateSupportMessageBag, который имеет множество удобных методов для работы с сообщениями об ошибках. Переменная $errors, которая автоматически становится доступной для всех представлений, также является экземпляром класса MessageBag.
Получение первого сообщения об ошибке для поля
Чтобы получить первое сообщение об ошибке для данного поля, используйте метод 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')) {
//
}
Указание пользовательских сообщений в языковых файлах
Каждое из встроенных правил проверки Laravel содержит сообщение об ошибке, которое находится в файле resources/lang/en/validation.php вашего приложения. В этом файле вы найдете запись перевода для каждого правила проверки. Вы можете изменять или модифицировать эти сообщения в зависимости от потребностей вашего приложения.
Кроме того, вы можете скопировать этот файл в каталог другого языка перевода, чтобы переводить сообщения на язык вашего приложения. Чтобы узнать больше о локализации Laravel, ознакомьтесь с полной документацией по локализации.
Пользовательские сообщения для определенных атрибутов
Вы можете настроить сообщения об ошибках, используемые для указанных комбинаций атрибутов и правил, в файлах языка проверки вашего приложения. Для этого добавьте настройки сообщения в массив custom языкового файла resources/lang/xx/validation.php вашего приложения:
'custom' => [
'email' => [
'required' => 'We need to know your email address!',
'max' => 'Your email address is too long!'
],
],
Указание атрибутов в языковых файлах
Многие из встроенных сообщений об ошибках Laravel включают заполнитель :attribute, который заменяется именем проверяемого поля или атрибута. Если вы хотите, чтобы часть вашего сообщения проверки :attribute была заменена настраиваемым значением, вы можете указать имя настраиваемого атрибута в массиве attributes языкового файла resources/lang/xx/validation.php:
'attributes' => [
'email' => 'email address',
],
Указание значений в языковых файлах
Некоторые сообщения об ошибках встроенных правил проверки Laravel содержат заполнитель :value, который заменяется текущим значением атрибута запроса. Однако иногда вам может понадобиться заменить часть вашего сообщения проверки :value на пользовательское представление значения. Например, рассмотрим следующее правило, которое указывает, что номер кредитной карты требуется, если payment_type имеет значение cc:
Validator::make($request->all(), [
'credit_card_number' => 'required_if:payment_type,cc'
]);
В случае сбоя этого правила проверки будет выдано следующее сообщение об ошибке:
The credit card number field is required when payment type is cc.
Вместо того, чтобы отображать cc в качестве значения типа платежа, вы можете указать более удобное для пользователя представление значения в вашем языковом файле resources/lang/xx/validation.php, определив массив значений values:
'values' => [
'payment_type' => [
'cc' => 'credit card'
],
],
После определения этого значения правило проверки выдаст следующее сообщение об ошибке:
The credit card number field is required when payment type is credit card.
Доступные правила валидации
Ниже приведен список всех доступных правил проверки и их функции:
accepted
Проверяемое поле должно иметь значение "yes", "on", 1 или true. Это полезно для проверки принятия «Условий использования» или аналогичных полей.
accepted_if:anotherfield,value,…
Проверяемое поле должно иметь значение "yes", "on", 1 или true, если другое проверяемое поле равно указанному значению. Это полезно для проверки принятия «Условий обслуживания» или аналогичных полей.
active_url
Проверяемое поле должно иметь допустимую запись A или AAAA в соответствии с функцией PHP dns_get_record. Имя хоста предоставленного URL извлекается с помощью функции PHP parse_url перед передачей в dns_get_record.
after:date
Проверяемое поле должно иметь значение после заданной даты. Даты будут переданы в функцию PHP strtotime для преобразования в действительный экземпляр DateTime:
'start_date' => 'required|date|after:tomorrow'
Вместо передачи строки даты для оценки strtotime, вы можете указать другое поле для сравнения с датой:
'finish_date' => 'required|date|after:start_date'
after_or_equal:date
Проверяемое поле должно иметь значение после указанной даты или равное ей. Для получения дополнительной информации смотрите правило after.
alpha
Проверяемое поле должно состоять полностью из буквенных символов.
alpha_dash
Проверяемое поле может содержать буквенно-цифровые символы, а также дефисы и подчеркивания.
alpha_num
Проверяемое поле должно состоять полностью из буквенно-цифровых символов.
array
Проверяемое поле должно быть массивом PHP array.
Когда для правила массива array предоставляются дополнительные значения, каждый ключ во входном массиве должен присутствовать в списке значений, предоставленных правилу. В следующем примере ключ admin во входном массиве недействительна, так как она не содержится в списке значений, предоставленных правилу array:
use IlluminateSupportFacadesValidator;
$input = [
'user' => [
'name' => 'Taylor Otwell',
'username' => 'taylorotwell',
'admin' => true,
],
];
Validator::make($input, [
'user' => 'array:username,locale',
]);
В общем, вы всегда должны указывать ключи массива, которые могут присутствовать в вашем массиве. В противном случае методы validate и validated валидатора вернут все проверенные данные, включая массив и все его ключи, даже если эти ключи не были проверены другими правилами проверки вложенных массивов.
Если хотите, вы можете указать валидатору Laravel никогда не включать непроверенные ключи массива в «проверенные» данные, которые он возвращает, даже если вы используете правило array без указания списка разрешенных ключей. Для этого вы можете вызвать метод валидатора excludeUnvalidatedArrayKeys в методе boot вашего приложения AppServiceProvider. После этого валидатор будет включать ключи массива в «проверенные» данные, которые он возвращает, только если эти ключи были специально проверены правилами вложенного массива:
use IlluminateSupportFacadesValidator;
/**
* Register any application services.
*
* @return void
*/
public function boot()
{
Validator::excludeUnvalidatedArrayKeys();
}
bail
Остановите выполнение правил проверки для поля после первого сбоя проверки.
В то время как правило bail прекращает проверку определенного поля только при сбое проверки, метод stopOnFirstFailure сообщит валидатору, что он должен прекратить проверку всех атрибутов после того, как произошла единственная ошибка проверки:
if ($validator->stopOnFirstFailure()->fails()) {
// ...
}
before:date
Проверяемое поле должно быть значением, предшествующим указанной дате. Даты будут переданы в функцию PHP strtotime для преобразования в действительный экземпляр DateTime. Кроме того, как правило after, имя другого проверяемого поля может быть указано как значение date.
before_or_equal:date
Проверяемое поле должно иметь значение, предшествующее указанной дате или равное ей. Даты будут переданы в функцию PHP strtotime для преобразования в действительный экземпляр DateTime. Кроме того, как правило after, имя другого проверяемого поля может быть указано как значение date.
between:min,max
Проверяемое поле должно иметь размер между заданными min и max. Строки, числа, массивы и файлы оцениваются так же, как правило size.
boolean
Проверяемое поле должно иметь возможность преобразования в логическое значение. Допустимые значения: true, false, 1, 0, "1" и "0".
confirmed
Проверяемое поле должно иметь совпадающее поле {field}_confirmation. Например, если проверяемое поле — это password, соответствующее поле password_confirmation должно присутствовать во входных данных.
current_password
Проверяемое поле должно совпадать с паролем аутентифицированного пользователя. Вы можете указать защиту аутентификации, используя первый параметр правила:
'password' => 'current_password:api'
date
Проверяемое поле должно быть действительной, не относительной датой в соответствии с функцией PHP strtotime.
date_equals:date
Проверяемое поле должно совпадать с указанной датой. Даты будут переданы в функцию PHP strtotime для преобразования в действительный экземпляр DateTime.
date_format:format
Проверяемое поле должно соответствовать заданному format. При проверке поля следует использовать либо date или date_format, а не то и другое вместе. Это правило проверки поддерживает все форматы, поддерживаемые классом PHP DateTime.
declined
Проверяемое поле должно иметь значение "no", "off", 0 или false.
declined_if:anotherfield,value,…
Проверяемое поле должно иметь значение "no", "off", 0 или false, если другое проверяемое поле равно указанному значению.
different:field
Проверяемое поле должно иметь значение, отличное от field.
digits:value
Проверяемое поле должно быть numeric и иметь точную длину value.
digits_between:min,max
Проверяемое поле должно быть numeric и иметь длину между заданными 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 IlluminateSupportFacadesValidator;
use IlluminateValidationRule;
Validator::make($data, [
'avatar' => [
'required',
Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
],
]);
distinct
При проверке массивов проверяемое поле не должно иметь повторяющихся значений:
'foo.*.id' => 'distinct'
По умолчанию использует свободные сравнения переменных. Чтобы использовать строгие сравнения, вы можете добавить параметр strict в определение правила проверки:
'foo.*.id' => 'distinct:strict'
Вы можете добавить ignore_case к аргументам правила проверки, чтобы правило игнорировало различия в использовании заглавных букв:
'foo.*.id' => 'distinct:ignore_case'
Проверяемое поле должно быть отформатировано как адрес электронной почты. Это правило проверки использует пакет egulias/email-validator для проверки адреса электронной почты. По умолчанию применяется валидатор RFCValidation, но вы также можете применить другие стили валидации:
'email' => 'email:rfc,dns'
В приведенном выше примере будут применяться проверки RFCValidation и DNSCheckValidation. Вот полный список стилей проверки, которые вы можете применить:
-
rfc:RFCValidation -
strict:NoRFCWarningsValidation -
dns:DNSCheckValidation -
spoof:SpoofCheckValidation -
filter:FilterEmailValidation
Валидатор filter, который использует функцию PHP filter_var, поставляется с Laravel и был поведением проверки электронной почты по умолчанию до Laravel версии 5.8.
{note} Валидаторы
dnsиspoofтребуют расширения PHPintl.
ends_with:foo,bar,…
Проверяемое поле должно заканчиваться одним из указанных значений.
enum
Правило Enum — это правило, основанное на классе, которое проверяет, содержит ли проверяемое поле допустимое значение перечисления. Правило Enum принимает имя перечисления в качестве единственного аргумента конструктора:
use AppEnumsServerStatus;
use IlluminateValidationRulesEnum;
$request->validate([
'status' => [new Enum(ServerStatus::class)],
]);
{note} Enums are only available on PHP 8.1+.
exclude
Проверяемое поле будет исключено из данных запроса, возвращаемых методами validate и validated.
exclude_if:anotherfield,value
Проверяемое поле будет исключено из данных запроса, возвращаемых методами validate и validated, если поле anotherfield равно value.
exclude_unless:anotherfield,value
Проверяемое поле будет исключено из данных запроса, возвращаемых методами validate и validated anotherfield не равно value. Если value равно null (exclude_unless:name,null), проверяемое поле будет исключено, если поле сравнения не имеет значение null или поле сравнения отсутствует в данных запроса.
exclude_without:anotherfield
Проверяемое поле будет исключено из данных запроса, возвращаемых методами validate и validated, если поле anotherfield отсутствует.
exists:table,column
Проверяемое поле должно существовать в данной таблице базы данных.
Основное использование правила Exists
'state' => 'exists:states'
Если опция column не указана, будет использоваться имя поля. Таким образом, в этом случае правило будет проверять, что таблица базы данных states содержит запись со значением столбца state, совпадающим со значением атрибута запроса state.
Указание кастомного имени столбца
Вы можете явно указать имя столбца базы данных, которое должно использоваться правилом проверки, поместив его после имени таблицы базы данных:
'state' => 'exists:states,abbreviation'
Иногда вам может потребоваться указать конкретное соединение с базой данных, которое будет использоваться для exists запроса. Вы можете сделать это, добавив имя подключения к имени таблицы:
'email' => 'exists:connection.staff,email'
Вместо того, чтобы указывать имя таблицы напрямую, вы можете указать модель Eloquent, которая должна использоваться для определения имени таблицы:
'user_id' => 'exists:AppModelsUser,id'
Если вы хотите настроить запрос, выполняемый правилом проверки, вы можете использовать класс Rule для плавного определения правила. В этом примере мы также укажем правила проверки в виде массива вместо использования символа | для их разделения:
use IlluminateSupportFacadesValidator;
use IlluminateValidationRule;
Validator::make($data, [
'email' => [
'required',
Rule::exists('staff')->where(function ($query) {
return $query->where('account_id', 1);
}),
],
]);
file
Проверяемое поле должно быть успешно загруженным файлом.
filled
Проверяемое поле не должно быть пустым, если оно присутствует.
gt:field
Проверяемое поле должно быть больше заданного field. Два поля должны быть одного типа. Строки, числа, массивы и файлы оцениваются с использованием тех же соглашений, что и правило size.
gte:field
Проверяемое поле должно быть больше или равно заданному field. Два поля должны быть одного типа. Строки, числа, массивы и файлы оцениваются с использованием тех же соглашений, что и правило size.
image
Проверяемый файл должен быть изображением (jpg, jpeg, png, bmp, gif, svg или webp).
in:foo,bar,…
Проверяемое поле должно быть включено в указанный список значений. Поскольку это правило часто требует, чтобы вы implode массив, метод Rule::in может быть использован для плавного построения правила:
use IlluminateSupportFacadesValidator;
use IlluminateValidationRule;
Validator::make($data, [
'zones' => [
'required',
Rule::in(['first-zone', 'second-zone']),
],
]);
Когда правило in комбинируется с правилом array, каждое значение во входном массиве должно присутствовать в списке значений, предоставленных правилу in. В следующем примере код аэропорта LAS во входном массиве недействителен, так как он не содержится в списке аэропортов, предоставленном правилу in:
use IlluminateSupportFacadesValidator;
use IlluminateValidationRule;
$input = [
'airports' => ['NYC', 'LAS'],
];
Validator::make($input, [
'airports' => [
'required',
'array',
Rule::in(['NYC', 'LIT']),
],
]);
in_array:anotherfield.*
Проверяемое поле должно существовать в значениях anotherfield.
integer
Проверяемое поле должно быть целым числом.
{note} Это правило проверки не проверяет, что ввод относится к типу переменной «целое число», а только что ввод относится к типу, принятому правилом PHP
FILTER_VALIDATE_INT. Если вам нужно проверить ввод как число, используйте это правило в сочетании с правилом проверкиnumeric.
ip
Проверяемое поле должно быть IP-адресом.
ipv4
Проверяемое поле должно быть адресом IPv4.
ipv6
Проверяемое поле должно быть адресом IPv6.
mac_address
Проверяемое поле должно быть MAC-адресом.
json
Проверяемое поле должно быть допустимой строкой JSON.
lt:field
Проверяемое поле должно быть меньше заданного field. Два поля должны быть одного типа. Строки, числа, массивы и файлы оцениваются с использованием тех же соглашений, что и правило size.
lte:field
Проверяемое поле должно быть меньше или равно заданному field. Два поля должны быть одного типа. Строки, числа, массивы и файлы оцениваются с использованием тех же соглашений, что и правило size.
max:value
Проверяемое поле должно быть меньше или равно максимальному value. Строки, числа, массивы и файлы оцениваются так же, как правило size.
mimetypes:text/plain,…
Проверяемый файл должен соответствовать одному из указанных типов MIME:
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'
Чтобы определить тип MIME загруженного файла, содержимое файла будет прочитано, и платформа попытается угадать тип MIME, который может отличаться от типа MIME, предоставленного клиентом.
mimes:foo,bar,…
Проверяемый файл должен иметь тип MIME, соответствующий одному из перечисленных расширений.
Основное использование правила MIME
'photo' => 'mimes:jpg,bmp,png'
Несмотря на то, что вам нужно только указать расширения, это правило фактически проверяет MIME-тип файла, читая содержимое файла и угадывая его MIME-тип. Полный список типов MIME и их соответствующих расширений можно найти по следующему адресу:
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
min:value
Проверяемое поле должно иметь минимальное значение value. Строки, числа, массивы и файлы оцениваются так же, как правило size.
multiple_of:value
Проверяемое поле должно быть кратным value.
{note} The
bcmathPHP extension is required in order to use themultiple_ofrule.
not_in:foo,bar,…
Проверяемое поле не должно быть включено в данный список значений. Метод Rule::notIn может использоваться для плавного построения правила:
use IlluminateValidationRule;
Validator::make($data, [
'toppings' => [
'required',
Rule::notIn(['sprinkles', 'cherries']),
],
]);
not_regex:pattern
Проверяемое поле не должно соответствовать заданному регулярному выражению.
Внутренне это правило использует функцию PHP preg_match. Указанный шаблон должен подчиняться тому же форматированию, которое требуется для preg_match, и, следовательно, также включать допустимые разделители. Например: 'email' => 'not_regex:/^.+$/i'.
{note} При использовании шаблонов
regex/not_regexможет потребоваться указать ваши правила проверки с использованием массива вместо использования разделителей|, особенно если регулярное выражение содержит символ|.
nullable
Проверяемое поле может быть null.
numeric
Проверяемое поле должно быть numeric.
password
Проверяемое поле должно совпадать с паролем аутентифицированного пользователя.
{note} Это правило было переименовано в
current_passwordс намерением удалить его в Laravel 9. Вместо этого используйте правило Текущего пароля.
present
Проверяемое поле должно присутствовать во входных данных, но может быть пустым.
prohibited
Проверяемое поле должно быть пустым или отсутствовать.
prohibited_if:anotherfield,value,…
Проверяемое поле должно быть пустым или отсутствовать, если поле anotherfield равно любому value.
prohibited_unless:anotherfield,value,…
Проверяемое поле должно быть пустым или отсутствовать, если поле anotherfield не равно какому-либо value.
prohibits:anotherfield,…
Если проверяемое поле присутствует, никакие поля в anotherfield не могут присутствовать, даже если они пусты.
regex:pattern
Проверяемое поле должно соответствовать заданному регулярному выражению.
Внутренне это правило использует функцию PHP preg_match. Указанный шаблон должен подчиняться тому же форматированию, которое требуется для preg_match, и, следовательно, также включать допустимые разделители. Например: 'email' => 'regex:/^.+@.+$/i'.
{note} При использовании шаблонов
regex/not_regexможет потребоваться указать правила в массиве вместо использования разделителей|, особенно если регулярное выражение содержит символ|.
required
Проверяемое поле должно присутствовать во входных данных и не быть пустым. Поле считается «пустым», если выполняется одно из следующих условий:
- Значение равно
null. - Значение — пустая строка.
- Значение представляет собой пустой массив или пустой объект
Countable. - Значение — загруженный файл без пути.
required_if:anotherfield,value,…
Проверяемое поле должно присутствовать и не быть пустым, если поле anotherfield равно любому value.
Если вы хотите создать более сложное условие для правила required_if, вы можете использовать метод Rule::requiredIf. Этот метод принимает логическое значение или замыкание. При передаче замыкания оно должно возвращать true или false, чтобы указать, требуется ли проверяемое поле:
use IlluminateSupportFacadesValidator;
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,…
Проверяемое поле должно присутствовать и не быть пустым, если поле anotherfield не равно какому-либо value. Это также означает, что в данных запроса должно присутствовать anotherfield, если value не имеет значения null. Если value равно null (required_unless:name,null), проверяемое поле будет обязательным, если поле сравнения не равно null или поле сравнения отсутствует в данных запроса.
required_with:foo,bar,…
Проверяемое поле должно присутствовать и не быть пустым, only if присутствует любое из других указанных полей, а не пустое.
required_with_all:foo,bar,…
Проверяемое поле должно присутствовать и не быть пустым, only if все другие указанные поля присутствуют, а не пусто.
required_without:foo,bar,…
Проверяемое поле должно присутствовать и не быть пустым, only when только если любое из других указанных полей пусто или отсутствует.
required_without_all:foo,bar,…
Поле для проверки должно присутствовать и не быть пустым, only when все другие указанные поля пусты или отсутствуют.
same:field
Данное field должно соответствовать проверяемому полю.
size:value
Проверяемое поле должно иметь размер, соответствующий заданному value. Для строковых данных value соответствует количеству символов. Для числовых данных value соответствует заданному целочисленному значению (атрибут также должен иметь правило numeric или integer). Для массива size соответствует count массива. Для файлов size соответствует размеру файла в килобайтах. Давайте посмотрим на несколько примеров:
// Убедитесь, что длина строки составляет ровно 12 символов...
'title' => 'size:12';
// Убедитесь, что указанное целое число равно 10...
'seats' => 'integer|size:10';
// Убедитесь, что в массиве ровно 5 элементов...
'tags' => 'array|size:5';
// Убедитесь, что загруженный файл составляет ровно 512 килобайт...
'image' => 'file|size:512';
starts_with:foo,bar,…
Проверяемое поле должно начинаться с одного из указанных значений.
string
Проверяемое поле должно быть строкой. Если вы хотите, чтобы поле также было null, вы должны назначить этому полю правило nullable.
timezone
Проверяемое поле должно быть действительным идентификатором часового пояса в соответствии с функцией PHP timezone_identifiers_list.
unique:table,column
Проверяемое поле не должно существовать в данной таблице базы данных.
Указание настраиваемого имени таблицы / столбца:
Вместо того, чтобы указывать имя таблицы напрямую, вы можете указать модель Eloquent, которая должна использоваться для определения имени таблицы:
'email' => 'unique:AppModelsUser,email_address'
Параметр column может использоваться для указания соответствующего столбца базы данных поля. Если опция column не указана, будет использоваться имя проверяемого поля.
'email' => 'unique:users,email_address'
Указание настраиваемого подключения к базе данных
Иногда вам может потребоваться настроить пользовательское соединение для запросов к базе данных, сделанных валидатором. Для этого вы можете добавить имя подключения к имени таблицы:
'email' => 'unique:connection.users,email_address'
Принуждение уникального правила игнорировать данный идентификатор:
Иногда вы можете захотеть проигнорировать данный идентификатор во время уникальной проверки. Например, рассмотрим экран «обновить профиль», который включает имя пользователя, адрес электронной почты и местоположение. Вероятно, вы захотите убедиться, что адрес электронной почты уникален. Однако, если пользователь изменяет только поле имени, а не поле электронной почты, вы не хотите, чтобы возникла ошибка проверки, потому что пользователь уже является владельцем рассматриваемого адреса электронной почты.
Чтобы указать валидатору игнорировать идентификатор пользователя, мы воспользуемся классом Rule для плавного определения правила. В этом примере мы также укажем правила проверки в виде массива вместо использования символа | для ограничения правил:
use IlluminateSupportFacadesValidator;
use IlluminateValidationRule;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
{note} Вы никогда не должны передавать какие-либо запросы, контролируемые пользователем, в метод
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_id равно 1:
'email' => Rule::unique('users')->where(function ($query) {
return $query->where('account_id', 1);
})
url
Проверяемое поле должно быть действительным URL.
uuid
Проверяемое поле должно быть действительным универсальным уникальным идентификатором (UUID) RFC 4122 (версии 1, 3, 4 или 5).
Условное добавление правил
Пропуск проверки, когда поля имеют определенные значения
Иногда вы можете захотеть не проверять данное поле, если другое поле имеет заданное значение. Вы можете сделать это, используя правило проверки exclude_if. В этом примере поля appointment_date и doctor_name не будут проверяться, если поле has_appointment имеет значение false:
use IlluminateSupportFacadesValidator;
$validator = Validator::make($data, [
'has_appointment' => 'required|boolean',
'appointment_date' => 'exclude_if:has_appointment,false|required|date',
'doctor_name' => 'exclude_if:has_appointment,false|required|string',
]);
В качестве альтернативы вы можете использовать правило exclude_unless, чтобы не проверять данное поле, если другое поле не имеет данного значения:
$validator = Validator::make($data, [
'has_appointment' => 'required|boolean',
'appointment_date' => 'exclude_unless:has_appointment,true|required|date',
'doctor_name' => 'exclude_unless:has_appointment,true|required|string',
]);
Проверка при наличии
В некоторых ситуациях вы можете захотеть выполнить проверки для поля только, если это поле присутствует в проверяемых данных. Чтобы быстро добиться этого, добавьте правило sometimes в свой список правил:
$v = Validator::make($data, [
'email' => 'sometimes|required|email',
]);
В приведенном выше примере поле email будет проверено, только если оно присутствует в массиве $data.
{tip} Если вы пытаетесь проверить поле, которое всегда должно присутствовать, но может быть пустым, ознакомьтесь с этим примечанием о дополнительных полях.
Комплексная условная проверка
Иногда вы можете захотеть добавить правила проверки, основанные на более сложной условной логике. Например, вы можете потребовать заданное поле только в том случае, если другое поле имеет значение больше 100. Или вам может потребоваться, чтобы два поля имели заданное значение только при наличии другого поля. Добавление этих правил проверки не должно вызывать затруднений. Сначала создайте экземпляр Validator с вашими статическими правилами, которые никогда не меняются:
use IlluminateSupportFacadesValidator;
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'games' => 'required|numeric',
]);
Предположим, наше веб-приложение предназначено для коллекционеров игр. Если коллекционер игр регистрируется в нашем приложении и у него есть более 100 игр, мы хотим, чтобы он объяснил, почему у него так много игр. Например, возможно, у них есть магазин по перепродаже игр, или, может быть, им просто нравится коллекционировать игры. Чтобы условно добавить это требование, мы можем использовать метод sometimes в экземпляре Validator.
$validator->sometimes('reason', 'required|max:500', function ($input) {
return $input->games >= 100;
});
Первым аргументом, передаваемым методу sometimes, является имя поля, которое мы условно проверяем. Второй аргумент — это список правил, которые мы хотим добавить. Если замыкание, переданное в качестве третьего аргумента, возвращает true, правила будут добавлены. Этот метод упрощает создание сложных условных проверок. Вы даже можете добавить условные проверки сразу для нескольких полей:
$validator->sometimes(['reason', 'cost'], 'required', function ($input) {
return $input->games >= 100;
});
{tip} Параметр
$input, переданный вашему замыканию, будет экземпляромIlluminateSupportFluentи может использоваться для доступа к вашему вводу и файлам при проверке.
Сложная условная проверка массива
Иногда вам может понадобиться проверить поле на основе другого поля в том же вложенном массиве, индекс которого вам неизвестен. В этих ситуациях вы можете позволить вашему закрытию получить второй аргумент, который будет текущим отдельным элементом в проверяемом массиве:
$input = [
'channels' => [
[
'type' => 'email',
'address' => 'abigail@example.com',
],
[
'type' => 'url',
'address' => 'https://example.com',
],
],
];
$validator->sometimes('channels.*.address', 'email', function ($input, $item) {
return $item->type === 'email';
});
$validator->sometimes('channels.*.address', 'url', function ($input, $item) {
return $item->type !== 'email';
});
Подобно параметру $input, передаваемому замыканию, параметр $item является экземпляром IlluminateSupportFluent, когда данные атрибута представляют собой массив; в противном случае это строка.
Валидация массивов
Как обсуждалось в документации правила проверки массива array, правило array принимает список разрешенных ключей массива. Если в массиве присутствуют какие-либо дополнительные ключи, проверка завершится ошибкой:
use IlluminateSupportFacadesValidator;
$input = [
'user' => [
'name' => 'Taylor Otwell',
'username' => 'taylorotwell',
'admin' => true,
],
];
Validator::make($input, [
'user' => 'array:username,locale',
]);
В общем, вы всегда должны указывать ключи массива, которые могут присутствовать в вашем массиве. В противном случае методы validate и validated валидатора вернут все проверенные данные, включая массив и все его ключи, даже если эти ключи не были проверены другими правилами проверки вложенных массивов.
Исключение непроверенных ключей массива
Если хотите, вы можете указать валидатору Laravel никогда не включать непроверенные ключи массива в «проверенные» данные, которые он возвращает, даже если вы используете правило array без указания списка разрешенных ключей. Для этого вы можете вызвать метод валидатора excludeUnvalidatedArrayKeys в методе boot вашего приложения AppServiceProvider. После этого валидатор будет включать ключи массива в «проверенные» данные, которые он возвращает, только если эти ключи были специально проверены правилами вложенного массива:
use IlluminateSupportFacadesValidator;
/**
* Register any application services.
*
* @return void
*/
public function boot()
{
Validator::excludeUnvalidatedArrayKeys();
}
Проверка ввода вложенного массива
Проверка полей ввода формы на основе вложенного массива не должна быть проблемой. Вы можете использовать «точечную нотацию» для проверки атрибутов в массиве. Например, если входящий HTTP-запрос содержит поле photos[profile], вы можете проверить его следующим образом:
use IlluminateSupportFacadesValidator;
$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 email address',
]
],
Валидация паролей
Чтобы гарантировать, что пароли имеют адекватный уровень сложности, вы можете использовать объект правила Laravel Password:
use IlluminateSupportFacadesValidator;
use IlluminateValidationRulesPassword;
$validator = Validator::make($request->all(), [
'password' => ['required', 'confirmed', Password::min(8)],
]);
Объект правила Password позволяет вам легко настроить требования к сложности пароля для вашего приложения, например указать, что для паролей требуется хотя бы одна буква, цифра, символ или символы со смешанным регистром:
// Требуется не менее 8 символов...
Password::min(8)
// Требуется хотя бы одна буква...
Password::min(8)->letters()
// Требуется хотя бы одна заглавная и одна строчная буква...
Password::min(8)->mixedCase()
// Требовать хотя бы одна цифра...
Password::min(8)->numbers()
// Требуется хотя бы один символ...
Password::min(8)->symbols()
Кроме того, вы можете убедиться, что пароль не был скомпрометирован в результате утечки данных публичного пароля, используя метод uncompromised:
Password::min(8)->uncompromised()
Внутренне объект правила Password использует модель k-Anonymity, чтобы определить, не произошла ли утечка пароля через haveibeenpwned.com без ущерба для конфиденциальности или безопасности пользователя.
По умолчанию, если пароль появляется хотя бы один раз в утечке данных, он будет считаться скомпрометированным. Вы можете настроить этот порог, используя первый аргумент метода uncompromised:
// Убедитесь, что пароль появляется менее 3 раз в одной и той же утечке данных...
Password::min(8)->uncompromised(3);
Конечно, вы можете связать все методы в приведенных выше примерах:
Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols()
->uncompromised()
Определение правил паролей по умолчанию
Возможно, вам будет удобно указать правила проверки паролей по умолчанию в одном месте вашего приложения. Вы можете легко сделать это, используя метод Password::defaults, который принимает замыкание. Замыкание, данное методу defaults, должно возвращать конфигурацию правила пароля по умолчанию. Обычно правило defaults должно вызываться в методе boot одного из сервис провайдеров вашего приложения:
use IlluminateValidationRulesPassword;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Password::defaults(function () {
$rule = Password::min(8);
return $this->app->isProduction()
? $rule->mixedCase()->uncompromised()
: $rule;
});
}
Затем, когда вы хотите применить правила по умолчанию к конкретному паролю, проходящему проверку, вы можете вызвать метод defaults без аргументов:
'password' => ['required', Password::defaults()],
Иногда вы можете захотеть добавить дополнительные правила проверки к правилам проверки пароля по умолчанию. Для этого вы можете использовать метод rules:
use AppRulesZxcvbnRule;
Password::defaults(function () {
$rule = Password::min(8)->rules([new ZxcvbnRule]);
// ...
});
Пользовательские правила проверки
Использование объектов правила
Laravel предоставляет множество полезных правил проверки; однако вы можете указать свои собственные. Один из методов регистрации настраиваемых правил проверки — использование объектов правил. Чтобы сгенерировать новый объект правила, вы можете использовать Artisan-команду make:rule. Давайте воспользуемся этой командой, чтобы сгенерировать правило, которое проверяет, что строка является прописной. Laravel поместит новое правило в каталог app/Rules. Если этот каталог не существует, Laravel создаст его, когда вы выполните команду Artisan для создания своего правила:
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],
]);
Доступ к дополнительным данным
Если вашему пользовательскому классу правил проверки требуется доступ ко всем другим данным, проходящим проверку, ваш класс правил может реализовать интерфейс IlluminateContractsValidationDataAwareRule. Этот интерфейс требует, чтобы ваш класс определил метод setData. Этот метод будет автоматически вызываться Laravel (до продолжения проверки) со всеми проверяемыми данными:
<?php
namespace AppRules;
use IlluminateContractsValidationRule;
use IlluminateContractsValidationDataAwareRule;
class Uppercase implements Rule, DataAwareRule
{
/**
* All of the data under validation.
*
* @var array
*/
protected $data = [];
// ...
/**
* Set the data under validation.
*
* @param array $data
* @return $this
*/
public function setData($data)
{
$this->data = $data;
return $this;
}
}
Или, если ваше правило проверки требует доступа к экземпляру валидатора, выполняющего проверку, вы можете реализовать интерфейс ValidatorAwareRule:
<?php
namespace AppRules;
use IlluminateContractsValidationRule;
use IlluminateContractsValidationValidatorAwareRule;
class Uppercase implements Rule, ValidatorAwareRule
{
/**
* The validator instance.
*
* @var IlluminateValidationValidator
*/
protected $validator;
// ...
/**
* Set the current validator.
*
* @param IlluminateValidationValidator $validator
* @return $this
*/
public function setValidator($validator)
{
$this->validator = $validator;
return $this;
}
}
Использование замыканий
Если вам нужна функциональность настраиваемого правила только один раз во всем приложении, вы можете использовать замыкание вместо объекта правила. Замыкание получает имя атрибута, значение атрибута и обратный вызов $fail, который должен вызываться в случае неудачной проверки:
use IlluminateSupportFacadesValidator;
$validator = Validator::make($request->all(), [
'title' => [
'required',
'max:255',
function ($attribute, $value, $fail) {
if ($value === 'foo') {
$fail('The '.$attribute.' is invalid.');
}
},
],
]);
Неявные правила
По умолчанию, когда проверяемый атрибут отсутствует или содержит пустую строку, обычные правила проверки, включая настраиваемые правила, не выполняются. Например, правило unique не будет выполняться для пустой строки:
use IlluminateSupportFacadesValidator;
$rules = ['name' => 'unique:users,name'];
$input = ['name' => ''];
Validator::make($input, $rules)->passes(); // true
Чтобы настраиваемое правило работало, даже если атрибут пуст, правило должно подразумевать, что атрибут является обязательным. Чтобы создать «неявное» правило, реализуйте интерфейс IlluminateContractsValidationImplicitRule. Этот интерфейс служит «маркерным интерфейсом» для валидатора; следовательно, он не содержит каких-либо дополнительных методов, которые необходимо реализовать помимо методов, требуемых типичным интерфейсом Rule.
Чтобы сгенерировать новый объект неявного правила, вы можете использовать Artisan-команду make:rule с опцией --implicit:
php artisan make:rule Uppercase --implicit
{note} Неявное» правило только подразумевает, что атрибут является обязательным. Действительно ли он делает недействительным отсутствующий или пустой атрибут, зависит от вас.