# wp_mail()

URL: https://chugunov.pro/api-wordpress/functions/wp_mail/
Проверено на WordPress 6.9, обновлено 06.08.2026.
Источник: независимый русскоязычный справочник chugunov.pro. Не является официальной документацией WordPress.

Тип: функция.
Появился в версии: 1.2.1.

## Сигнатура

```php
wp_mail( string|string[] $to, string $subject, string $message, string|string[] $headers = '', string|string[] $attachments = array(), string|string[] $embeds = array() ): bool
```

## Описание

Возвращаемое значение true не означает автоматически, что пользователь успешно получил письмо. Оно означает лишь, что использованный метод смог обработать запрос без ошибок.
Тип содержимого по умолчанию — text/plain, который не допускает использование HTML.
Однако тип содержимого письма можно задать с помощью фильтра 'wp_mail_content_type'.
Кодировка по умолчанию основана на кодировке, используемой на блоге. Кодировку можно задать с помощью фильтра 'wp_mail_charset'.
При использовании параметра $embeds для встраивания изображений в HTML-письма ссылайтесь на встроенный файл в вашем HTML через URL вида cid:, значение которого совпадает с Content-ID файла. По умолчанию Content-ID (cid) для каждого встроенного файла — это ключ в массиве embeds, если он не изменён через фильтр 'wp_mail_embed_args'. Например:

Вы также можете настроить Content-ID для каждого файла, используя фильтр 'wp_mail_embed_args' и задав значение cid.

## Параметры

- `$to` `string|string[]` — обязательный. Массив или список адресов электронной почты через запятую для отправки сообщения.
- `$subject` `string` — обязательный. Тема письма.
- `$message` `string` — обязательный. Содержимое сообщения.
- `$headers` `string|string[]` — необязательный, по умолчанию `''`. Дополнительные заголовки.
- `$attachments` `string|string[]` — необязательный, по умолчанию `array()`. Пути к прикрепляемым файлам.
- `$embeds` `string|string[]` — необязательный, по умолчанию `array()`. Пути к встраиваемым файлам.

## Возвращаемое значение

`bool`

## Исходный код

Файл: `wp-includes/pluggable.php:189`

```php
function wp_mail( $to, $subject, $message, $headers = '', $attachments = array(), $embeds = array() ) {
	// Compact the input, apply the filters, and extract them back out.

	/**
	 * Filters the wp_mail() arguments.
	 *
	 * @since 2.2.0
	 * @since 6.9.0 The `$embeds` element was added to the `$args` array.
	 *
	 * @param array $args {
	 *     Array of the `wp_mail()` arguments.
	 *
	 *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
	 *     @type string          $subject     Email subject.
	 *     @type string          $message     Message contents.
	 *     @type string|string[] $headers     Additional headers.
	 *     @type string|string[] $attachments Paths to files to attach.
	 *     @type string|string[] $embeds      Paths to files to embed.
	 * }
	 */
	$atts = apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments', 'embeds' ) );

	/**
	 * Filters whether to preempt sending an email.
	 *
	 * Returning a non-null value will short-circuit wp_mail(), returning
	 * that value instead. A boolean return value should be used to indicate whether
	 * the email was successfully sent.
	 *
	 * @since 5.7.0
	 * @since 6.9.0 The `$embeds` element was added to the `$atts` array.
	 *
	 * @param null|bool $return Short-circuit return value.
	 * @param array     $atts {
	 *     Array of the `wp_mail()` arguments.
	 *
	 *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
	 *     @type string          $subject     Email subject.
	 *     @type string          $message     Message contents.
	 *     @type string|string[] $headers     Additional headers.
	 *     @type string|string[] $attachments Paths to files to attach.
	 *     @type string|string[] $embeds      Paths to files to embed.
	 * }
	 */
	$pre_wp_mail = apply_filters( 'pre_wp_mail', null, $atts );

	if ( null !== $pre_wp_mail ) {
		return $pre_wp_mail;
	}

	if ( isset( $atts['to'] ) ) {
		$to = $atts['to'];
	}

	if ( ! is_array( $to ) ) {
		$to = explode( ',', $to );
	}

	if ( isset( $atts['subject'] ) ) {
		$subject = $atts['subject'];
	}

	if ( isset( $atts['message'] ) ) {
		$message = $atts['message'];
	}

	if ( isset( $atts['headers'] ) ) {
		$headers = $atts['headers'];
	}

	if ( isset( $atts['attachments'] ) ) {
		$attachments = $atts['attachments'];
	}

	if ( ! is_array( $attachments ) ) {
		$attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
	}

	if ( isset( $atts['embeds'] ) ) {
		$embeds = $atts['embeds'];
	}

	if ( ! is_array( $embeds ) ) {
		$embeds = explode( "\n", str_replace( "\r\n", "\n", $embeds ) );
	}

	global $phpmailer;

	// (Re)create it, if it's gone missing.
	if ( ! ( $phpmailer instanceof PHPMailer\PHPMailer\PHPMailer ) ) {
		require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
		require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
		require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
		require_once ABSPATH . WPINC . '/class-wp-phpmailer.php';
		$phpmailer = new WP_PHPMailer( true );

		$phpmailer::$validator = static function ( $email ) {
			return (bool) is_email( $email );
		};
	}

	// Headers.
	$cc       = array();
	$bcc      = array();
	$reply_to = array();

	if ( empty( $headers ) ) {
		$headers = array();
	} else {
		if ( ! is_array( $headers ) ) {
			/*
			 * Explode the headers out, so this function can take
			 * both string headers and an array of headers.
			 */
			$tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
		} else {
			$tempheaders = $headers;
		}
		$headers = array();

		// If it's actually got contents.
		if ( ! empty( $tempheaders ) ) {
			// Iterate through the raw headers.
			foreach ( (array) $tempheaders as $header ) {
				if ( ! str_contains( $header, ':' ) ) {
					if ( false !== stripos( $header, 'boundary=' ) ) {
						$parts    = preg_split( '/boundary=/i', trim( $header ) );
						$boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
					}
					continue;
				}
				// Explode them out.
				list( $name, $content ) = explode( ':', trim( $header ), 2 );

				// Cleanup crew.
				$name    = trim( $name );
				$content = trim( $content );

				switch ( strtolower( $name ) ) {
					// Mainly for legacy -- process a "From:" header if it's there.
					case 'from':
						$bracket_pos = strpos( $content, '<' );
						if ( false !== $bracket_pos ) {
							// Text before the bracketed email is the "From" name.
							if ( $bracket_pos > 0 ) {
								$from_name = substr( $content, 0, $bracket_pos );
								$from_name = str_replace( '"', '', $from_name );
								$from_name = trim( $from_name );
							}

							$from_email = substr( $content, $bracket_pos + 1 );
							$from_email = str_replace( '>', '', $from_email );
							$from_email = trim( $from_email );

							// Avoid setting an empty $from_email.
						} elseif ( '' !== trim( $content ) ) {
							$from_email = trim( $content );
						}
						break;
					case 'content-type':
						if ( str_contains( $content, ';' ) ) {
							list( $type, $charset_content ) = explode( ';', $content );
							$content_type                   = trim( $type );
							if ( false !== stripos( $charset_content, 'charset=' ) ) {
								$charset = trim( str_replace( array( 'charset=', '"' ), '', $charset_content ) );
							} elseif ( false !== stripos( $charset_content, 'boundary=' ) ) {
								$boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset_content ) );
								$charset  = '';
								if ( preg_match( '~^multipart/(\S+)~', $content_type, $matches ) ) {
									$content_type = 'multipart/' . strtolower( $matches[1] ) . '; boundary="' . $boundary . '"';
								}
							}

							// Avoid setting an empty $content_type.
						} elseif ( '' !== trim( $content ) ) {
							$content_type = trim( $content );
						}
						break;
					case 'cc':
						$cc = array_merge( (array) $cc, explode( ',', $content ) );
						break;
					case 'bcc':
						$bcc = array_merge( (array) $bcc, explode( ',', $content ) );
						break;
					case 'reply-to':
						$reply_to = array_merge( (array) $reply_to, explode( ',', $content ) );
						break;
					default:
						// Add it to our grand headers array.
						$headers[ trim( $name ) ] = trim( $content );
						break;
				}
			}
		}
	}

	// Empty out the values that may be set.
	$phpmailer->clearAllRecipients();
	$phpmailer->clearAttachments();
	$phpmailer->clearCustomHeaders();
	$phpmailer->clearReplyTos();
	$phpmailer->Body    = '';
	$phpmailer->AltBody = '';

	/*
	 * Reset encoding to 8-bit, as it may have been automatically downgraded
	 * to 7-bit by PHPMailer (based on the body contents) in a previous call
	 * to wp_mail().
	 *
	 * See https://core.trac.wordpress.org/ticket/33972
	 */
	$phpmailer->Encoding = PHPMailer\PHPMailer\PHPMailer::ENCODING_8BIT;

	// Set "From" name and email.

	// If we don't have a name from the input headers.
	if ( ! isset( $from_name ) ) {
		$from_name = 'WordPress';
	}

	/*
	 * If we don't have an email from the input headers, default to wordpress@$sitename
	 * Some hosts will block outgoing mail from this address if it doesn't exist,
	 * but there's no easy alternative. Defaulting to admin_email might appear to be
	 * another option, but some hosts may refuse to relay mail from an unknown domain.
	 * See https://core.trac.wordpress.org/ticket/5007.
	 */
	if ( ! isset( $from_email ) ) {
		// Get the site domain and get rid of www.
		$sitename   = wp_parse_url( network_home_url(), PHP_URL_HOST );
		$from_email = 'wordpress@';

		if ( null !== $sitename ) {
			if ( str_starts_with( $sitename, 'www.' ) ) {
				$sitename = substr( $sitename, 4 );
			}

			$from_email .= $sitename;
		}
	}

	/**
	 * Filters the email address to send from.
	 *
	 * @since 2.2.0
	 *
	 * @param string $from_email Email address to send from.
	 */
	$from_email = apply_filters( 'wp_mail_from', $from_email );

	/**
	 * Filters the name to associate with the "from" email address.
	 *
	 * @since 2.3.0
	 *
	 * @param string $from_name Name associated with the "from" email address.
	 */
	$from_name = apply_filters( 'wp_mail_from_name', $from_name );

	try {
		$phpmailer->setFrom( $from_email, $from_name, false );
	} catch ( PHPMailer\PHPMailer\Exception $e ) {
		$mail_error_data                             = compact( 'to', 'subject', 'message', 'headers', 'attachments' );
		$mail_error_data['phpmailer_exception_code'] = $e->getCode();

		/** This filter is documented in wp-includes/pluggable.php */
		do_action( 'wp_mail_failed', new WP_Error( 'wp_mail_failed', $e->getMessage(), $mail_error_data ) );

		return false;
	}

	// Set mail's subject and body.
	$phpmailer->Subject = $subject;
	$phpmailer->Body    = $message;

	// Set destination addresses, using appropriate methods for handling addresses.
	$address_headers = compact( 'to', 'cc', 'bcc', 'reply_to' );

	foreach ( $address_headers as $address_header => $addresses ) {
		if ( empty( $addresses ) ) {
			continue;
		}

		foreach ( (array) $addresses as $address ) {
			try {
				// Break $recipient into name and address parts if in the format "Foo <bar@baz.com>".
				$recipient_name = '';

				if ( preg_match( '/(.*)<(.+)>/', $address, $matches ) ) {
					if ( count( $matches ) === 3 ) {
						$recipient_name = $matches[1];
						$address        = $matches[2];
					}
				}

				switch ( $address_header ) {
					case 'to':
						$phpmailer->addAddress( $address, $recipient_name );
						break;
					case 'cc':
						$phpmailer->addCC( $address, $recipient_name );
						break;
					case 'bcc':
						$phpmailer->addBCC( $address, $recipient_name );
						break;
					case 'reply_to':
						$phpmailer->addReplyTo( $address, $recipient_name );
						break;
				}
			} catch ( PHPMailer\PHPMailer\Exception $e ) {
				continue;
			}
		}
	}

	// Set to use PHP's mail().
	$phpmailer->isMail();

	// Set Content-Type and charset.

	// If we don't have a Content-Type from the input headers.
	if ( ! isset( $content_type ) ) {
		$content_type = 'text/plain';
	}

	/**
	 * Filters the wp_mail() content type.
	 *
	 * @since 2.3.0
	 *
	 * @param string $content_type Default wp_mail() content type.
	 */
	$content_type = apply_filters( 'wp_mail_content_type', $content_type );

	$phpmailer->ContentType = $content_type;

	// Set whether it's plaintext, depending on $content_type.
	if ( 'text/html' === $content_type ) {
		$phpmailer->isHTML( true );
	}

	// If we don't have a charset from the input headers.
	if ( ! isset( $charset ) ) {
		$charset = get_bloginfo( 'charset' );
	}

	/**
	 * Filters the default wp_mail() charset.
	 *
	 * @since 2.3.0
	 *
	 * @param string $charset Default email charset.
	 */
	$phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );

	// Set custom headers.
	if ( ! empty( $headers ) ) {
		foreach ( (array) $headers as $name => $content ) {
			// Only add custom headers not added automatically by PHPMailer.
			if ( ! in_array( $name, array( 'MIME-Version', 'X-Mailer' ), true ) ) {
				try {
					$phpmailer->addCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
				} catch ( PHPMailer\PHPMailer\Exception $e ) {
					continue;
				}
			}
		}
	}

	if ( ! empty( $attachments ) ) {
		foreach ( $attachments as $filename => $attachment ) {
			$filename = is_string( $filename ) ? $filename : '';

			try {
				$phpmailer->addAttachment( $attachment, $filename );
			} catch ( PHPMailer\PHPMailer\Exception $e ) {
				continue;
			}
		}
	}

	if ( ! empty( $embeds ) ) {
		foreach ( $embeds as $key => $embed_path ) {
			/**
			 * Filters the arguments for PHPMailer's addEmbeddedImage() method.
			 *
			 * @since 6.9.0
			 *
			 * @param array $args {
			 *     An array of arguments for PHPMailer's addEmbeddedImage() method.
			 *
			 *     @type string $path        The path to the file.
			 *     @type string $cid         The Content-ID of the image. Default: The key in the embeds array.
			 *     @type string $name        The filename of the image.
			 *     @type string $encoding    The encoding of the image. Default: 'base64'.
			 *     @type string $type        The MIME type of the image. Default: empty string, which lets PHPMailer auto-detect.
			 *     @type string $disposition The disposition of the image. Default: 'inline'.
			 * }
			 */
			$embed_args = apply_filters(
				'wp_mail_embed_args',
				array(
					'path'        => $embed_path,
					'cid'         => (string) $key,
					'name'        => basename( $embed_path ),
					'encoding'    => 'base64',
					'type'        => '',
					'disposition' => 'inline',
				)
			);

			try {
				$phpmailer->addEmbeddedImage(
					$embed_args['path'],
					$embed_args['cid'],
					$embed_args['name'],
					$embed_args['encoding'],
					$embed_args['type'],
					$embed_args['disposition']
				);
			} catch ( PHPMailer\PHPMailer\Exception $e ) {
				continue;
			}
		}
	}

	/**
	 * Fires after PHPMailer is initialized.
	 *
	 * @since 2.2.0
	 *
	 * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
	 */
	do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );

	$mail_data = compact( 'to', 'subject', 'message', 'headers', 'attachments', 'embeds' );

	// Send!
	try {
		$send = $phpmailer->send();

		/**
		 * Fires after PHPMailer has successfully sent an email.
		 *
		 * The firing of this action does not necessarily mean that the recipient(s) received the
		 * email successfully. It only means that the `send` method above was able to
		 * process the request without any errors.
		 *
		 * @since 5.9.0
		 * @since 6.9.0 The `$embeds` element was added to the `$mail_data` array.
		 *
		 * @param array $mail_data {
		 *     An array containing the email recipient(s), subject, message, headers, attachments, and embeds.
		 *
		 *     @type string[] $to          Email addresses to send message.
		 *     @type string   $subject     Email subject.
		 *     @type string   $message     Message contents.
		 *     @type string[] $headers     Additional headers.
		 *     @type string[] $attachments Paths to files to attach.
		 *     @type string[] $embeds      Paths to files to embed.
		 * }
		 */
		do_action( 'wp_mail_succeeded', $mail_data );

		return $send;
	} catch ( PHPMailer\PHPMailer\Exception $e ) {
		$mail_data['phpmailer_exception_code'] = $e->getCode();

		/**
		 * Fires after a PHPMailer exception is caught.
		 *
		 * @since 4.4.0
		 *
		 * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
		 *                        containing the mail recipient, subject, message, headers, attachments, and embeds.
		 */
		do_action( 'wp_mail_failed', new WP_Error( 'wp_mail_failed', $e->getMessage(), $mail_data ) );

		return false;
	}
}
```

## История изменений

- 6.9.0 — Improved Content-Type header handling for multipart messages.
- 5.5.0 — is_email() is used for email validation, instead of PHPMailer’s default validator.
- 1.2.1 — Introduced.

## Связанные

Использует: `WP_PHPMailer::__construct`, [`stripos`](https://chugunov.pro/api-wordpress/functions/stripos/), [`wp_parse_url`](https://chugunov.pro/api-wordpress/functions/wp_parse_url/), [`is_email`](https://chugunov.pro/api-wordpress/functions/is_email/), [`network_home_url`](https://chugunov.pro/api-wordpress/functions/network_home_url/), [`do_action_ref_array`](https://chugunov.pro/api-wordpress/functions/do_action_ref_array/), [`get_bloginfo`](https://chugunov.pro/api-wordpress/functions/get_bloginfo/), [`apply_filters`](https://chugunov.pro/api-wordpress/functions/apply_filters/), [`do_action`](https://chugunov.pro/api-wordpress/functions/do_action/), `WP_Error::__construct`.
Используется в: [`wpmu_new_site_admin_notification`](https://chugunov.pro/api-wordpress/functions/wpmu_new_site_admin_notification/), `WP_Automatic_Updater::send_plugin_theme_email`, `WP_Recovery_Mode_Email_Service::send_recovery_mode_email`, [`_wp_privacy_send_request_confirmation_notification`](https://chugunov.pro/api-wordpress/functions/_wp_privacy_send_request_confirmation_notification/), [`_wp_privacy_send_erasure_fulfillment_notification`](https://chugunov.pro/api-wordpress/functions/_wp_privacy_send_erasure_fulfillment_notification/), [`wp_send_user_request`](https://chugunov.pro/api-wordpress/functions/wp_send_user_request/), [`wp_privacy_send_personal_data_export_email`](https://chugunov.pro/api-wordpress/functions/wp_privacy_send_personal_data_export_email/), [`wp_site_admin_email_change_notification`](https://chugunov.pro/api-wordpress/functions/wp_site_admin_email_change_notification/), [`update_network_option_new_admin_email`](https://chugunov.pro/api-wordpress/functions/update_network_option_new_admin_email/), [`wp_network_admin_email_change_notification`](https://chugunov.pro/api-wordpress/functions/wp_network_admin_email_change_notification/), [`retrieve_password`](https://chugunov.pro/api-wordpress/functions/retrieve_password/), `WP_Automatic_Updater::send_email`, `WP_Automatic_Updater::send_debug_email`, [`update_option_new_admin_email`](https://chugunov.pro/api-wordpress/functions/update_option_new_admin_email/), [`send_confirmation_on_profile_email`](https://chugunov.pro/api-wordpress/functions/send_confirmation_on_profile_email/), [`wp_new_blog_notification`](https://chugunov.pro/api-wordpress/functions/wp_new_blog_notification/), [`wp_password_change_notification`](https://chugunov.pro/api-wordpress/functions/wp_password_change_notification/), [`wp_new_user_notification`](https://chugunov.pro/api-wordpress/functions/wp_new_user_notification/), [`wp_notify_postauthor`](https://chugunov.pro/api-wordpress/functions/wp_notify_postauthor/), [`wp_notify_moderator`](https://chugunov.pro/api-wordpress/functions/wp_notify_moderator/), [`wp_update_user`](https://chugunov.pro/api-wordpress/functions/wp_update_user/), [`wpmu_welcome_user_notification`](https://chugunov.pro/api-wordpress/functions/wpmu_welcome_user_notification/), [`newblog_notify_siteadmin`](https://chugunov.pro/api-wordpress/functions/newblog_notify_siteadmin/), [`newuser_notify_siteadmin`](https://chugunov.pro/api-wordpress/functions/newuser_notify_siteadmin/), [`wpmu_welcome_notification`](https://chugunov.pro/api-wordpress/functions/wpmu_welcome_notification/), [`wpmu_signup_blog_notification`](https://chugunov.pro/api-wordpress/functions/wpmu_signup_blog_notification/), [`wpmu_signup_user_notification`](https://chugunov.pro/api-wordpress/functions/wpmu_signup_user_notification/).

Оригинал в официальной документации: https://developer.wordpress.org/reference/functions/wp_mail/
