How to Use Blat with PHP — Step-by-Step ExampleSending email from PHP on a Windows server can be straightforward when you use a small command-line utility called Blat. Blat is a lightweight tool that sends email via SMTP and can be invoked from PHP with the exec/system functions. This guide walks through installation, configuration, examples for plain text and HTML emails with attachments, error handling, and security considerations.
What is Blat?
Blat is a free, open-source command-line SMTP mailer for Windows. It can send messages via a local SMTP server or a remote SMTP service (with authentication). Because it’s a standalone executable, PHP scripts can call Blat to send mail even when PHP’s built-in mail() function is not configured or not available.
Key fact: Blat runs on Windows and is invoked from the command line; PHP interacts with it by executing shell commands.
Why use Blat with PHP?
- Works on Windows servers where sendmail/postfix aren’t available.
- Simple to configure and script.
- Supports attachments, HTML content, SMTP auth, and custom headers.
- Useful when you want direct control over SMTP parameters from PHP.
Prerequisites
- Windows server (IIS, XAMPP for Windows, WAMP, etc.).
- PHP installed and configured.
- Blat executable downloaded and available on the server (or in your application directory).
- Access to an SMTP server (local or remote) and credentials if authentication is required.
- PHP functions for executing shell commands must be enabled (exec, shell_exec, system, passthru). If they’re disabled for security, you’ll need another approach.
Install and configure Blat
- Download Blat from the official site or a trusted archive. Place blat.exe into a directory, e.g., C:lat or your application folder.
- Optionally add the Blat directory to the system PATH so it’s callable from any working directory:
- System Properties → Advanced → Environment Variables → Path → Edit → Add C:lat
- Configure default SMTP server (optional): Open a command prompt and run:
C:latlat.exe -install smtp.example.com [email protected] 25 -u username -pw password
This stores default server settings so you can use Blat without specifying SMTP each time. If you prefer not to store credentials, pass them on the command line when sending.
Basic PHP + Blat: plain text email
Create a simple PHP script that writes the message to a temporary file, then calls Blat to send it.
Example:
<?php $to = '[email protected]'; $subject = 'Test email from PHP using Blat'; $body = "Hello, This is a test message sent via Blat invoked from PHP. Regards, PHP Server"; // Create temp file for message body $tempFile = tempnam(sys_get_temp_dir(), 'blat_'); file_put_contents($tempFile, $body); // Build Blat command $blatPath = 'C:\blat\blat.exe'; // adjust path if needed $cmd = escapeshellarg($blatPath) . ' ' . escapeshellarg($tempFile) . ' -to ' . escapeshellarg($to) . ' -subject ' . escapeshellarg($subject) . ' -mime'; // use -mime for proper encoding // Execute command and capture output exec($cmd . ' 2>&1', $output, $returnVar); // Clean up temp file unlink($tempFile); if ($returnVar === 0) { echo "Email sent successfully."; } else { echo "Failed to send email. Output: " . implode(" ", $output); }
Notes:
- Use temp files to avoid quoting issues when passing multiline bodies.
- escapeshellarg() is used to reduce injection risk.
- Redirecting stderr to stdout (2>&1) captures error messages.
Sending HTML email
To send HTML email, include appropriate headers and use the -mime option with the content-type header.
Example:
<?php $to = '[email protected]'; $subject = 'HTML Email from PHP via Blat'; $html = "<html><body><h1>Hello</h1><p>This is <strong>HTML</strong> content.</p></body></html>"; $tempFile = tempnam(sys_get_temp_dir(), 'blat_'); file_put_contents($tempFile, $html); $blatPath = 'C:\blat\blat.exe'; $cmd = escapeshellarg($blatPath) . ' ' . escapeshellarg($tempFile) . ' -to ' . escapeshellarg($to) . ' -subject ' . escapeshellarg($subject) . ' -mime' . ' -header ' . escapeshellarg('Content-Type: text/html; charset=UTF-8'); exec($cmd . ' 2>&1', $output, $returnVar); unlink($tempFile); if ($returnVar === 0) { echo "HTML email sent."; } else { echo "Failed. " . implode(" ", $output); }
Sending attachments
Blat supports attachments with the -attach option. For multiple attachments, pass -attach multiple times or separate with commas.
Example:
<?php $to = '[email protected]'; $subject = 'Email with Attachment'; $body = "Please find the attached file."; $tempFile = tempnam(sys_get_temp_dir(), 'blat_'); file_put_contents($tempFile, $body); $attachment = 'C:\path\to\file.pdf'; $blatPath = 'C:\blat\blat.exe'; $cmd = escapeshellarg($blatPath) . ' ' . escapeshellarg($tempFile) . ' -to ' . escapeshellarg($to) . ' -subject ' . escapeshellarg($subject) . ' -mime' . ' -attach ' . escapeshellarg($attachment); exec($cmd . ' 2>&1', $output, $returnVar); unlink($tempFile); if ($returnVar === 0) echo "Sent with attachment."; else echo "Error: " . implode(" ", $output);
Using SMTP authentication and SSL/TLS
Blat can authenticate and use SSL/TLS depending on the version. If your SMTP server requires auth and encryption, either configure defaults with -install (as above) or pass options on each call.
Common options:
- -server smtp.example.com
- -port 587 (or 465 for implicit SSL)
- -u username
- -pw password
- -smtps (or -ssl) — depends on Blat build/version for enabling SSL
Example:
$cmd = escapeshellarg($blatPath) . ' ' . escapeshellarg($tempFile) . ' -to ' . escapeshellarg($to) . ' -subject ' . escapeshellarg($subject) . ' -mime' . ' -server ' . escapeshellarg('smtp.example.com') . ' -port 587' . ' -u ' . escapeshellarg('smtpuser') . ' -pw ' . escapeshellarg('smtppassword') . ' -starttls';
Check your Blat version for the exact flags for SSL/TLS (-starttls, -smtps, -ssl).
Security tip: avoid embedding plaintext credentials in code or scripts. Use environment variables or a protected configuration file with strict permissions.
Handling errors and logging
- Capture command output and exit code in PHP (exec or shell_exec).
- Log both stdout/stderr and exit codes to a secure log for troubleshooting.
- For transient SMTP failures, implement retries with exponential backoff.
- Check Blat’s error messages; common issues are authentication failures, blocked ports, or firewall rules.
Security considerations
- Use escapeshellarg() for every variable included in shell commands to reduce injection risk.
- Restrict file permissions on temp files and config files that may contain credentials.
- Prefer environment variables or Windows Protected Storage for SMTP credentials.
- If possible, configure Blat with default server settings via -install and restrict access to the Blat executable.
- Ensure your PHP process runs with minimal privileges necessary.
Example: function wrapper for reuse
<?php function sendWithBlat($to, $subject, $body, $attachments = [], $options = []) { $tempFile = tempnam(sys_get_temp_dir(), 'blat_'); file_put_contents($tempFile, $body); $blat = $options['blatPath'] ?? 'C:\blat\blat.exe'; $cmdParts = [escapeshellarg($blat), escapeshellarg($tempFile), '-to', escapeshellarg($to), '-subject', escapeshellarg($subject), '-mime']; if (!empty($options['server'])) { $cmdParts[] = '-server'; $cmdParts[] = escapeshellarg($options['server']); } if (!empty($options['port'])) { $cmdParts[] = '-port'; $cmdParts[] = escapeshellarg($options['port']); } if (!empty($options['user'])) { $cmdParts[] = '-u'; $cmdParts[] = escapeshellarg($options['user']); } if (!empty($options['pass'])) { $cmdParts[] = '-pw'; $cmdParts[] = escapeshellarg($options['pass']); } foreach ($attachments as $att) { $cmdParts[] = '-attach'; $cmdParts[] = escapeshellarg($att); } $cmd = implode(' ', $cmdParts) . ' 2>&1'; exec($cmd, $output, $code); unlink($tempFile); return ['code' => $code, 'output' => $output]; }
Troubleshooting checklist
- Verify blat.exe path and that PHP user can execute it.
- Test Blat from a Windows command prompt first to isolate PHP issues.
- Ensure outbound SMTP ports (25, 465, 587) are open in firewall and hosting provider allows SMTP.
- Confirm SMTP credentials and encryption settings match the server requirements.
- Check for disabled PHP execution functions (exec, shell_exec, system).
Alternatives
- Use PHP’s built-in mail() with a properly configured SMTP server in php.ini (Windows).
- Use a PHP mail library like PHPMailer or SwiftMailer — these provide native SMTP support, robust MIME handling, and better security without shell calls.
- Use an external email API (SendGrid, Mailgun, etc.) for improved deliverability and analytics.
Blat is a practical, lightweight choice for sending mail from PHP on Windows when other solutions aren’t available. For production systems, weigh the security implications of executing shell commands from PHP versus using native PHP libraries or APIs.