webklex/php-imap
PHP-IMAP is a pure-PHP IMAP client wrapper that works without the php-imap extension, supporting IMAP IDLE and OAuth auth. Optionally use php-imap for better decoding, edge cases, and legacy POP3 support.
## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require webklex/php-imap
For Laravel, use the dedicated wrapper:
composer require webklex/laravel-imap
Configuration:
Create a config file (e.g., config/imap.php) with your IMAP server details:
return [
'default' => [
'host' => env('IMAP_HOST', 'imap.example.com'),
'port' => env('IMAP_PORT', 993),
'encryption' => env('IMAP_ENCRYPTION', 'ssl'),
'validate_cert' => env('IMAP_VALIDATE_CERT', false),
'username' => env('IMAP_USERNAME'),
'password' => env('IMAP_PASSWORD'),
'protocol' => env('IMAP_PROTOCOL', 'imap'),
'path_prefix' => env('IMAP_PATH_PREFIX', ''),
],
];
First Use Case: Fetch and display unread emails from the INBOX:
use Webklex\PHPIMAP\ClientManager;
$clientManager = new ClientManager('config/imap.php');
$client = $clientManager->account('default');
$client->connect();
$unreadMessages = $client->getFolder('INBOX')
->messages()
->whereFlag('\\Seen', false)
->get();
foreach ($unreadMessages as $message) {
echo $message->getSubject() . "\n";
}
ClientManager: Manages multiple IMAP accounts/configurations.Client: Handles connection and folder operations.Folder: Represents an IMAP folder (e.g., INBOX, Sent).Message: Represents an email with methods for parsing, attachments, and actions.$client = $clientManager->account('default');
$client->connect(); // Establish connection
// Fetch all messages from a folder with pagination
$messages = $client->getFolder('INBOX')
->messages()
->paginate(10, 1); // 10 items, page 1
foreach ($messages as $message) {
echo $message->getSubject() . "\n";
}
Use query builders for complex searches:
// Find unread messages from a specific sender
$messages = $client->getFolder('INBOX')
->messages()
->whereFlag('\\Seen', false)
->whereFrom('sender@example.com')
->get();
// Search using custom criteria (e.g., subject contains "invoice")
$messages = $client->getFolder('INBOX')
->messages()
->search('SUBJECT "invoice"')
->get();
foreach ($messages as $message) {
$attachments = $message->getAttachments();
foreach ($attachments as $attachment) {
$path = $attachment->saveTo(storage_path('app/attachments'));
echo "Saved: " . $path . "\n";
}
}
$message->move('INBOX.Archived'); // Move to a folder
$message->copy('INBOX.Backup'); // Copy to another folder
$client->idle(function ($message) {
echo "New message arrived: " . $message->getSubject() . "\n";
});
Configure OAuth in your IMAP settings and use the oauth protocol:
$client->setConfig([
'protocol' => 'oauth',
'oauth_token' => 'your_oauth_token',
]);
$client->connect();
webklex/laravel-imap package for seamless Laravel integration:
use Webklex\IMAP\Facades\IMAP;
$messages = IMAP::account('default')->getFolder('INBOX')->messages()->get();
config/app.php:
'providers' => [
Webklex\IMAP\IMAPServiceProvider::class,
],
Offload heavy IMAP operations (e.g., processing thousands of emails) to Laravel queues:
dispatch(new ProcessEmailsJob($client, 'INBOX'));
Cache folder/message data to reduce IMAP server load:
$cacheKey = 'imap_messages_' . md5('INBOX');
$messages = Cache::remember($cacheKey, now()->addHours(1), function () use ($client) {
return $client->getFolder('INBOX')->messages()->get();
});
Wrap IMAP operations in try-catch blocks:
try {
$client->connect();
$messages = $client->getFolder('INBOX')->messages()->get();
} catch (\Webklex\PHPIMAP\Exceptions\ConnectionException $e) {
Log::error('IMAP Connection Failed: ' . $e->getMessage());
// Retry logic or fallback
}
'timeout' => 30, // seconds
imap.php:
'decoder' => [
'charset' => 'utf-8',
'iconv_options' => ['//IGNORE'],
],
Message::getRawBody() to inspect raw content if parsing fails.INBOX/Special Folder) may break.path_prefix in config:
'path_prefix' => 'INBOX/',
$client->idle(function ($message) {
echo "New message: " . $message->getSubject() . "\n";
}, 60); // Timeout after 60 seconds
IMAP::FT_PEEK to avoid marking messages as seen during IDLE.$attachment->saveTo(storage_path('app/attachments'), true); // Stream to disk
'date_formats' => [
'Y-m-d H:i:s',
'D, d M Y H:i:s O',
// Add custom formats if needed
],
php-imap extension.php-imap extension or use the legacy-imap protocol:
'protocol' => 'legacy-imap',
$client->setDebug(true);
$client->connect();
Check logs for raw IMAP commands/responses.
$rawBody = $message->getRawBody();
file_put_contents('debug.eml', $rawBody); // Save to file for inspection
Masks allow fetching only specific parts of a message to reduce load:
$messages = $client->getFolder('INBOX')
->messages()
->mask(['subject', 'from', 'date']) // Only fetch
How can I help you explore Laravel packages today?