Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

Валидация данных

Эта страница помечена как незавершённая. Вы можете помочь проекту, дополнив её.

Ненадежные данные поступают из многих источников (пользователи, сторонние сайты, ваша собственная база данных!, ...) и все они нуждаются в проверке как на ввод, так и на вывод.

Output Sanitation

Метод валидации данных зависит от типа данных, а также от того, в каком контексте они используются. Далее мы рассмотрим несколько типичных задач, а также то, как необходимо валидировать данные.

Совет: Рекомендуется делать валидацию как можно позже, идеально - непосредственно перед выводом, вместо того, чтобы сделать это в самом начале. Таким образом, вы будете уверены, что данные валидны, и не будет необходимости помнить, делалась уже валидация, или нет.

Целые числа

intval( $int ) или (int) $int
Это должно быть целым числом, приводим переменную к такому типу.
absint( $int )
Целое, не отрицательное число.

HTML/XML

Note that many types of XML documents (as opposed to HTML documents) understand only a few named character references: apos, amp, gt, lt, quot. When outputting text to such an XML document, be sure to filter any text containing illegal named entities through WordPress's ent2ncr( $text ) function.

HTML/XML Fragments

wp_kses( (string) $fragment, (array) $allowed_html, (array) $protocols = null )
KSES Strips Evil Scripts. All untrusted HTML (post text, comment text, etc.) should be run through wp_kses().
To avoid having to pass an array of allowed HTML tags, you can use wp_kses_post( (string) $fragment ) for tags that are allowed in posts/pages or wp_kses_data( (string) $fragment ) for the small list of tags allowed in comments.
wp_rel_nofollow( (string) $html )
Adds a "rel='nofollow'" attribute to any <a> link.
wp_kses_allowed_html( (string) $context )
Provides an array of allowed HTML tags for a given context. Allowed values are post | strip | data | entities or the name of a field filter such : as pre_user_description.

Текстовые значения

esc_html( $text ) (начиная с 2.8)
Кодирует символы < > & " ' (меньше, больше, амперсанд, двойная кавычка, одинарная кавычка). Очень похоже на esc_attr.
esc_html__ (начиная с 2.8)
Переводит и кодирует
esc_html_e (начиная с 2.8)
Переводит, кодирует и выводит
esc_textarea (начиная с 3.1)
Кодирует текст для использования в элементе textarea.
sanitize_text_field (since 2.9.0)
Валидация строки, введённой пользователем, или из базы данных.

Атрибуты тэга

esc_attr( $text ) (начиная с 2.8)
esc_attr__()
Переводит и кодирует
esc_attr_e()
Переводит, кодирует и выводит

JavaScript

esc_js( $text ) (начиная с 2.8)

URLs

esc_url( $url, (array) $protocols = null ) (начиная с 2.8)
Always use esc_url when sanitizing URLs (in text nodes, attribute nodes or anywhere else). Rejects URLs that do not have one of the provided whitelisted protocols (defaulting to http, https, ftp, ftps, mailto, news, irc, gopher, nntp, feed, and telnet), eliminates invalid characters, and removes dangerous characters. Replaces clean_url() which was deprecated in 3.0.
This function encodes characters as HTML entities: use it when generating an (X)HTML or XML document. Encodes ampersands (&) and single quotes (') as numeric entity references (&#038, &#039).
esc_url_raw( $url, (array) $protocols = null ) (since 2.8)
For inserting an URL in the database. This function does not encode characters as HTML entities: use it when storing a URL or in other cases where you need the non-encoded URL. This functionality can be replicated in the old clean_url function by setting $context to db.
urlencode( $scalar )
Encodes for use in URL (as a query parameter, for example)
urlencode_deep( $array )
urlencodes all array elements.

Базы Данных

$wpdb->insert( $table, (array) $data )
$data должна быть не экранирована (функция выполнит это за вас). Keys как columns, Values как values.
$wpdb->update( $table, (array) $data, (array) $where )
$data должна быть не экранирована. Keys как columns, Values как values. $where должна быть не экранирована. Multiple WHERE conditions are ANDed together.
$wpdb->update(
  'my_table',
  array( 'status' => $untrusted_status, 'title' => $untrusted_title ),
  array( 'id' => 123 )
);
$wpdb->prepare( $format, (scalar) $value1, (scalar) $value2, ... )
$format это sprintf()-подобный формат строки. Он понимает только %s и %d заполнители, ни один из которых не должен быть заключён в кавычки.
$wpdb->get_var( $wpdb->prepare(
  "SELECT something FROM table WHERE foo = %s and status = %d",
  $name, // неэкранированная строка (функция проверит это для вас)
  $status // ненадёжный числитель (функция проверит это для вас)
) );
esc_sql( $sql )
Псевдоним для $wpdb->escape().
$wpdb->escape( $text )
Экранирует одну строку или массив строк для использования в SQL запросах. Прославленный addslashes(). $wpdb->prepare как правило, предпочтительнее, так как он исправляет несколько типичных ошибок форматирования.
$wpdb->escape_by_ref( &$text )
Нет возвращаемого значения. Поскольку параметр передается по ссылке, текст непосредственно изменяется, поэтому нет необходимости назначать какое-либо возвращаемое значение.
like_escape( $string )
Подготавливает $string для использования в LIKE выражениях SQL запросов. Будет по прежнему нуждаться в SQL экранировании (с одной из перечисленных функций).

Filesystem

validate_file( (string) $filename, (array) $allowed_files = "" )
Used to prevent directory traversal attacks, or to test a filename against a whitelist. Returns 0 if $filename represents a valid relative path. After validating, you must treat $filename as a relative path (i.e. you must prepend it with an absolute path), since something like /etc/hosts will validate with this function. Returns an integer greater than zero if the given path contains .., ./, or :, or is not in the $allowed_files whitelist. Be careful making boolean interpretations of the result, since false (0) indicates the filename has passed validation, whereas true (> 0) indicates failure.

HTTP Headers

Header splitting attacks are annoying since they are dependent on the HTTP client. WordPress has little need to include user generated content in HTTP headers, but when it does, WordPress typically uses whitelisting for most of its HTTP headers.

WordPress does use user generated content in HTTP Location headers, and provides sanitation for those.

wp_redirect($location, $status = 302)
A safe way to redirect to any URL. Ensures the resulting HTTP Location header is legitimate.
wp_safe_redirect($location, $status = 302)
Even safer. Only allows redirects to whitelisted domains.

Input Validation

Many of the functions above in #Output_Sanitation are useful for input validation. In addition, WordPress uses the following functions.

Slugs

sanitize_title( $title )
Used in post slugs, for example
sanitize_user( $username, $strict = false )
Use $strict when creating a new user (though you should use the API for that).

HTML

balanceTags( $html ) or force_balance_tags( $html )
Tries to make sure HTML tags are balanced so that valid XML is output.
tag_escape( $html_tag_name )
Sanitizes an HTML tag name (does not escape anything, despite the name of the function).
sanitize_html_class( $class, $fallback )
Santizes a html classname to ensure it only contains valid characters. Strips the string down to A-Z,a-z,0-9,'-' if this results in an empty string then it will return the alternative value supplied.

Email

is_email( $email_address )
returns boolean false if invalid, or $email_address if valid

Arrays

array_map( 'absint', $array )
Ensures all elements are nonnegative integers. Replace callback 'absint' with whatever is appropriate for your data. array_map() is a core PHP function that runs array elements through an arbitrary callback function, in this example, absint().

Other

Some other functions that may be useful to sanitise data input:

Validation Philosophies

There are several different philosophies about how validation should be done. Each is appropriate for different scenarios.

Whitelist

Accept data only from a finite list of known and trusted values.

$possible_values = array( 'a', 1, 'good' );
if ( !in_array( $untrusted, $possible_values ) )
  die( "Don't do that!" );
// Be careful here with fancy breaks and default actions.
switch ( $untrusted ) {
case 'a' :
  ...
  break;
...
default :
  die( "You hoser!" );
}

Blacklist

Reject data from finite list of known untrusted values. This is very rarely a good idea.

Format Detection

Test to see if the data is of the correct format. Only accept it if it is.

if ( !ctype_alnum( $data ) )
  die( "Your data is teh suX0R" );
if ( preg_match( "/[^0-9.-]/", $data ) )
  die( "Float on somewhere else, jerky" );

Format Correction

Accept most any data, but remove or alter the dangerous pieces.

$trusted_integer = (int) $untrusted_integer;
$trusted_alpha = preg_replace( '/[^a-z]/i', "", $untrusted_alpha );
$trusted_slug = sanitize_title( $untrusted_slug );

Changelog

  • 3.1: Introduced esc_textarea. (#15454)
  • 3.0: Deprecated clean_url() in favor of esc_url() and esc_url_raw(). (#12309)
  • 2.8: Deprecated the following functions. (via WordPress Development Updates)
    • sanitize_url() -> esc_url_raw()
    • wp_specialchars() -> esc_html() (also: esc_html__() and esc_html_e())
    • attribute_escape() -> esc_attr() (also: esc_attr__() and esc_attr_e())

External Resources