[RESOLU] probleme avec plusieurs conditions

Eléphant du PHP | 345 Messages

09 févr. 2022, 19:25

Bonjour,
ce script fonctionne.
$sql = "SELECT * FROM calendrier" ;
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
$resultat = $pdostat->fetch();
$saison = $resultat['saison'];
$jour = $resultat['jour'];
$meteo = $resultat['meteo'];
$heure = date("H:i");
if(($jour < 75) AND ($heure < 09.00 OR $heure > 17.00)) {
$sql ="UPDATE calendrier SET meteo= '/images/neige_nuit.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
else {
$sql ="UPDATE calendrier SET meteo= '/images/neige.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
mais quand je rajoute ceci à la suite:
if(($jour > 76 OR $jour < 150) AND ($heure < 08.00 OR $heure > 19.12)) { 
$sql = "UPDATE calendrier SET meteo = '/images/nuage_nuit.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
else {
$sql = "UPDATE calendrier SET meteo = '/images/soleil_nuage.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
le premier bloc conditionnel ne marche plus.

btzolive
Invité n'ayant pas de compte PHPfrance

11 févr. 2022, 10:33

Bonjour,

Ta première condition ($jour > 76 OR $jour < 150) est toujours vrai. C'est peut-être l'origine de ton problème.

Tous les jours >76 => de 77 à l'infini
Tous les jours < 150 => de -l'infini à 149

Le réunion des deux ensemble (OR) te donne de - l'infini à + l'infini, donc ta condition est toujours vrai.

Eléphant du PHP | 345 Messages

11 févr. 2022, 11:33

OUi, cela semble en effet logique. Mais en mettant ceci, ca devrait fonctionner? (en table $jour est à 6)
if(($jour < 75) && ($heure < 09.00 OR $heure > 17.00)) {
$sql ="UPDATE calendrier SET meteo= '/images/neige_nuit.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
else {
$sql ="UPDATE calendrier SET meteo= '/images/neige.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
if(($jour > 75) && ($heure < 08.00 OR $heure > 19.12)) { 
$sql = "UPDATE calendrier SET meteo = '/images/nuage_nuit.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
else {
$sql = "UPDATE calendrier SET meteo = '/images/soleil_nuage.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}


Mammouth du PHP | 2703 Messages

11 févr. 2022, 15:20

que renvoie ce code
date("H:i")
?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

12 févr. 2022, 12:17

Je n'ai jamais croisé ce genre de notation "19.12" pour une heure donc à vérifier si le problème ne viendrait pas de là...
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 345 Messages

12 févr. 2022, 18:37

@ Or 1, rien. Sauf si je mets $date(H:i) qui me renvoie l'heure courante comme $heure = date("H:i"); (présent dans le script)
@@arthur, en mettant 19.00 ça ne va pas mieux :(

Mammouth du PHP | 2703 Messages

12 févr. 2022, 19:42

@ Or 1, rien.
si si, ce code retourne une chaine de caractère avec un ":" entre l'heure et les minutes. comparer une chaine avec un nombre est une bonne idée pour avoir un comportement imprévu.

Eléphant du PHP | 345 Messages

13 févr. 2022, 03:17

Je ne comprends rien si ce n'est que
if(($jour < 75) && ($heure < 09.00 OR $heure > 17.00)) { .
ne serait pas très propre?
(comparer une chaine avec un nombre est une bonne idée pour avoir un comportement imprévu.)

ynx
Mammouth du PHP | 586 Messages

13 févr. 2022, 12:05

Bonjour,

En effet le problème vient bien des comparaisons entre chaine de caractère et nombre, tel que if ($heure < 19.12).

Puisque la variable $heure contient l'heure et les minutes séparés par deux points, cette condition revient à écrire if ("19:30" < 19.12) si il est 19h30.
Puisque les types des deux variables à comparer sont différentes (string et float), PHP est obligé de convertir la chaine de caractère en nombre afin de pouvoir effectuer la comparaison.

Le ":" dans la chaine "19:30" n'est pas un caractère numérique, ce caractère et les suivants sont donc ignorés lors de la conversion en nombre.
La chaine "19:30" est alors convertie en nombre 19, la comparaison finale revient donc à écrire if (19 < 19.12), ce qui n'est pas le résultat attendu.

Plus d'infos :
https://www.php.net/manual/fr/language. ... ggling.php
https://www.php.net/manual/fr/language. ... ison.types


Une première solution basique serait de récupérer les heures et minutes dans deux variables distinctes pour effectuer les comparaisons, mais ceci peuvent vite devenir complexe.
Je t'invite à tester cet exemple pour t'en rendre compte, tu peux décommenter les lignes 4 et 5 pour écraser la valeur des variables $heure et $minute pour tester :
$heure = date('h');
$minute = date('i');

// $heure = 20;
// $minute = 10;

// si $heure = 20 et $minute = 10, la condition 1 est fausse
if ($heure < 8 || ($heure >= 19 && $minute > 12)) {
    echo 'confition 1 vraie';
} else {
    echo 'confition 1 fausse';
}

if ($heure < 8 || ($heure >= 19 && $minute > 12) || $heure >= 20) {
    echo 'confition 2 vraie';
} else {
    echo 'confition 2 fausse';
}
Selon les comparaisons à faire, une solution peut-être plus simple et plus propre serait d'utiliser les fonctions PHP dédiées aux dates, tel que l'objet DateTime.

Eléphant du PHP | 345 Messages

14 févr. 2022, 19:06

Merci ynx pour ces explications. Cela reste quand même brouillon dans ma tête et pas très clean.
Je ne pense pas utiliser dateTime car mon calendrier est particulier: 360 jours "découpés" en 4, loin du format D M Y !
J'ai donc revu mon code en utilisant mktime pour un rendu plus propre.
$sql = "SELECT * FROM calendrier" ;
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
$resultat = $pdostat->fetch();
$saison = $resultat['saison'];
$jour = $resultat['jour'];
$meteo = $resultat['meteo'];
$heure = date("H:i");
if($jour  <  75) {
$hts = mktime(date("H"),date("i"),0,date("m"), date("d"), date("Y"));
$debut = mktime(17, 00, 0, date("m"), date("d"), date("Y"));
$fin = mktime(10, 00, 0, date("m"), date("d"), date("Y"));
}
/* Si l'heure courante est supérieure à l'heure  OU inférieure à l'heure */
if($hts > $debut || $hts < $fin)
{
$sql ="UPDATE calendrier SET meteo= '/images/neige_nuit.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
else {
	$sql ="UPDATE calendrier SET meteo= '/images/neige.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
if($jour > 76 || $jour < 150) {
$hts = mktime(date("H"),date("i"),0,date("m"), date("d"), date("Y"));
$debut = mktime(21, 00, 0, date("m"), date("d"), date("Y"));
$fin = mktime(07, 00, 0, date("m"), date("d"), date("Y"));
}
/* Si l'heure courante est supérieure à l'heure  OU inférieure à l'heure */
if($hts > $debut || $hts < $fin)
{
$sql = "UPDATE calendrier SET meteo = '/images/nuage_nuit.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
else {
$sql = "UPDATE calendrier SET meteo = '/images/soleil_nuage.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
J'en suis toujours au meme stade: la 1ere condition fonctionne seulement si je la mets seule. Le bout de script tel que présenté va afficher la seconde condition !

Mammouth du PHP | 2703 Messages

14 févr. 2022, 19:12

comparer une chaine avec une chaine, cela fonctionne bien, par exemple :
$heure > "19:12"

Eléphant du PHP | 345 Messages

14 févr. 2022, 19:26

Merci Or, je pense que cette fois j'arrive à mes fins!
.....
if($jour < 76) {
if($heure > "17:00" || $heure < "09:00") {
$sql ="UPDATE calendrier SET meteo= '/images/neige_nuit.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
else {
	$sql ="UPDATE calendrier SET meteo= '/images/neige.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
if($jour > 75 && $jour < 150) {
if($heure > "21:00" || $heure < "07:00") {
$sql = "UPDATE calendrier SET meteo = '/images/nuage_nuit.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
else {
$sql = "UPDATE calendrier SET meteo = '/images/soleil_nuage.gif'";	
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
}
}
}
?>