Très novice en PHP, j'utilise un script pour copier et supprimer des fichiers présents sur un serveur distant, et je génère un mail au format html pour avoir un suivi de ces manipulations.
Le problème est que des espaces ou des sauts de lignes s'insèrent dans des chaînes et perturbent l'affichage. Par exemple "<span>" devient "<s pan>" ce qui souligne le texte suivant, ou "<br/> qui devient "<b r/>" et passe le texte en gras. Je viens de trouver le remplacement de "<span style" par "<span s tyle", ce qui supprime la couleur affectée au texte qui suit. Ces ajouts intempestifs se retrouvent même parfois dans les noms de fichiers. Je précise que cela n'impacte que le corps du mail de trace.
J'ai traité toutes les occurrences possibles d'insertion d'espaces dans span et br, mais je n'ai pas trouvé comment faire pour les sauts de lignes.
Le corps du mail est créé par des lignes de ce type :
$mail_body .= '<span style ="color: black;">' .$orig_file . ' transféré de serveur à serveur</span><br/>';
L'ajout d'espace ou de sauts de lignes se fait autant dans les instructions span, br et style que dans les noms et chemins des fichiers, et seulement dans le corps du mail, sans impact sur le traitement des fichiers
Le script balaie les sous-dossiers de "storage", en récupère le nom dans $folder, puis analyse la date des fichiers dans chaque sous-dossier --> $file pour si besoin les copier vers un dossier "akstorage" et y supprimer.
Un exemple de $orig_file : /storage/demos/site-apprendre.monsite.tld-20240403-103856cest-kUW2fFsao1_Yix6F.jpa
Le problème pourrait venir de ce qu'avec les mails, il y a souvent un "encodage" quoted-printable. Si tu ne sembles pas avoir de souci avec le contenu sinon les retours à la ligne, attention au fait que cet "encodage" peut aussi insérer des retours à la ligne de manière "dure" dans le texte, donc après X caractères, même si c'est dans une balise. Or, on sait qu'un retour à la ligne est interprété comme une espace en HTML…
Si tu effectues déjà une passe de transformation, il serait intéressant de voir comment elle opère et l'adapter le cas échéant.
Edit
Ça sent en effet le type de média renseigné de manière inattendue.
Mais j'ai un doute car l'exemple de "$orig_file" (avec le nom de domaine réel) ci-dessus comporte déjà 89 caractères et n'est pas coupé dans le code-source.
La ligne la plus longue, non coupée elle aussi, fait 139 caractères.
Par ailleurs, étant du html, je n'utilise pas \r\n mais <br/> et le changement de ligne fonctionne sans erreur.
L'utilisation de chunk_split a provoqué une erreur Gateway, et impossible ensuite d'obtenir autre chose que la liste des dossiers, puisqu'aucun nouveau fichier n'est à traiter.
Le script n'est utilisé habituellement qu'en tâche cron, une fois par semaine.
Ymox, le fichier comportant certaines données sensibles, il me faudrait les masquer pour pouvoir en afficher le code ici. De plus, si j'ai bien vu, il n'est pas possible de joindre le fichier mais seulement d'insérer ce code.
PS : Malgré l'erreur, j'ai bien reçu le mail, sans anomalie dans son corps. Cependant, comme ces insertions sont aléatoires, il m'est difficile de dire si les ajouts de ces lignes de code sont ou non la solution. On verra lors des prochaines exécutions de la tâche cron.
Si le fichier contient des données sensibles, forcément, il faut les caviarder si tu souhaites fournir cela ici. Et oui, on préfère avoir directement le code. Evidemment, ne modifies que les données, pas des éléments liés directement à son fonctionnement.
Je résume : il s'agit dune duplication de fichiers et suppression des plus anciens, situés sur un serveur dédié aux backups. Le script est situé sur un serveur web.
J'ai supprimé la partie infos d'accès au serveur de backups et masqué les infos d'expéditeur et destinataire du mail.
Désolé, mon message explicatif en réponse a Ymox a été refusé par le forum et je ne pourrai répondre que dans 24 heures !
J'y disais que base64 était peut-être en cause : les mails m'arrivaient vides. En commentant la ligne comme l'est ci-dessus celle de chunk_split, en ajoutant Doctype et en décalant la tâche cron, j'ai bien reçu un corps de message non vide, mais les fichiers ayant été traités quelques minutes plus tôt, je n'ai que les infos des dossiers examinés. Prochain cron dans une semaine...
Tu as tenté de faire un chunk_split(base64_encode(…)), le problème est qu'avec cela, on va introduire des retours à la ligne dans les données base64. J'espère qu'au décodage, ils ne seront pas pris en compte, mais je pense au vu du sujet ils le sont et les chaînes base64 pourraient être converties lignes par lignes sinon comme un ensemble. Seulement si certaines fois cela ne se voit pas du fait des caractères, cela pose problème quand cela survient au milieu des balises. Mais comme c'est dépendant du client mail, cela pourra varier de l'un à l'autre avec le même message…
Dans un premier temps, je constate que tu n'as pas ajouté le "prédicat" <!DOCTYPE html> dans ce que tu envoies, cela peut avoir des conséquences suivant le client utilisé, mais vu la simplicité de ce que tu envoies comme structure HTML, si c'est vraiment ça, coup de chance.
Par contre, mes excuses, je croyais que tu envoyais les différences de contenus de fichiers par mail (comme si tu faisais un diff), je n'avais pas compris que c'était le mail en lui-même qui était ainsi problématique.
Note qu'utiliser mail() n'est pas le plus pratique, peut-être que, sans que cela ne te livre le fin mot, passer à une bibliothèque comme PhpMailer pourrait être un peu plus rentable.
Je pense m'être trompé en disant que malgré l'erreur Gateway les mails arrivaient corrects, car j'en ai ensuite reçu dont le corps était vide. Dans la version actuelle, où chunk_split a été désactivé comme dans le code ci-dessus, je viens de recevoir le mail de la tâche cron avec le contenu totalement vide encore ( $headers .= "Content-Transfer-Encoding: base64" . "\r\n"; en cause ?).
Le problème reste la construction du $mail_body, le reste fonctionnant sans anomalie.
Je viens de commenter la ligne d'encodage base64 et de décaler l'heure du cron après avoir ajouté au tout début
$mail_body = "<!DOCTYPE html>";
La tâche cron vient de m'envoyer le mail dont le contenu comporte bien toute une série de lignes concernant le nom du dossier en cours, mais rien sur les fichiers traités puisqu'ils ont déjà été traités il y a quelques minutes. Il va donc falloir attendre plusieurs jours si je force une exécution manuellement, une semaine si j’attends la tâche cron.
@Robert_G Bonjour, je viens de retirer des spam votre dernier message si cela arrive encore vous pouvez poster dans ce sujet Si votre message est considéré comme spam
Après un problème de messagerie hier où le mail de résultat expédié par la tâche cron hier à 9h35 ne m'est parvenu que ce matin à 8h13, en fait bloqué dans la messagerie de l'expéditeur, je constate hélas qu'au moins une espace a encore été ajoutée dans le texte, n'impactant pas cette fois l’affichage de mise en couleurs :
Est-ce que tu pourrais nous fournir le code brut de l'e-mail tel que reçu, ainsi que les en-têtes (en caviardant évidemment ce qui doit l'être, mais signalant si une des valeurs à masquer comporte aussi un problème) ?
Désolé, mais il y aurait des dizaines de noms de fichiers à masquer. Le code source fait 55050 lettres, 34130 pour le contenu affiché du mail.
En l'occurrence, il ne s'agissait pas d'espace mais de saut de ligne dans le mot "serveur" et j'ai trouvé d'autres lignes concernées au moins par ces sauts de lignes.
PS : En regardant le code-source dans notepad++ (Outlook me l'ouvre dans le bloc-notes), je trouve des lignes limitées à 997 caractères, puis l'insertion d'un saut de ligne.
Il n'y a qu'un seul paragraphe défini dans la génération du code source. Faudrait-il définir des paragraphes ou remplacer <br/> par des \r\n pour forcer des sauts de lignes et éviter ces ajouts en trop d'espaces et sauts de lignes ?
C'est ce quoi je m'attendais, des sauts de ligne parce que d'une manière ou d'une autre, la longueur du texte "brut" par ligne est limitée.
Je te proposerais d'essayer avec le type quoted-printable et la fonction quoted_printable_encode() plutôt qu'une base 64 ? L'avantage étant que tu pourrais l'utiliser sur un chunk_split(), il me semble que les retours à la ligne devraient moins poser de problème.
Je ne comprends pas : si je scinde les lignes en 70 caractères, si "\r\n" tombe au milieu d'un mot, comment la couleur, par exemple, va-t-elle être prise en compte si un saut de ligne s'insère entre "s" et "tyle" dans le mot "style" ?
Mais à voir le dernier mail reçu j'ai l'impression que ce ne sont pas ces sauts de ligne en trop qui posent problème, mais plus les espaces ajoutées dans certains mots.
Ne pas oublier que retour à la ligne ou espace, en HTML, ça s'affichera de la même manière, vu qu'il faut a minima un <br /> pour avoir un retour à la ligne dans la page.
Mon idée est que quelque part, le message est "forcé" à un certain nombre de caractères par ligne, et comme cette manière de forcer n'est pas consciente du HTML, si ça survient dans les balises, ben…
Reste à savoir si c'est au niveau du serveur SMTP (donc à l'envoi, mais après l'appel à mail()) ou du serveur de réception.
Edit
Je ne souhaite pas remonter ce sujet pour un détail pareil, en espérant que ce n'est justement pas le souci : tous tes en-têtes sont sous la forme [nom]:[espace][valeur], sauf… Content-type:text/html qui n'a pas d'espace. Même si celui-ci n'est pas obligatoire, il est recommandé. A voir si ce n'est pas le client qui, détectant du HTML dans le texte, l'analyse malgré un en-tête qui pourrait lui poser problème.
Je ne comprends pas : si je scinde les lignes en 70 caractères, si "\r\n" tombe au milieu d'un mot, comment la couleur, par exemple, va-t-elle être prise en compte si un saut de ligne s'insère entre "s" et "tyle" dans le mot "style" ?
Mais à voir le dernier mail reçu j'ai l'impression que ce ne sont pas ces sauts de ligne en trop qui posent problème, mais plus les espaces ajoutées dans certains mots.
Re, c'est un wordwrap donc pas au milieu d'un mot. voir doc ici ?
Sinon, avez-vous essayé ? Comme le souligne très justement Ymox, il ne faut pas confondre les sauts de ligne html avec les fins de ligne (\r\n) théoriquement nécessaires
Je vais essayer en plus d'enregistrer le code dans un fichier texte pour m'assurer de ce qui est transmis à la messagerie, et il faudra attendre que de nouveaux fichiers soient à copier, en plus de ceux qui auront dépassé la date de conservation et doivent être supprimés.
Bon, un coup pour rien ! J'ai eu la mauvaise idée de définir la copie du contenu du mail dans un fichier avant d'envoyer le mail et je n'ai ni l'un ni l'autre.
Je ne vois pas quelle erreur j'ai faite ici ($time a été précédemment défini par strtotime("now")) :
gb-net.fr
gb-net.fr
gb-net.fr
gb-net.fr