Solution au problème de connexion PHP FTP dans un environnement conteneurisé
P粉302484366
2023-08-28 23:03:17
<p>J'essaie de conteneuriser mon script PHP. </p><p>Mais pour une raison quelconque, il ne peut pas se connecter à mon serveur FTP lorsqu'il est exécuté dans un conteneur. </p><p>Exécutez le script sur ma machine locale sans aucun problème. </p><p><strong>Dockerfile :</strong></p><pre class="brush:php;toolbar:false;">FROM php:8.1-cli
EXPOSER 8080
COPIER ./var/www/html/
RÉP TRAVAIL /var/www/html
ENTRYPOINT php -f serve.php</pre><p><strong>Script PHP :</strong></p><pre class="brush:php;toolbar:false;">$ connexion = ftp_connect(FTP_HOST, 21, 90);
ftp_pasv($connexion, vrai);
si (ftp_login ($ connexion, FTP_USERNAME, FTP_PASSWORD))
{
$stream = fopen('data://text/plain,','r');
ftp_fput ($ connexion, $ nom de fichier, $ flux);
}
ftp_close ($connection);</pre><p>Après 90 secondes, l'avertissement suivant s'affichera : </p><p><em>ftp_fput() : connexion expirée dans /var/ www/html/ftp.php sur la ligne 16</em></p><p>J'ai essayé d'accéder au conteneur et d'installer le client FTP. </p><p>Cela me donne une erreur de délai d'attente similaire : je peux me connecter à l'hôte, mais l'exécution d'une commande provoque une pause. </p><p>J'ai également essayé d'exécuter le conteneur sur un VPS pour éliminer tout problème de pare-feu/réseau local. </p><p>Mais le problème existe toujours. </p><p>Si vous avez besoin de plus amples informations pour résoudre le problème, veuillez me le faire savoir. </p>
Faites attention à la documentation de la
ftp_pasv
fonction de PHP (c'est moi qui souligne) :Notez également que vous ne vérifiez pas la valeur de retour d'état de l'appel
ftp_pasv
调用的状态返回值,所以您不会注意到该调用是否实际成功(这很可能不会成功)。因此,您的脚本将尝试建立主动的 FTP 连接。这在容器中不起作用(除非使用--network=host
, vous ne remarquerez donc pas si l'appel a réellement réussi (ce qui ne sera probablement pas le cas). Par conséquent, votre script tentera d'établir une connexion FTP active. Cela ne fonctionne pas dans les conteneurs (sauf si démarré avec--network=host
), car les conteneurs s'exécutent dans un réseau privé via NAT sur la machine hôte.Solution : connectez-vous d'abord, puis activez le mode passif (vérifiez également toujours les valeurs de retour d'erreur ; de nombreuses anciennes fonctions de la bibliothèque standard PHP ne génèrent pas d'exceptions, mais s'appuient sur des valeurs de retour d'erreur) :