PHP mail() не работает, PHPMailer падает, Composer ломается: полный разбор ошибок и решений

mr. Cooper 1 час назад Веб-разработка
PHP mail() не работает, PHPMailer падает, Composer ломается: полный разбор ошибок и решений

Вы запускаете PHP-скрипт, отправляете письмо - и тишина. Или видите белый экран, или загадочное Class not found. Эти ошибки встречаются у большинства разработчиков, но гуглить их каждый раз - то ещё удовольствие. В этой статье разберём пять самых частых проблем с почтой, Composer и автозагрузкой классов: почему они возникают и как их решить раз и навсегда.

Функция mail() - встроенный инструмент PHP для отправки писем. Она передаёт сообщение локальному почтовому агенту (sendmail, postfix, exim). Если агент не настроен или заблокирован - письма уходят в никуда, и PHP об этом молчит.

Почему это происходит

mail() возвращает true даже если письмо не доставлено. Это не значит «письмо отправлено» - это значит «письмо принято очередью». Частые причины:

  • На сервере не установлен и не запущен sendmail/postfix.

  • Хостинг блокирует исходящий SMTP (порт 25).

  • В php.ini неверно задан параметр sendmail_path.

  • Письмо попадает в спам и вы его просто не видите.

  • Запуск через локальный сервер (XAMPP, Laragon) - там mail() не работает по умолчанию.

Как диагностировать

$result = mail('test@example.com', 'Тест', 'Тело письма');
var_dump($result); // true ≠ доставлено

// Смотрите логи
// Linux: /var/log/mail.log или /var/log/maillog
// Или через PHP
ini_set('sendmail_from', 'you@yourdomain.com');
error_log(print_r(error_get_last(), true));

Проверьте php.ini:

; Для Linux
sendmail_path = /usr/sbin/sendmail -t -i

; Для Windows (XAMPP)
SMTP = smtp.gmail.com
smtp_port = 587

Решение: переходите на PHPMailer или SMTP

mail() - устаревший инструмент. Для надёжной отправки используйте PHPMailer или Symfony Mailer через SMTP. Это работает на любом хостинге.

PHP SMTP ошибка при отправке email через PHPMailer

Частые ошибки

SMTP connect() failed.
Could not authenticate.
SMTP Error: Could not connect to SMTP host.
535 Incorrect authentication data

Причины

1. Неверные параметры подключения

$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host       = 'smtp.gmail.com';  // не mail.gmail.com!
$mail->SMTPAuth   = true;
$mail->Username   = 'you@gmail.com';
$mail->Password   = 'your-app-password'; // не пароль аккаунта!
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port       = 587;

2. Gmail блокирует «ненадёжные» приложения

С 2022 года Google отключил «доступ для ненадёжных приложений». Используйте App Password (пароль приложения):

  1. Включите двухфакторную аутентификацию в аккаунте Google.

  2. Перейдите: Аккаунт Google → Безопасность → Пароли приложений.

  3. Создайте пароль для «Почты» и «Windows/Linux».

  4. Используйте этот 16-значный пароль в $mail->Password.

3. SSL/TLS конфликт

// Если получаете SSL: certificate verify failed
$mail->SMTPOptions = [
    'ssl' => [
        'verify_peer'       => false,
        'verify_peer_name'  => false,
        'allow_self_signed' => true,
    ]
];
// Только для отладки! На проде используйте нормальный сертификат.

4. Порт заблокирован хостингом

Порт 25 почти всегда закрыт. Используйте:

  • 587 + STARTTLS - рекомендуется

  • 465 + SSL - альтернатива

Полный рабочий пример

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

try {
    $mail->isSMTP();
    $mail->Host       = 'smtp.gmail.com';
    $mail->SMTPAuth   = true;
    $mail->Username   = 'you@gmail.com';
    $mail->Password   = 'abcd efgh ijkl mnop'; // App Password
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port       = 587;
    $mail->CharSet    = 'UTF-8';

    $mail->setFrom('you@gmail.com', 'Ваше имя');
    $mail->addAddress('recipient@example.com');
    $mail->Subject = 'Тема письма';
    $mail->Body    = 'Текст письма';

    $mail->send();
    echo 'Письмо отправлено';
} catch (Exception $e) {
    echo "Ошибка: {$mail->ErrorInfo}";
}

Composer: ошибка «Could not open input file: composer.phar»

Что происходит

Вы вводите php composer.phar install или просто composer install - и получаете:

Could not open input file: composer.phar

Причины и решения

Причина 1: вы не в той папке

# Неверно - composer.phar нет в текущей директории
php composer.phar install

# Верно - укажите полный путь или перейдите в нужную папку
cd /path/to/project
php composer.phar install

Причина 2: Composer не установлен глобально

# Проверьте, установлен ли Composer глобально
composer --version

# Если нет - установите:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"

# Для глобальной установки (Linux/Mac)
sudo mv composer.phar /usr/local/bin/composer

Причина 3: На Windows неверная команда

# Если установлен через installer - просто:
composer install

# Если composer.phar лежит в папке проекта:
php composer.phar install

Причина 4: composer.phar повреждён или отсутствует

Скачайте заново с официального сайта: https://getcomposer.org/download/

Composer install: конфликт зависимостей

Типичное сообщение

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - phpmailer/phpmailer v6.8.0 requires php ^7.2|^8.0
    - Your PHP version (7.1.33) does not satisfy that requirement.

Как разобраться

Шаг 1: читайте ошибку полностью

Composer объясняет конфликт построчно. Определите: это конфликт версий PHP, конфликт пакетов между собой, или ограничения composer.json.

Шаг 2: обновите PHP или понизьте пакет

# Посмотреть какую версию пакета можно поставить
composer require phpmailer/phpmailer:^6.5 --dry-run

# Разрешить установку с предупреждениями
composer install --ignore-platform-reqs
# Осторожно: только для dev-окружения!

Шаг 3: используйте why и why-not

# Почему пакет не может быть установлен
composer why-not phpmailer/phpmailer 6.8

# Что требует конкретный пакет
composer why symfony/console

Шаг 4: обновите composer.lock

# Пересчитать зависимости
composer update --with-dependencies

# Обновить конкретный пакет
composer update phpmailer/phpmailer

Шаг 5: проверьте минимальную стабильность

// composer.json
{
  "minimum-stability": "stable",
  "prefer-stable": true
}

PHP autoload не находит классы: ошибка Class not found

Симптомы

Fatal error: Uncaught Error: Class 'PHPMailer\PHPMailer\PHPMailer' not found
PHP Fatal error: Class 'App\Models\User' not found

Причины и решения

Причина 1: забыли подключить autoload

// Это обязательно в начале каждого скрипта!
require_once 'vendor/autoload.php';

Причина 2: не запустили composer dump-autoload

После добавления новых классов или изменения composer.json → autoload нужно обновить:

composer dump-autoload
# Или с оптимизацией для продакшна
composer dump-autoload --optimize

Причина 3: неверное пространство имён

PSR-4 autoload чувствителен к регистру и структуре папок.

// composer.json
{
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  }
}

Класс App\Models\User должен лежать в src/Models/User.php, и внутри файла:

<?php
namespace App\Models;

class User {
    // ...
}

Причина 4: опечатка в имени класса или namespace

// Неверно
use App\Model\User;   // Model вместо Models

// Верно
use App\Models\User;

Причина 5: регистр имени файла (Linux)

На Windows user.php и User.php - одно и то же. На Linux - разные файлы. Имя файла должно совпадать с именем класса с учётом регистра.

# Проверьте реальное имя файла
ls -la src/Models/

Часто задаваемые вопросы (FAQ)

Почему mail() возвращает true, но письма нет? true означает, что функция передала письмо локальному агенту. Доставка зависит от конфигурации сервера, не от PHP. Используйте PHPMailer с SMTP для надёжной отправки.

Как проверить, что SMTP подключение работает? Включите отладку PHPMailer: $mail->SMTPDebug = SMTP::DEBUG_SERVER; - это выведет полный лог переговоров с сервером.

Можно ли использовать Gmail SMTP бесплатно? Да, через App Password. Лимит - 500 писем в день. Для больших объёмов используйте Mailgun, SendGrid или Amazon SES.

Что делать, если Composer зависает при установке? Попробуйте: composer install --no-interaction --prefer-dist. Или добавьте зеркало: composer config repo.packagist composer https://packagist.org.

Нужно ли коммитить composer.lock в git? Да, для приложений - обязательно. Это фиксирует точные версии зависимостей. Для библиотек - нет, добавьте в .gitignore.

Как добавить собственные классы в autoload без Composer? Зарегистрируйте через spl_autoload_register():

spl_autoload_register(function ($class) {
    require 'classes/' . $class . '.php';
});

Почему composer update ломает проект? update поднимает версии до последних допустимых по composer.json. Используйте composer install (использует composer.lock) для воспроизводимой установки.

Class not found есть только на сервере, локально всё работает? Скорее всего, забыли запустить composer install на сервере или не загрузили папку vendor/ при деплое.

Полезные советы и лучшие практики

Не используйте mail() в продакшне. PHPMailer, Symfony Mailer или SwiftMailer - любой из них надёжнее нативной функции.

Храните SMTP-данные в .env. Никогда не хардкодьте пароли в коде:

$mail->Password = $_ENV['SMTP_PASSWORD'];

Настройте SPF, DKIM и DMARC для своего домена - это снижает вероятность попадания в спам.

Для локальной разработки используйте Mailpit или Mailtrap - они перехватывают письма и показывают их в веб-интерфейсе без реальной отправки.

Запускайте composer validate перед install - это проверяет корректность composer.json.

Добавляйте vendor/ в .gitignore. Папка с зависимостями не должна быть в репозитории.

Используйте composer install --no-dev на продакшне - это исключает dev-пакеты и ускоряет установку.

Итог

Большинство проблем с почтой в PHP - следствие использования устаревшей функции mail() или неверных настроек SMTP. PHPMailer с App Password решает 90% случаев. Ошибки Composer в большинстве случаев лечатся внимательным чтением сообщения об ошибке и командой dump-autoload. Если классы не находятся - проверьте три вещи: подключён ли vendor/autoload.php, совпадает ли namespace со структурой папок, запущен ли composer dump-autoload после изменений.

Комментарии

Пока нет комментариев. Будьте первым, кто напишет.

Чтобы оставить комментарий, войдите в аккаунт.

Похожие статьи