Webklex / php-imap

PHP-IMAP is a wrapper for common IMAP communication without the need to have the php-imap module installed / enabled. The protocol is completely integrated and therefore supports IMAP IDLE operation and the "new" oAuth authentication process as well.
https://www.php-imap.com
MIT License
315 stars 149 forks source link

how to fix memory issue when loading message? #516

Open cris-m opened 1 month ago

cris-m commented 1 month ago

I was trying to load emails. it work on other email but I get issue with email account with multiple messages.

here is the code:

 $config = config('imap.accounts.default');
$config['username'] = $credentials['email'];
$config['password'] = $credentials['password'];

$client = Client::make($config);
$folders = [];
$mailFolders = $client->getFolders($hierarchical = false);

foreach ($mailFolders as $folder) {
    $folder_name = $folder->name;

    $folders[$folder_name]['unread_count'] = $folder->messages()->unseen()->count();
    $folders[$folder_name]['messages'] = [];

    $folder->messages()->all()->chunked(function ($messages, $chunk) use ($folder_name, &$folders) {
        $messages->each(function($message) use ($folder_name, &$folders) {
            $folders[$folder_name]['messages'][] = $message;
        });
    }, $chunk_size = 10, $start_chunk = 1);
}

I get the following issue in laravel:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 1576960 bytes) in vendor/webklex/php-imap/src/Part.php on line 196

Is there a better way to load all message?

Drackokacka commented 1 month ago

If you don't need to access older messages, you could use folder's method since to get smaller batch of messages, see example:

$messages = $folder->query()
    ->since('01.01.2024')
    ->all();

I hope someone will come with better solution to read ALL messages in chunks without heavy memory impact.

cris-m commented 1 month ago

I still getting the same error. if there a way to handle an account with multiple messages?

bjaverhagen commented 1 month ago

I had a memory problem when fetching messages with large attachments? I fixed the memory-issue with this solution: #457 Maybe it can help you to.

cris-m commented 1 month ago

I had to increase memory_limit in php.ini to 512M but loading all the message throw :

Webklex\ PHPIMAP\ Exceptions\ GetMessagesFailedException
Trailing data

I tried the following:


 public function index(Request $request)
    {
        $credentials = decrypt(session('imap_credentials'));
        $config = config('imap.accounts.default');
        $config['username'] = $credentials['email'];
        $config['password'] = $credentials['password'];

        $client = Client::make($config);

        if (!$client->isConnected()) {
            try {
                $client->checkConnection();
            } catch (\Exception $e) {
                Auth::logout();
                $request->session()->invalidate();

                return redirect()->route('login')->with('alert', [
                    'type' => 'danger',
                    'message' => 'Failed to connect to the email server. You have been logged out. Please log in again.',
                ]);
            }
        }

        $folders = [];
        $mailFolders = $client->getFolders($hierarchical = false);

        foreach ($mailFolders as $folder) {
            $folder_name = $folder->name;

            // Get unread message count
            $folders[$folder_name]['unread_count'] = $folder->messages()->unseen()->count();

            // Fetch messages from the folder
            $folders[$folder_name]['messages'] = $folder->messages()->all()->fetchOrderDesc()->get();
        }

        return view('office.emails.test', compact('folders'));
    }