Shoutbox avec ajax

Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention   -  
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour a tous,


J'utilise une petite shoutbox qui me sert de tchat pour discuter avec des amis sur un serveur privé.Tout fonctionnait a merveille avant que je fasse une mise a jour (je suis sous debian 11).Du coup je sais pas si le problème vient du code ou du navigateur.J'utilise apache2 en serveur web.J'ai pris ce bout de code ajax sur le net et j'en été très satisfait j'usqua présent.Le code est simple pour m'éviter d'avoir a créer une base de donnée que je ne saurais pas gérer.Quand quelqu'un envoi un message, ce message est enregistré dans un fichier texte nommé "chat.txt" et ansi de suite pour les autres messages, le fichier texte est lu et son contenu s'affiche donc sur la page du tchat.


Voici le code de la page du tchat:


<?php
/*Just for your server-side code*/
header('Content-Type: text/html; charset=UTF-8');
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<meta charset="utf-8">
<style type="text/css">
body { padding-left:40px; background-image:radial-gradient(white, black);;; font-family:arial;}
input, textarea { font-family: courier new; font-size: 12px; }
#content { width:800px; text-align:left; margin-left:60px; }

#chatwindow { border:1px solid #aaaaaa; padding:4px; background:#ff8000; color:white;}
#chatnick { border: none; border-bottom:1px solid #aaaaaa; padding:4px; background:#ff8000;}
#chatmsg { border: none; border-bottom:1px solid #aaaaaa; padding:4px; background:#ff8000; }

#info { text-align:left; padding-left:0px; font-family:arial; }
#info td { font-size:12px; padding-right:10px; color:#ff8000; }
#info .small { font-size:10px; padding-left:10px; padding-right:0px; }

#info a { text-decoration:none; color:white; }
#info a:hover { text-decoration:underline; color:#; }

</style>
</head>
<body>
<div id="info">
<br>
<table border="0">
<tr>
<td colspan="2">
</td>
</tr>
<br>
<center><div id="content">
<textarea id="chatwindow" rows="19" cols="95" readonly></textarea><br>

<input id="chatnick" type="text" size="9" maxlength="10" placeholder="Nom"> 
<input id="chatmsg" type="text" size="80" maxlength="80" onkeyup="keyup(event.keyCode);" placeholder="message">
<input type="button" value="Envoyer" onclick="submit_msg();" style="cursor:pointer;border:1px solid gray;"><br><br>
</div></center>
<br>
<br>
<script>
var nick_maxlength=10;
var http_request=false;
var http_request2=false;
var intUpdate;


/* http_request for writing */
function ajax_request(url){http_request=false;if(window.XMLHttpRequest){http_request=new XMLHttpRequest();if(http_request.overrideMimeType){http_request.overrideMimeType('text/xml');}}else if(window.ActiveXObject){try{http_request=new ActiveXObject("Msxml2.XMLHTTP");}catch(e){try{http_request=new ActiveXObject("Microsoft.XMLHTTP");}catch(e){}}}
if(!http_request){alert('Giving up :( Cannot create an XMLHTTP instance');return false;}
http_request.onreadystatechange=alertContents;http_request.open('GET',url,true);http_request.send(null);}
function alertContents(){if(http_request.readyState==4){if(http_request.status==200){rec_response(http_request.responseText);}else{}}}


/* http_request for reading */
function ajax_request2(url){http_request2=false;if(window.XMLHttpRequest){http_request2=new XMLHttpRequest();if(http_request2.overrideMimeType){http_request2.overrideMimeType('text/xml');}}else if(window.ActiveXObject){try{http_request2=new ActiveXObject("Msxml2.XMLHTTP");}catch(e){try{http_request2=new ActiveXObject("Microsoft.XMLHTTP");}catch(e){}}}
if(!http_request2){alert('Giving up :( Cannot create an XMLHTTP instance');return false;}
http_request2.onreadystatechange=alertContents2;http_request2.open('GET',url,true);http_request2.send(null);}
function alertContents2(){if(http_request2.readyState==4){if(http_request2.status==200){rec_chatcontent(http_request2.responseText);}else{}}}

/* chat stuff */
chatmsg.focus()
var show_newmsg_on_bottom=1; /* set to 0 to let new msg´s appear on top */
var waittime=1000; /* time between chat refreshes (ms) */

intUpdate=window.setTimeout("read_cont();", waittime);
chatwindow.value = "Bienvenue sur le tchat";


function read_cont() { zeit = new Date(); ms = (zeit.getHours() * 24 * 60 * 1000) + (zeit.getMinutes() * 60 * 1000) + (zeit.getSeconds() * 1000) + zeit.getMilliseconds(); ajax_request2("chat.txt?x=" + ms); }
function display_msg(msg1) { chatwindow.value = msg1.trim(); }
function keyup(arg1) { if (arg1 == 13) submit_msg(); }
function submit_msg() { clearTimeout(intUpdate); if (chatnick.value == "") { check = prompt("please enter username:"); if (check === null) return 0; if (check == "") check="..."; chatnick.value=check; } if (chatnick.value.length > nick_maxlength) chatnick.value=chatnick.value.substring(0,nick_maxlength); spaces=""; for(i=0;i<(nick_maxlength-chatnick.value.length);i++) spaces+=" "; v=chatwindow.value.substring(chatwindow.value.indexOf("\n")) + "\n" + chatnick.value + spaces + "| " + chatmsg.value; if (chatmsg.value != "") chatwindow.value=v.substring(1); write_msg(chatmsg.value,chatnick.value); chatmsg.value=""; intUpdate=window.setTimeout("read_cont();", waittime);}
function write_msg(msg1,nick1) { ajax_request("w.php?m=" + encodeURIComponent(msg1) + "&n=" + encodeURIComponent(nick1)); }
function rec_response(str1) { }

function rec_chatcontent(cont1) {
if (cont1 != "") {
out1 = unescape(cont1);
if (show_newmsg_on_bottom == 0) { out1 = ""; while (cont1.indexOf("\n") > -1) { out1 = cont1.substr(0, cont1.indexOf("\n")) + "\n" + out1; cont1 = cont1.substr(cont1.indexOf("\n") + 1); out1 = unescape(out1); } }
if (chatwindow.value != out1) { display_msg(out1); }
intUpdate=window.setTimeout("read_cont()", waittime);
}
}</script>
</body>
</html>



Maintenant voici le code du fichier w.php (w pour write):

<?php
/**
  • Author: chris at linuxuser.at * Licence: MIT */ $fn = "chat.txt"; $maxlines = 1000; $nick_maxlength = 10; /* Set this to a minimum wait time between posts (in sec) */ $waittime_sec = 0; /* spam keywords */ $spam[] = "cum"; $spam[] = "dick"; $spam[] = "EAT coon"; /* IP's to block */ $blockip[] = "72.60.167.89"; /* spam, if message IS exactly that string */ $espam[] = "ajax"; $msg = $_REQUEST["m"]; $n = $_REQUEST["n"]; if ($waittime_sec > 0) { $lastvisit = $_COOKIE["lachatlv"]; setcookie("lachatlv", time()); if ($lastvisit != "") { $diff = time() - $lastvisit; if ($diff < $waittime_sec) { die(); } } } if ($msg != "") { if (strlen($msg) < 2) { die(); } if (strlen($msg) > 3) { /* Smilies are ok */ if (strtoupper($msg) == $msg) { die(); } } if (strlen($msg) > 150) { die(); } if (strlen($msg) > 15) { if (substr_count($msg, substr($msg, 6, 8)) > 1) { die(); } } foreach ($blockip as $a) { if ($_SERVER["REMOTE_ADDR"] == $a) { die(); } } $mystring = strtoupper($msg); foreach ($spam as $a) { if (strpos($mystring, strtoupper($a)) === false) { /* Everything Ok Here */ } else { die(); } } foreach ($espam as $a) { if (strtoupper($msg) == strtoupper($a)) { die(); } } $handle = fopen ($fn, 'r'); $chattext = fread($handle, filesize($fn)); fclose($handle); $arr1 = explode("\n", $chattext); if (count($arr1) > $maxlines) { /* Pruning */ $arr1 = array_reverse($arr1); for ($i=0; $i<$maxlines; $i++) { $arr2[$i] = $arr1[$i]; } $arr2 = array_reverse($arr2); } else { $arr2 = $arr1; } $chattext = implode("\n", $arr2); // Last spam filter: die if message has already been in the chat history if (substr_count($chattext, $msg) > 2) { die(); } $spaces = ""; if (strlen($n) > $nick_maxlength-1) $n = substr($n, 0, $nick_maxlength-1); for ($i=0; $i<($nick_maxlength - strlen($n)); $i++) $spaces .= " "; $out = $chattext . $n . $spaces . "| " . $msg . "\n"; $out = str_replace("\'", "'", $out); $out = str_replace("\\\"", "\"", $out); $handle = fopen ($fn, 'w'); fwrite($handle, $out.trim()); fclose($handle); $input = fopen($file, 'r'); } ?>



Si jamais c'est un problème de droits, voici les règles de l'ensemble des fichiers:

rwxrwxrwx 1 root www-data     0 17 févr. 06:18 chat.txt
-rwxrwxrwx 1 root www-data 5310 17 févr. 06:25 tchat.php
-rwxrwxrwx 1 root www-data 2657 8 oct. 17:14 w.php



D'ou vient le problème d'après vous ? Je précise que tout marchait bien il y a encore 2 jours avant que je fasse une misa a jour de ma debian 11.


Merci a vous.


Configuration: Linux / Chrome 98.0.4758.102

20 réponses

jordane45 Messages postés 38486 Date d'inscription   Statut Modérateur Dernière intervention   4 752
 
Bonjour
Vu qur c'est dr l'Ajax.. commence par regarder dans la console JavaScript de ton navigateur ce qui s'y affiche (de préfèrence en passant par firefox et en ayant activé le debugage de l'Ajax (xhr) )
0
jordane45 Messages postés 38486 Date d'inscription   Statut Modérateur Dernière intervention   4 752
 
EDIT : Erreur de discussion

0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour a vous deux


Je pense que le problème vient pas directement du code en lui meme mais de apache ou de la version php utilisée.Je m'explique avec un autre ordinateur sous ubuntu 20.04 j'ai hébergé et testé la shoutbox et ça marche bien, mes messages s'affiche et le fichier chat.txt est correctement lu.Quand je repasse l'hébergement de la shoutbox sous debian 11 et mon serveur apache ça ne marche plus.

J'ai activer le xhr comme mentionné plus haut, j'obtiens une erreur 500 lors de l'envoi du message avec ma debian:

GEThttp://127.0.0.1/shout/w.php?m=User&n= test
[HTTP/1.0 500 Internal Server Error 1ms]



Comme je l'ai précisé, le code marche avec ubuntu20.04 et apache ça marche... je comprends pas vraiment.Voici les différence entre les différences entre ma version de apache et php sous debian 11 d'abord:

Apache

apache2 -v  
Server version: Apache/2.4.52 (Debian)
Server built: 2021-12-20T17:42:09


php

PHP 8.1.2 (cli) (built: Jan 27 2022 01:00:14) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
with Zend OPcache v8.1.2, Copyright (c), by Zend Technologies



Les modules chargés par apache

apachectl -M
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
Loaded Modules:
core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
unixd_module (static)
access_compat_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
authn_file_module (shared)
authz_core_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
filter_module (shared)
mime_module (shared)
mpm_prefork_module (shared)
negotiation_module (shared)
php_module (shared)
reqtimeout_module (shared)
setenvif_module (shared)
status_module (shared)



Maintenant configuration avec ubuntu 20.04 (qui donc marche bien avec la shoutbox)

apache2 -v
Server version: Apache/2.4.52
Server built: 2022-01-03T21:27:14

php

PHP 7.4.25 (cli) (built: Oct 23 2021 21:53:50) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.25, Copyright (c), by Zend Technologies



Les modules chargés par apache


apachectl -M
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
Loaded Modules:
core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
unixd_module (static)
access_compat_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
authn_file_module (shared)
authz_core_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
filter_module (shared)
mime_module (shared)
mpm_prefork_module (shared)
negotiation_module (shared)
php7_module (shared)
reqtimeout_module (shared)
setenvif_module (shared)
status_module (shared)



Si ça marche avec ubuntu20.04 et pas debian11 c'est donc coté serveur ou version php que ça plante ?


Merci
0
jordane45 Messages postés 38486 Date d'inscription   Statut Modérateur Dernière intervention   4 752
 
Tu as monté de version de PHP ( php 8 )
Une erreur 500 indique une erreur côté serveur.. soit dans la configuration d'apache/php .. soit une erreur de code dans la page.
Si tu as d'autres pages php dans ton site et qu'elles fonctionnent.. c'est que le souci vient donc du code php appellé par ton script ajax.

Certaines fonctions ont été désactivées (ou remplacées) sur php 8
Il faudrait donc tester le code du fichier w.php "morceaux" par morceaux .. pour essayer de trouver là où ça bloque
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Pitet Messages postés 2826 Date d'inscription   Statut Membre Dernière intervention   527
 
Bonjour,

Sur ton serveur debian, utilise la commande suivante pour localiser le journal d'erreur de php :
php -i | grep error_log


Puis regarde dans ce fichier pour trouver le message d'erreur correspondant au retour 500.
0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour,

voici les dernière lignes de mon fichier error.log: (j'ai mis que la dernière ligne vu que les autres lignes renvoient la meme chose)

[Thu Feb 17 15:58:35.828722 2022] [php:error] [pid 2049] [client 127.0.0.1:54930] PHP Fatal error:  Uncaught ValueError: fread(): Argument #2 ($length) must be greater than 0 in /var/www/shout/w.php:68\nStack trace:\n#0 /var/www/shout/w.php(68): fread()\n#1 {main}\n  thrown in /var/www/shout/w.php on line 68, referer: http://127.0.0.1/shout/tchat.php



On peut s'apercevoir que c'est ligne 68 de w.php que ça coince, voici la ligne en question:

$chattext = fread($handle, filesize($fn)); fclose($handle);



Et le code en entier:


<?php
/**
  • Author: chris at linuxuser.at * Licence: MIT */ $fn = "chat.txt"; $maxlines = 1000; $nick_maxlength = 10; /* Set this to a minimum wait time between posts (in sec) */ $waittime_sec = 0; /* spam keywords */ $spam[] = "cum"; $spam[] = "dick"; $spam[] = "EAT coon"; /* IP's to block */ $blockip[] = "72.60.167.89"; /* spam, if message IS exactly that string */ $espam[] = "ajax"; $msg = $_REQUEST["m"]; $n = $_REQUEST["n"]; if ($waittime_sec > 0) { $lastvisit = $_COOKIE["lachatlv"]; setcookie("lachatlv", time()); if ($lastvisit != "") { $diff = time() - $lastvisit; if ($diff < $waittime_sec) { die(); } } } if ($msg != "") { if (strlen($msg) < 2) { die(); } if (strlen($msg) > 3) { /* Smilies are ok */ if (strtoupper($msg) == $msg) { die(); } } if (strlen($msg) > 150) { die(); } if (strlen($msg) > 15) { if (substr_count($msg, substr($msg, 6, 8)) > 1) { die(); } } foreach ($blockip as $a) { if ($_SERVER["REMOTE_ADDR"] == $a) { die(); } } $mystring = strtoupper($msg); foreach ($spam as $a) { if (strpos($mystring, strtoupper($a)) === false) { /* Everything Ok Here */ } else { die(); } } foreach ($espam as $a) { if (strtoupper($msg) == strtoupper($a)) { die(); } } $handle = fopen ($fn, 'r'); $chattext = fread($handle, filesize($fn)); fclose($handle); $arr1 = explode("\n", $chattext); if (count($arr1) > $maxlines) { /* Pruning */ $arr1 = array_reverse($arr1); for ($i=0; $i<$maxlines; $i++) { $arr2[$i] = $arr1[$i]; } $arr2 = array_reverse($arr2); } else { $arr2 = $arr1; } $chattext = implode("\n", $arr2); // Last spam filter: die if message has already been in the chat history if (substr_count($chattext, $msg) > 2) { die(); } $spaces = ""; if (strlen($n) > $nick_maxlength-1) $n = substr($n, 0, $nick_maxlength-1); for ($i=0; $i<($nick_maxlength - strlen($n)); $i++) $spaces .= " "; $out = $chattext . $n . $spaces . "| " . $msg . "\n"; $out = str_replace("\'", "'", $out); $out = str_replace("\\\"", "\"", $out); $handle = fopen ($fn, 'w'); fwrite($handle, $out.trim()); fclose($handle); $input = fopen($file, 'r'); } ?>



J'avoue que cette erreur:

PHP Fatal error:  Uncaught ValueError: fread(): Argument #2 ($length) must be greater than 0 


je ne la comprends pas très bien.
0
jordane45 Messages postés 38486 Date d'inscription   Statut Modérateur Dernière intervention   4 752
 
Essaye de reposter ton code correctement ( en indiquant le langage dans les balises de code et en faisant des retours à la ligne de de l'indentation dans ton code .. ) car là c'est illisible.
Explications sur l'utilisation correcte des balises de code ( à lire entièrement ! ) disponibles ici : https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

Merci
0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Effectivement j'ai pas fais attention désolé.

Voici le code de w.php intégral:


<?php
    /**
     * Author: chris at linuxuser.at
     * Licence: MIT
     */
    $fn = "chat.txt";
    $maxlines = 1000;

    $nick_maxlength = 10;

    /* Set this to a minimum wait time between posts (in sec) */
    $waittime_sec = 0;

    /* spam keywords */
    $spam[] = "cum";
    $spam[] = "dick";
    $spam[] = "EAT coon";

    /* IP's to block */
    $blockip[] = "72.60.167.89";

    /* spam, if message IS exactly that string */
    $espam[] = "ajax";

    $msg = $_REQUEST["m"];
    $n = $_REQUEST["n"];
 

    if ($waittime_sec > 0) {
        $lastvisit = $_COOKIE["lachatlv"];
        setcookie("lachatlv", time());

        if ($lastvisit != "") {
            $diff = time() - $lastvisit;
            if ($diff < $waittime_sec) { die(); }
        }
    }

    if ($msg != "") {
        if (strlen($msg) < 2) { die(); }
        if (strlen($msg) > 3) {
            /* Smilies are ok */
            if (strtoupper($msg) == $msg) { die(); }
        }
        if (strlen($msg) > 150) { die(); }
        if (strlen($msg) > 15) {
            if (substr_count($msg, substr($msg, 6, 8)) > 1) { die(); }
        }

        foreach ($blockip as $a) {
            if ($_SERVER["REMOTE_ADDR"] == $a) { die(); }
        }

        $mystring = strtoupper($msg);
        foreach ($spam as $a) {
             if (strpos($mystring, strtoupper($a)) === false) {
                 /* Everything Ok Here */
             } else {
                 die();
             }
        }

        foreach ($espam as $a) {
            if (strtoupper($msg) == strtoupper($a)) { die(); }
        }

        $handle = fopen ($fn, 'r');
        $chattext = fread($handle, filesize($fn)); fclose($handle);

        $arr1 = explode("\n", $chattext);

        if (count($arr1) > $maxlines) {
            /* Pruning */
            $arr1 = array_reverse($arr1);
            for ($i=0; $i<$maxlines; $i++) { $arr2[$i] = $arr1[$i]; }
            $arr2 = array_reverse($arr2);
        } else {
            $arr2 = $arr1;
        }

        $chattext = implode("\n", $arr2);


        // Last spam filter: die if message has already been in the chat history
        if (substr_count($chattext, $msg) > 2) { die(); }

        $spaces = "";
        if (strlen($n) > $nick_maxlength-1) $n = substr($n, 0, $nick_maxlength-1);
        for ($i=0; $i<($nick_maxlength - strlen($n)); $i++) $spaces .= " ";

        $out = $chattext . $n . $spaces . "| " . $msg . "\n";
        $out = str_replace("\'", "'", $out);
        $out = str_replace("\\\"", "\"", $out);
        $handle = fopen ($fn, 'w'); fwrite($handle, $out.trim()); fclose($handle);
        $input = fopen($file, 'r');
  }      
?>/code>


Et la ligne 68 qui pose problème:

<code php>$chattext = fread($handle, filesize($fn)); fclose($handle);
0
jordane45 Messages postés 38486 Date d'inscription   Statut Modérateur Dernière intervention   4 752
 
Le message semble indiquer un souci avec la taille du fichier.
... le fichier existe ?
.. il n'est pas vide ?

0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Le fichier chat.txt est vide tant que personne n'envoi de message sur la page tchat.php, une fois que les messages sont envoyés le fichier est lu et les messages sont stockés dans chat.txt et s'affichent ensuite dans tchat.php, tout les fichiers utiles a la shoutbox sont situés dans le meme répertoire.

oot@debian:/var/www/shout# ls -l
total 76
-rwxrw-r-- 1 root www-data    17 17 févr. 11:14 chat.txt
-rw-r--r-- 1 root www-data  5680 28 nov.  16:51 tchat.php
-rw-r--r-- 1 root www-data  2657 28 nov.  16:51 w.php



Pour infos j'ai trouvé le code de la shoutbox ici:
https://www.metachris.com/projects/most-simple-ajax-chat-ever/


Comme mentionné ce code a marché pendant plus de 2 ans et marche toujours avec ubuntu 20.04 et php 7.4 mais pas avec debian 11 et php8.1

Bien sur je pourrais continuer a héberger la shoutbox sous ma machine ubuntu mais j'aimerais comprendre d'ou vient cette erreur sachant que tot ou tard j'y serais a nouveau confronté avec une update.
0
Pitet Messages postés 2826 Date d'inscription   Statut Membre Dernière intervention   527
 
Je n'ai pas trouvé l'info dans le changelog ou la doc de PHP, mais à priori la fonction fread() ne retourne pas le même type d'erreur avec PHP 7.4 et PHP 8+

Avec PHP 7.4 :
$ php -r "echo fread(fopen('emptyfile.txt', 'r'), filesize('emptyfile.txt')); echo 'done';"

Warning: fread(): Length parameter must be greater than 0 in Command line code on line 1
done

Si le fichier est vide, PHP retourne une alerte (Warning), ce type d'erreur n'arrête pas l'exécution du script (le "echo 'done';" s'affiche bien).

Avec PHP 8.1 :
$ php -r "echo fread(fopen('emptyfile.txt', 'r'), filesize('emptyfile.txt')); echo 'done';"

Fatal error: Uncaught ValueError: fread(): Argument #2 ($length) must be greater than 0 in Command line code:1
Stack trace: [...]

Si le fichier est vide, PHP retourne une erreur fatale, l'exécution du script est interrompue (le "echo 'done';" ne s'affiche pas).

C'est donc surement la raison pour laquelle le script fonctionnait sur ton serveur avec PHP 7.4, puisque même si le fichier txt était vide, l'erreur déclenchée par fread() n'interrompait pas le script.

Au lieu d'utiliser fopen() fread() fclose(), une manière plus rapide pour récupérer tout le contenu d'un fichier est d'utiliser la fonction file_get_contents() avec laquelle tu ne devrais pas avoir d'erreur même si le fichier est vide (à condition que celui-ci existe et est accessible en lecture) :
<?php

$fn = 'chat.txt';

// ...

$chattext = '';

if (is_readable($fn)) {
    $chattext = file_get_contents($fn);
}
0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Bonsoir,


Bien vu pour le file_get_contents je ne savais pas merci :)

J'ai modifié le script avec votre code et j'ai une nouvelle erreur mais cette fois-ci a la toute fin du script, error.log:

Thu Feb 17 21:48:35.661918 2022] [php:error] [pid 11450] [client 127.0.0.1:55010] PHP Fatal error:  Uncaught ArgumentCountError: trim() expects at least 1 argument, 0 given in /var/www/shout/w.php:97\nStack trace:\n#0 /var/www/shout/w.php(97): trim()\n#1 {main}\n  thrown in /var/www/shout/w.php on line 97, referer: http://127.0.0.1/shout/tchat.php


La ligne 97 c'est celle-ci:

$handle = fopen ($fn, 'w'); fwrite($handle, $out.trim()); fclose($handle);



J'ai quand meme l'impression que c'était plus facile avec les versions antérieur a php8... enfin je ne m'y connais pas assez pour pouvoir émettre un jugement non plus.
0
Pitet Messages postés 2826 Date d'inscription   Statut Membre Dernière intervention   527
 
Oula, je n'avais pas vu le script original. Le dépôt github indique que le code date de 2006, pas sûr que tu es choisi le meilleur exemple ;) Le script semble être fait pour du PHP 5 et à priori il n'a jamais fonctionné comme il devrait le faire.

Même problème que fread(), la fonction trim() sans paramètre déclenche une erreur fatale en PHP 8 alors qu'elle déclenche un warning en PHP 7.

Surtout, la syntaxe "$out.trim()" pour appliquer la fonction trim sur la chaine $out n'existe pas en PHP, je pense que l'auteur a confondu avec du JavaScript.
Pour appliquer la fonction trim en PHP, il faut passer la chaine de caractère en paramètre de la fonction (celle-ci permet de supprimer les espaces au début et à la fin de la chaine) :
<?php

$out = '    mon super message    ';

echo '[' . $out . ']'; // affiche [    mon super message    ]
echo '[' . trim($out) . ']'; // affiche [mon super message]


En utilisant la syntaxe "$out.trim()", le script fait simplement une concaténation de la variable $out avec le retour de la fonction trim() qui est une chaine vide puisqu'elle n'a pas de paramètre (ce qui déclenche également le warning/error car utiliser trim sans paramètre n'est pas correct et n'a pas de sens).
<?php

$out = '    mon super message    ';

echo '[' . $out . trim() . ']'; // affiche [    mon super message    ] (warning ou fatal error)


L'utilisation de trim pour supprimer les espaces au début et à la fin de la chaine $out n'a jamais fonctionné dans ce script, et cette syntaxe a toujours dû déclencher un warning avant PHP 8 (ton fichier log en PHP 7.4 doit en être rempli).
La syntaxe correcte serait simplement :
$handle = fopen ($fn, 'w'); fwrite($handle, trim($out)); fclose($handle);
// ou avec file_put_contents
file_put_contents($fn, trim($out));


Concernant la facilité selon les versions de PHP, le changement de version majeure (ici PHP 5 -> PHP 8) implique souvent des incompatibilités. C'est déjà étonnant qu'un script si peu récent puisse fonctionner sur PHP 7.4.
Il est vrai aussi que PHP a tendance à devenir de plus en plus strict au fur de son évolution, ce qui peut effectivement rendre le langage moins accessible, mais ça à aussi l'avantage d'éviter, comme dans ton cas, d'avoir des erreurs dans son code sans s'en rendre compte.
0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour,


Je vous remercie beaucoup ça marche :) effectivement mes logs php7 sont truffés de warning.Ça marche avec php8 mais j'ai encore un petit problème, les messages sont écrits les un a la suite des autres sur la meme ligne, il y a pas de retour a la ligne.

 | Bonjour       | Bonjour toi ça va ?



Pourtant ligne 94 on a bien le "\n" qui (si je ne me trompe pas) sert a faire le retour a la ligne.

$out = $chattext . $n . $spaces . "| " . $msg . "\n";



Ça doit etre un petit détail, en tout cas merci :)
0
Pitet Messages postés 2826 Date d'inscription   Statut Membre Dernière intervention   527
 
A priori tu ne t'es pas trompé, le "\n" devrait bien ajouter un saut de ligne à la fin de la variable $out.

Est-ce que les sauts de ligne s'affichent correctement dans le fichier texte ?
Si les sauts de ligne s'affichent bien dans le fichier texte mais pas dans la page HTML, il faudra surement utiliser la fonction PHP nl2br pour remplacer les sauts de ligne "\n" par des balises <br> lors de l'affichage en HTML.
https://www.php.net/manual/fr/function.nl2br.php
0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Non les sauts de lignes ne sont pas respectés non plus dans le fichier texte, le contenu du fichier apparait sur la meme ligne.Dois-je quand meme m'orienter vers nl2br ?
0
jordane45 Messages postés 38486 Date d'inscription   Statut Modérateur Dernière intervention   4 752
 
Bonjour
Pour les sauts de ligne ça dépend surtout de quel éditeur tu utilises.
Essaie de remplacer les \n Par des \r\n
0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour,

J'utilise gedit et des fois mousepad comme éditeurs de texte.Je viens d'essayer \r\n apparemment ça change pas le problème, le contenu du fichier chat.txt apparait toujours sur la meme ligne et donc idem sur la page du tchat.
0
Pitet Messages postés 2826 Date d'inscription   Statut Membre Dernière intervention   527
 
J'ai l'impression que ton script ajoute bien un saut de ligne à la fin du dernier message mais ne conserve pas les sauts de ligne entre les messages.
Il faudrait déboguer le script pour vérifier : par exemple en ajoutant des var_dump/print_r/echo pour voir le type et le contenu des variables pendant l'exécution.

Peux tu partager ta dernière version du fichier w.php (avec la balise de code stp) ?
0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Oui bien sur, voici la dernière version du code avec les modifications dont on a parlé


<?php
    /**
     * Author: chris at linuxuser.at
     * Licence: MIT
     */
    $fn = "chat.txt";
    $maxlines = 1000;

    $nick_maxlength = 10;

    /* Set this to a minimum wait time between posts (in sec) */
    $waittime_sec = 0;

    /* spam keywords */
    $spam[] = "cum";
    $spam[] = "dick";
    $spam[] = "EAT coon";

    /* IP's to block */
    $blockip[] = "72.60.167.89";

    /* spam, if message IS exactly that string */
    $espam[] = "ajax";

    $msg = $_REQUEST["m"];
    $n = $_REQUEST["n"];
 

    if ($waittime_sec > 0) {
        $lastvisit = $_COOKIE["lachatlv"];
        setcookie("lachatlv", time());

        if ($lastvisit != "") {
            $diff = time() - $lastvisit;
            if ($diff < $waittime_sec) { die(); }
        }
    }

    if ($msg != "") {
        if (strlen($msg) < 2) { die(); }
        if (strlen($msg) > 3) {
            /* Smilies are ok */
            if (strtoupper($msg) == $msg) { die(); }
        }
        if (strlen($msg) > 150) { die(); }
        if (strlen($msg) > 15) {
            if (substr_count($msg, substr($msg, 6, 8)) > 1) { die(); }
        }

        foreach ($blockip as $a) {
            if ($_SERVER["REMOTE_ADDR"] == $a) { die(); }
        }

        $mystring = strtoupper($msg);
        foreach ($spam as $a) {
             if (strpos($mystring, strtoupper($a)) === false) {
                 /* Everything Ok Here */
             } else {
                 die();
             }
        }

        foreach ($espam as $a) {
            if (strtoupper($msg) == strtoupper($a)) { die(); }
        }

        $handle = fopen ($fn, 'r');
        $chattext = '';
       if (is_readable($fn)) {
    $chattext = file_get_contents($fn);
}

        $arr1 = explode("\n", $chattext);

        if (count($arr1) > $maxlines) {
            /* Pruning */
            $arr1 = array_reverse($arr1);
            for ($i=0; $i<$maxlines; $i++) { $arr2[$i] = $arr1[$i]; }
            $arr2 = array_reverse($arr2);
        } else {
            $arr2 = $arr1;
        }

        $chattext = implode("\n", $arr2);


        // Last spam filter: die if message has already been in the chat history
        if (substr_count($chattext, $msg) > 2) { die(); }

        $spaces = "";
        if (strlen($n) > $nick_maxlength-1) $n = substr($n, 0, $nick_maxlength-1);
        for ($i=0; $i<($nick_maxlength - strlen($n)); $i++) $spaces .= " ";

        $out = $chattext . $n . $spaces . "| " . $msg . "\n";
        $out = str_replace("\'", "'", $out);
        $out = str_replace("\\\"", "\"", $out);
        $handle = fopen ($fn, 'w'); fwrite($handle, trim($out)); fclose($handle);
        $input = fopen($file, 'r');
  }      
?>
0
Pitet Messages postés 2826 Date d'inscription   Statut Membre Dernière intervention   527
 
La fonction trim supprime les espaces mais aussi les sauts de ligne au début et à la fin de la chaine.

Remplace les dernières lignes par ceci :
        $out = $chattext . $n . $spaces . "| " . $msg;
        $out = str_replace("\'", "'", $out);
        $out = str_replace("\\\"", "\"", $out);
        
        file_put_contents($fn, trim($out) . "\n");


Si tu voulais appliquer la fonction trim uniquement sur le message, tu peux faire comme ceci :
        $out = $chattext . $n . $spaces . "| " . trim($msg) . "\n";
        $out = str_replace("\'", "'", $out);
        $out = str_replace("\\\"", "\"", $out);
        
        file_put_contents($fn, $out);
0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
J'ai accidentellement passer le sujet en résolu...

Merci je teste ça des que je rentre
0
Integreur Messages postés 86 Date d'inscription   Statut Membre Dernière intervention  
 
Re bonjour,


Merci ça marche super :) je te remercie de ta patience.Je souhaite rajouter des smileys et d'autres trucs sympas a mon petit tchat privé, aurais tu des liens de tutoriels ou autre concernant la mise en place d'une shoutbox ?


Merci encore ton aide, ce sujet est résolu.
0