Zwischengespeicherte Datenmänge Reduzieren (PHP)

  • PHP

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Matix Media.

    Zwischengespeicherte Datenmänge Reduzieren (PHP)

    Hallo,

    ich frage mich gerade was bei meinem Script in PHP laut der Fehlermeldung der Fehler ist:

    Quellcode

    1. Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) in /var/customers/webs/ni1423026_1/preview/private/Tutum_System/v2/plugins/additional.php on line 38

    PHP-Quellcode

    1. function SplitTime($time) {
    2. $date = getdate(strtotime($time)); //Line 38
    3. return $date;
    4. }


    Vielen Dank im Vorraus!

    Edit:
    auf die Datei wird über ein requiere in ​index.php zugegriffen.
    Grüße, Matix
    Die Fehlermeldung hat (vermutlich) nichts mit der Funktion bzw. der Datei zu tun.

    Dein Script packt so viele Daten in den Arbeitsspeicher, dass es an die Grenze von 128 MB kommt.
    Vermutlich ein oder mehrere große Arrays wo sehr viele Daten drin sind.

    Um das Problem zu beheben, kann man entweder die Scripte optimieren oder das Limit in PHP höher setzen (php.ini, Eintrag memory_limit).
    Wobei je nach Anwendung klar sein sollte, das letzteres keine Dauerlösung ist. Und falls das Script von einer größeren Personengruppe aufgerufen werden kann, sollte aus Sicherheitsgründen das Limit auch nicht sehr viel größer sein.

    Möglich wäre auch ein Memoryleak in PHP oder einer Extension, halte ich aber für unwahrscheinlich.
    Viel Dank,
    ich vversuche gerade ein System zu erstellen was einen bestimmte Uhrzeiten vorschlägt. Dabei Arbeite ich mit SEHR vielen Arrays. Vermutlich ist das der Grund. Ich versuche mal eine Lösung zu finden ohne so viele Arrays.

    Viel Dank

    Edit:

    Wenn ich schon dabei bin, in meinem System geht es darum das eine Start Uhrzeit und eine Ende Uhrzeit gibt, und ein Kurs hat immer eine bestimmte länge vvon 30 min z.B. und dann soll das System alle Uhrzeiten rechnen Die in diesen Zeitraum passen die jeweils eine spanne von halt 30 min. hat. Hat jemand ihrgend einen Ansatz oder sonstieges dafür? Weil ich noch nicht so viel erfahrung mit PHP habe und es bei mir vielleicht nichtmal Klappt...

    Mein bisheriger Code:

    PHP-Quellcode

    1. $start_time;
    2. $end_time;
    3. $lenth;
    4. $sql2 = "SELECT * FROM `events` WHERE `ID` = " . $_POST["event_id"];
    5. $result2 = $conn->query($sql2);
    6. if($result2->num_rows > 0) {
    7. while($row3 = $result2->fetch_assoc()) {
    8. $lenth = $row3["lenth"];
    9. }
    10. }
    11. $row2 = getSettings();
    12. $start_time = $row2["day_start"];
    13. $end_time = $row2["day_end"];
    14. $day = getDay_en($_POST["date"]);
    15. $days = json_decode($row2["days"], true);
    16. if(!in_array($day, $days)) {echo 'Für den ausgewählten Tag, sind keine Buchungen Verfügbar!<br><br><br><br> <a class="button" href="javascript:history.back()">Zurück</a>';} else {
    17. $end_split = SplitTime($end_time);
    18. $lenth_split = SplitTime($lenth);
    19. $lenth_time_mins = $lenth_split["minutes"];
    20. $end_time_split = $end_split["hours"].$end_split["minutes"];
    21. $splittime = "0000";
    22. $times = array();
    23. $last_time = SubtractTime($start_time, $lenth_time_mins);
    24. while($splittime < $end_time_split) {
    25. $last_time_split = SplitTime(AddTime($last_time, $lenth_time_mins));
    26. $splittime = $last_time_split["hours"].$last_time_split["minutes"];
    27. array_push($times, AddTime($lastTime,$lenth_time_mins));
    28. }
    29. foreach ($times as $time) {
    30. echo '<h3>Uhrzeit Auswählen</h3>
    31. <a>Schritt 3 von 4</a><br><br>
    32. <form action="?set_infos" method="post">
    33. <input type="hidden" name="event_id" value="' . $_POST["event_id"] . '">
    34. <input type="hidden" name="date" value="' . $_POST["date"] . '">
    35. <button type="submit" class="book_time" name="time" value="'.$time.'">'.$time.' - '.AddTime($time,$lenth_time_mins).' Uhr</button>
    36. </form>';
    37. }
    38. }


    requiere additional.php

    PHP-Quellcode

    1. function getSettings() {
    2. require './config.php';
    3. $sql = "SELECT * FROM `settings`";
    4. $result = $conn->query($sql);
    5. if ($result->num_rows > 0) {
    6. // output data of each row
    7. while($row = $result->fetch_assoc()) {
    8. return $row;
    9. }
    10. }
    11. }
    12. function console_log( $data ){
    13. echo '<script>';
    14. echo 'console.log('. json_encode( $data ) .')';
    15. echo '</script>';
    16. }
    17. function getNewDate($oldDate) {
    18. $originalDate = $oldDate;
    19. $newDate = date("d-m-Y", strtotime($originalDate));
    20. $newDate = str_replace("-", ".", $newDate);
    21. return $newDate;
    22. }
    23. function AddTime($time, $adding)
    24. {
    25. return $time + ($adding*60);
    26. }
    27. function SubtractTime($time, $subtracting)
    28. {
    29. return $time - ($subtracting*60);
    30. }
    31. function getDay_en($date)
    32. {
    33. $date = getdate(strtotime($date));
    34. return $date["weekday"];
    35. }
    36. function SplitTime($time) {
    37. $date = getdate(strtotime($time));
    38. return $date;
    39. }


    requiere config.php

    PHP-Quellcode

    1. $server = "vweb15.nitrado.net";
    2. $s_username = "ni******_1sql8";
    3. $s_password = "1*************";
    4. $conn = new mysqli($server, $s_username, $s_password, $s_username);
    5. if ($conn->connect_error) {
    6. die("(Connection failed: " . $conn->connect_error . ")");
    7. }
    8. echo "";

    Vielen dank im vorraus!
    Grüße, Matix

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Matix Media“ ()

    Ich bin zwar erst in Zeile 5 deines Scriptes, aber das solltest du dir auf jeden Fall abgewöhnen, selbst wenn Du das nur für dich programmierst:

    PHP-Quellcode

    1. $sql2 = "SELECT * FROM `events` WHERE `ID` = " . $_POST["event_id"];


    GRUNDSÄTZLICH sind Benutzereingaben als fehlerhaft / schädlich anzusehen, bis die Prüfung das Gegenteil bewiesen hat. Dies gilt um so mehr, wenn Du die Eingaben für eine Datenbankabfrage benötigst. Stichwort SQL-Injection.

    Dann eine Frage zu den Uhrzeiten, die vorgeschlagen werden sollen: Welche "Auflösung" benötigts Du denn? 1 Minute, 5 Minuten, 15 Minuten, 30 Minuten, .... ? Und welcher Zeitraum soll gleichzeitig angezeigt werden? 1 Tag, 1 Woche, 1 Monat ... ?
    Bei 1 Minute und 30 Tagen wären das 60 (Minuten pro Stunde) * 24 (Stunden pro Tag) * 30 (Tage) * 8 (Byte pro Zeiteintrag) = 345.600 Byte plus etwas Overhead plus Ausgabetext. Wenn 128MB für die Aufgabe nicht ausreichen, läuft definitiv etwas falsch.
    Zur Suche nach der kritischen Stelle kannst Du nach den verdächtigen Stellen eingeben:

    PHP-Quellcode

    1. echo memory_get_peak_usage(); exit();

    Halt so lange ranarbeiten, bis Du den Speicherfresser ausfindig gemacht hast. Dann kann es ans Optimieren gehen.
    Du kannst dir gerne Ansehen an welcher stelle es hackt. Und ja ich weiß das da etwas schief geht, sobald man die Website betritt kann man das sehen. Guck es dir dochmal an preview.matix-media.de/private/Tutum_System/v2/

    Musst dich erstmal ein bisschen durchklicken, Sprich du musst einen Kurs "Buchen"
    Grüße, Matix
    Generell würde ich ja raten, sich intensiv mit Grundlagen zu beschäftigen und dann den bestehen Code gründlich einem refactoring zu unterziehen.

    Hier aber mal ein kleiner Denkanstoß, für die Frage nach den Zeiten (sofern ich das richtig verstanden habe).

    PHP-Quellcode

    1. $timeRangeBegin = DateTimeImmutable::createFromFormat('Y-m-d\\TH:i:s', '2019-04-24T20:00:00');
    2. $timeRangeEnd = DateTimeImmutable::createFromFormat('Y-m-d\\TH:i:s', '2019-04-24T23:00:00');
    3. $eventDuration = new DateInterval('PT30M');
    4. $increment = new DateInterval('PT5M');
    5. //
    6. $begin = $timeRangeBegin;
    7. $end = $begin->add($eventDuration);
    8. //
    9. while($end <= $timeRangeEnd) {
    10. echo $begin->format('d.m.Y H:i'), ' - ', $end->format('d.m.Y H:i'), "\n";
    11. $begin = $begin->add($increment);
    12. $end = $end->add($increment);
    13. }
    Krass, ich beschäftige mich tazechlich viel zu wenig mit den Grundlagen. Das liegt daran das ich mir nur dass aneigne was ich gerade brauche und darauf Stoße ich auf viele Probleme.

    Vielen Dank! Ich würde sagen das mir das wirklich geholfen hat!

    Edit:

    Sorry, ich bins nochmal, ich habe jetzt relativ lange einen Fehler zu beheben aber ich check einfach nicht was daran falsch ist....

    Fehler:

    Quellcode

    1. Fatal error: Can't use function return value in write context in /var/customers/webs/ni1423026_1/preview/private/Tutum_System/v2/index.php on line 48


    Line 44-52

    PHP-Quellcode

    1. if(!in_array($day, $days)) {echo 'Für den ausgewählten Tag, sind keine Buchungen Verfügbar!<br><br><br><br> <a class="button" href="javascript:history.back()">Zurück</a>';} else {
    2. $today = date("y-m-d");
    3. $timeRangeBegin = DateTimeImmutable::createFromFormat('Y-m-d\\TH:i:s', $today.'T'.$start_time);
    4. $timeRangeEnd = DateTimeImmutable::createFromFormat('Y-m-d\\TH:i:s', $today.'T'.$end_time);
    5. $list ($ev_hours, $ev_min, $ev_sec) = split(':', $lenth); //line 48
    6. $ev_min = $ev_hours * 60 + $ev_min;
    7. $eventDuration = new DateInterval('PT'.$ev_min.'M');
    8. $increment = new DateInterval('PT5M');
    9. //



    Edit: Und nochwas... Ich habe jetzt mal Zeile 48 und 49 Rausgenommen, gab kein Fehler mehr, bis ich zu der stelle gekommen bin, dann wurde mir gesagt, dass die Klasse DateTimeImmutable nicht gefunden werden konnte...

    Ich brauche Hilfe ;( ^^

    Grüße, Matix

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Matix Media“ ()