-
Notifications
You must be signed in to change notification settings - Fork 91
[BUG] Fix PHP 8.x incompatibility in SMTP5 library (each() removed in PHP 8.0) #257
Description
Problem
When using multiOTP 5.10.x with the embedded PHP 8.4.x, sending emails via SMTP fails with a fatal PHP error:
PHP Fatal error: Uncaught Error: Call to undefined function each()
in /usr/local/bin/multiotp/multiotp.proxy.php on line 65732
The same error occurs in index.php (used by the web service / XmlServer):
PHP Fatal error: Uncaught Error: Call to undefined function each()
in /usr/local/bin/multiotp/index.php on line 65732
The each() function was deprecated in PHP 7.2 and completely removed in PHP 8.0. The embedded SMTP5 library still uses it in the SMTP authentication handshake.
Root Cause
In the SMTP5 class, the SMTP authentication method detection uses each():
php// Before fix (broken on PHP 8.x):
list($code, $arr) = each($_RESULT);
Fix
Replace each() with its PHP 8.x compatible equivalent:
php// After fix (compatible with PHP 8.x):
$code = key($_RESULT); $arr = current($_RESULT); next($_RESULT);
This fix needs to be applied in two files:
multiotp.proxy.php
index.php
One-liner to apply:
bashsed -i 's/list($code, $arr) = each($_RESULT);/$code = key($_RESULT); $arr = current($_RESULT); next($_RESULT);/' multiotp.proxy.php
sed -i 's/list($code, $arr) = each($_RESULT);/$code = key($_RESULT); $arr = current($_RESULT); next($_RESULT);/' index.php
Additional findings during investigation
- SMTP password config key corruption
When setting SMTP password via CLI (multiotp -config smtp-password=...), the key is sometimes written as smtp_password:= instead of smtp_password= in multiotp.ini, causing silent authentication failure. Setting it directly in the ini file avoids this. - SMTP SSL mode logic
The $ssl_mode detection in SendEmail() only checks smtp_ssl=1 for SSL mode but does not handle STARTTLS (port 587). Port 465 with smtp_ssl=1 works correctly. Port 587 with STARTTLS causes a TLS handshake error because the library connects with TLS directly instead of upgrading via STARTTLS.
Recommendation: Use port 465 with smtp_ssl=1 for Gmail and other providers that support it. - email_code_allowed disabled by default
The email_code_allowed config is 0 by default, which causes error 66 when trying to send OTP by email. This should be documented more prominently.
Environment
multiOTP version: 5.10.1.5
PHP version: 8.4.16
Deployment: Docker (multiotp/multiotp-open-source)
SMTP provider tested: Gmail (smtp.gmail.com:465, SSL)
Dockerfile workaround (for Docker users until fix is merged)
dockerfileFROM multiotp/multiotp-open-source
RUN sed -i 's/list($code, $arr) = each($_RESULT);/$code = key($_RESULT); $arr = current($_RESULT); next($_RESULT);/'
/usr/local/bin/multiotp/multiotp.proxy.php &&
sed -i 's/list($code, $arr) = each($_RESULT);/$code = key($_RESULT); $arr = current($_RESULT); next($_RESULT);/'
/usr/local/bin/multiotp/index.php
I hope it will be usefull for someone who also wants to add their smtp.
And hope dev's will fix it