alojahey
Goto Top

PHP-Script läuft in Dauerschleife

Hallo ,
ich habe einen Android KSWebServer mit Apache,also nicht den gewohnten Umfang. lag zB ist nicht verfügbar.
Ich bin gerade krankgeschrieben und habe aus Langeweile versucht mir eine kleine Webanwendung zu schreiben.
Dort soll anhand von Div-Boxen die Tagesaufteilung eines Mitarbeiters angezeigt werden.
Also zB 01.05.24 fängt er um 7:15 im Büro an, fährt dann 15 Minuten zum Kunden, dort ist er 2:30, dann fährt er 30 Minuten zum nächsten Kunden. Dort dann 30 Minuten Pause. Dann 3 h beim Kunden und 45 Minuten Rückfahrt.
Im Büro dann nochmal 15 Minuten und um 15 Uhr dann Feierabend. In der Kopfzeile dann die Kalkulierten Tage des Monats, linke Seite dann die Mindeststartzeit und der Späteste Feierabend des Monats.
Pro 15 Minuten 20 px Höhe. 1 h also 80 px.

Die DB hat zwei Tabellen. Einmal Stati (id, statiname, farbe) und Tätigkeiten (id,time, stati_id ,mitarbeiter_id).
Nun sollen Tagesdiffs erzeugt werden mit den Tätigsblöcken.Der Anfang ist jedesmal die Differenz zwischen dem Monatsminimum des Mitarbeiters und dem Tagesminumum. GGfs kommt da ein Blankoblock hin. Also der Meier fängt normalerweise um 8:00 an und hört um 17 Uhr auf. Nun fängt er am 03.05.24 ausnahmsweise um 06:00 Uhr an, an den anderen Tagen jeweils um 8:00. Also muss dann an den restlichen Tagen ein Blankodiv von 2 h, also 8 x 15 Minuten x 20 px davorgeneriert werden.
Freie Tage müssen ebenfalls abgefangen werden.

Ich gehe also hin ermittle das Monatsminimum und die Anzahl Tätigkeiten packe ich in ein Array. Also
$anzahl_taetlichkeiten[$x] . So bekomme ich, zB 01.05.24 -> 4, 02.05.24 -> 5, 03.05.24 -> 0, 04.05.24 -> 8, 05.05.24 -> 3. Wenn der Array-Wert !=0 ist, sollen halt TagesDivs erzeugt werden.

Und da rennt sich das Skript tod.
Das Array:

$anzahldatumboxen=$number+1;
FOR($z=1;$z<$number;$z++){
$sql_anzahl_taetigkeiten=sprintf("select count(time) from taetigkeiten where date_format(time, '%%d')=%s and date_format(time, '%%m')=%s and date_format(time,'%%Y')=%s and mitarbeiter_id=%s order by time asc",  
mysqli_real_escape_string($db_link,$z),
mysqli_real_escape_string($db_link,$selmonth),
mysqli_real_escape_string($db_link,$selyear),
mysqli_real_escape_string($db_link,$mitarbeiter_id));
//echo $sql_anzahl_taetigkeiten;
$mysqlresult_taetigkeiten=mysqli_query($db_link,$sql_anzahl_taetigkeiten);
while($ausgabe_anzahl_taetigkeiten=mysqli_fetch_row($mysqlresult_taetigkeiten)){
$anzahl_taetigkeiten[]=$ausgabe_anzahl_taetigkeiten[0];
}}

Die Monats Min- und Maxwerte:

$sql_minmonatsstartzeit=sprintf("SELECT date_format(min(time),'%%H:%%i') as minmonatsstart,date_format(max(time),'%%H:%%i') as maxmonatsende FROM taetigkeiten   
where date_format(time, '%%m')=%s and mitarbeiter_id=1 and date_format(time,'%%Y')=%s",  
mysqli_real_escape_string($db_link,$selmonth),
mysqli_real_escape_string($db_link,$selyear));

//echo "pups".$sql_minmonatsstartzeit;  
$mysqlresult=mysqli_query($db_link,$sql_minmonatsstartzeit);
$minmaaxzeitenmonat=mysqli_fetch_row($mysqlresult);
$minmonatsstartzeit=$minmaaxzeitenmonat['0'];  
$maxmonatsende=$minmaaxzeitenmonat['1'];  


Die Min- und Maxwerte pro Tag:

for ($x=1;$x<=$number;$x++)
{
//echo "peng-------".$x."<br>";}  
$sql_mintagesstartzeit=sprintf("SELECT date_format(min(time),'%%H:%%i') as mintagesstart,date_format(max(time),'%%H:%%i') as maxtagesende FROM taetigkeiten   
where date_format(time, '%%d')=%s and date_format(time, '%%m')=%s and date_format(time,'%%Y')=%s and mitarbeiter_id=%s",  
mysqli_real_escape_string($db_link,$x),
mysqli_real_escape_string($db_link,$selmonth),
mysqli_real_escape_string($db_link,$selyear),
mysqli_real_escape_string($db_link,$mitarbeiter_id));


//echo "<br><br>pups".$sql_mintagesstartzeit;  
$mysqlresult_tag=mysqli_query($db_link,$sql_mintagesstartzeit);
//echo mysqli_num_rows($mysqlresult_tag);

$minmaxzeitentag=mysqli_fetch_row($mysqlresult_tag);
$mintagesstartzeit=$minmaxzeitentag['0'];  

Und zum Schluss der Problemcode. Ich gehe halt hin frage einmal den Datensatz ab und via Hilfstabelle den vorherigen. Die Differenz ist dann die Dauer.

$sql_tagesdiv=sprintf("select t.*, stati.statiname,stati.farbe, timeSTAMPdiff(minute,(select time from taetigkeiten t1 where date_format(time,'%%d')=%s and date_format(time,'%%m')=%s  and date_format(time,'%%Y')=%s AND t1.mitarbeiter_id = t.mitarbeiter_id and t1.id < t.id order by t1.id desc limit 1), time)  diff from taetigkeiten t,stati where date_format(time,'%%d')=%s and date_format(time,'%%m')=%s  and date_format(time,'%%Y')=%s and mitarbeiter_id=%s and stati_id=stati.id",  
mysqli_real_escape_string($db_link,$x),
mysqli_real_escape_string($db_link,$selmonth),
mysqli_real_escape_string($db_link,$selyear),
mysqli_real_escape_string($db_link,$x),
mysqli_real_escape_string($db_link,$selmonth),
mysqli_real_escape_string($db_link,$selyear),
mysqli_real_escape_string($db_link,$mitarbeiter_id));
$mysqlresult_tag=mysqli_query($db_link,$sql_tagesdiv);
echo $sql_tagesdiv;
//echo $x." - -".$number."<br><br>";  
}
$taeglichesminimum=strtotime($mintagesstartzeit);
$monatlichesminimum=strtotime($minmonatsstartzeit);

$blankoblock=($monatlichesminimum-$taeglichesminimum)/60;
$blankoblockhoehe=($blankoblock/15)*20;
//echo "<br><br>Blanko".$minmonatsstartzeit;  
echo '<div class="tagesdiv">';  
if($blankoblockhoehe!=0)
echo '<div class="divblanko" style ="height:'.$blankoblockhoehe.'px;">blanko</div>';   
else
echo '<div class="divblankoblind">blanko</div>';   


while($ausgabe_tagesdiv=mysqli_fetch_assoc($mysqlresult_tag))
{
//echo $ausgabe_tagesdiv['uhrzeit']." - ".$ausgabe_tagesdiv['datum']." - ".$ausgabe_tagesdiv['mitarbeiter_id']." - ";  


$hoehe=$ausgabe_tagesdiv['diff']*20;  

$mysqlresult_tag=mysqli_query($db_link,$sql_tagesdiv);
if($mintagesstartzeit!="")  
$unterschiedanfangszeit =(strtotime($mintagesstartzeit)-strtotime($minmonatsstartzeit))/60 ;

//echo "<br>Peep".$mintagesstartzeit." -  ".$minmonatsstartzeit;  
$ms_tagesdiv=mysqli_query($db_link,$sql_tagesdiv);
echo '<div class="div'.mb_strtolower($ausgabe_tagesdiv['statiname']).'" style="height:'.$hoehe.'px;">'.$ausgabe_tagesdiv['statiname'].'<br>'.$hoehe.'</div>';  
}

   /*<div style ="width:68px;border:1px solid green;vertical-align: middle; text-align: center;height:42px;">Kunde</div>*/ 

}

echo "</div>";  

Die Kopfleiste habe ich mal weggelassen genau wie das css, kann aber natürlich nachgereicht werden. Komischerweise funktionieren die Abfragen in Einzeldateien. Klar Subquerys sind nicht schön undbelasten den Server. Aber bei max 31 Tagen sind es 31 Blöcke und das ist doch vertretbar.
Vielen Dank für Anregungen.
Alojahey

Content-ID: 668434

Url: https://administrator.de/contentid/668434

Ausgedruckt am: 21.11.2024 um 11:11 Uhr

Xaero1982
Lösung Xaero1982 27.09.2024 um 17:34:25 Uhr
Goto Top
Moin,

keine Ahnung, ob das passt:

Quelle: ChatGPT

Ja, ich kann deinen PHP-Code analysieren und korrigieren. Hier sind einige allgemeine Verbesserungen und Korrekturen, die ich vorgenommen habe:

### Verbesserungen:
1. SQL-Injection-Vermeidung: Es wird `mysqli_real_escape_string` verwendet, was gut ist, aber moderne Methoden wie vorbereitete Statements (`prepared statements`) wären sicherer.
2. Redundantes SQL-Abfragen: Es gibt eine unnötige Wiederholung von `mysqli_query($db_link, $sql_tagesdiv)` innerhalb der Schleife, was ineffizient ist.
3. Fehlerbehandlung für SQL-Abfragen: Es fehlen Überprüfungen, ob die SQL-Abfragen erfolgreich waren.
4. Datums-/Zeitvergleiche: Es könnte effizienter sein, Datums-/Zeitvergleiche direkt in SQL anstatt in PHP zu machen, aber ich werde den Code so lassen, wie er ist.
5. HTML-Struktur: Es gibt keine vollständige HTML-Struktur in deinem Beispiel. Es wäre ratsam, einen sauberen HTML-Wrapper zu erstellen.

Hier ist die korrigierte Version deines Codes:

### Korrigierter Code:


$sql_tagesdiv = sprintf(
    "SELECT t.*, stati.statiname, stati.farbe,   
    TIMESTAMPDIFF(MINUTE, 
        (SELECT time FROM taetigkeiten t1 
         WHERE DATE_FORMAT(time,'%%d') = %s   
         AND DATE_FORMAT(time,'%%m') = %s   
         AND DATE_FORMAT(time,'%%Y') = %s   
         AND t1.mitarbeiter_id = t.mitarbeiter_id 
         AND t1.id < t.id 
         ORDER BY t1.id DESC LIMIT 1),
    time) AS diff 
    FROM taetigkeiten t, stati 
    WHERE DATE_FORMAT(time,'%%d') = %s   
    AND DATE_FORMAT(time,'%%m') = %s   
    AND DATE_FORMAT(time,'%%Y') = %s   
    AND mitarbeiter_id = %s 
    AND stati_id = stati.id",  
    mysqli_real_escape_string($db_link, $x),
    mysqli_real_escape_string($db_link, $selmonth),
    mysqli_real_escape_string($db_link, $selyear),
    mysqli_real_escape_string($db_link, $x),
    mysqli_real_escape_string($db_link, $selmonth),
    mysqli_real_escape_string($db_link, $selyear),
    mysqli_real_escape_string($db_link, $mitarbeiter_id)
);

$mysqlresult_tag = mysqli_query($db_link, $sql_tagesdiv);

if (!$mysqlresult_tag) {
    echo "Fehler bei der SQL-Abfrage: " . mysqli_error($db_link);  
    exit;
}

echo '<div class="tagesdiv">';  

$taeglichesminimum = strtotime($mintagesstartzeit);
$monatlichesminimum = strtotime($minmonatsstartzeit);

$blankoblock = ($monatlichesminimum - $taeglichesminimum) / 60;
$blankoblockhoehe = ($blankoblock / 15) * 20;

if ($blankoblockhoehe != 0) {
    echo '<div class="divblanko" style="height:' . $blankoblockhoehe . 'px;">blanko</div>';  
} else {
    echo '<div class="divblankoblind">blanko</div>';  
}

while ($ausgabe_tagesdiv = mysqli_fetch_assoc($mysqlresult_tag)) {
    $hoehe = $ausgabe_tagesdiv['diff'] * 20;  

    if ($mintagesstartzeit != "") {  
        $unterschiedanfangszeit = (strtotime($mintagesstartzeit) - strtotime($minmonatsstartzeit)) / 60;
    }

    echo '<div class="div' . mb_strtolower($ausgabe_tagesdiv['statiname']) . '" style="height:' . $hoehe . 'px;">';  
    echo $ausgabe_tagesdiv['statiname'] . '<br>' . $hoehe . '</div>';  
}

echo "</div>";  

### Änderungen im Detail:

1. Doppelte SQL-Abfrage: Ich habe das überflüssige `mysqli_query($db_link, $sql_tagesdiv)` innerhalb der Schleife entfernt, da du das SQL-Ergebnis bereits außerhalb der Schleife abfragst.
2. Fehlerüberprüfung: Ich habe eine Fehlerüberprüfung für die SQL-Abfrage hinzugefügt, damit du benachrichtigt wirst, wenn etwas schiefgeht.
3. Klarere HTML-Struktur: Die `div`-Elemente sind jetzt klarer strukturiert und formatiert.
4. Sicherheitsbedenken: Obwohl `mysqli_real_escape_string` verwendet wird, solltest du in Betracht ziehen, auf vorbereitete SQL-Statements (`prepared statements`) umzusteigen, um die Sicherheit zu verbessern.


Musste testen face-smile Sagt ChatGPT
Alojahey
Alojahey 30.09.2024 um 11:19:29 Uhr
Goto Top
vielen Dank. kleine Fehler waren noch drin.. Aber jetzt macht es das was es soll. Nun geht es an die Schönheit.
Ein 15 Min Block sind halt 20 px Höhe. Eine Stunde 80 px usw.
Links sdie Zeitleiste läuft in 15 minuten Blöcken. Start bei 07:30 Eine Stunde Büro müsste dann genau bei 08:30 abschließen => 80 px. Tut es aber nicht. Sind immer ein paar Pixel Versatz drin. Dachte es liegt an border, und habe es durch outline ersetzt.