PHP While-Schleife läuft nur einmal durch

chickenburner

Cadet 1st Year
Registriert
Feb. 2020
Beiträge
11
Hallo,

Meine While-Schleife läuft nur einmal durch. Es werden alle Aufgaben in der While-Schleife erfolgreich erledigt, allerdings immer nur beim ersten Datensatz mit Status 1. Woran liegt das?


PHP:
<?php

include "Config.php";

require_once 'api2pdf/Api2Pdf.php';
require_once 'api2pdf/ApiResult.php';


use Api2Pdf\Api2Pdf;


    $Status = "1";
    $NewStatus = "2";

    $mysqli4 = new mysqli(Config::getHost(), Config::getUsername(), Config::getPassword(), Config::getDatabase());

    $stmt = $mysqli4->prepare("SELECT * FROM Files WHERE Status = ? ");
   
    $stmt->bind_param('s', $Status);
   
    $stmt->execute();
   
    $result = $stmt->get_result();
   
    $i = 0;

     while ($all = $result->fetch_object())
       
     {  
            $ID = $all->ID;
           
            $Customer = $all->Customer;


            $apiClient = new Api2Pdf('');

            $apiClient->setInline(true);
            $apiClient->setFilename('test.pdf');
            $apiClient->setOptions(
                [
                    'orientation' => 'landscape',
                    'pageHeight'=> 303,
                    'pageWidth'=> 216,

                ]
            );

            $result = $apiClient->wkHtmlToPdfFromHtml('');

            $mbOut = $result->getMbOut();

            if($mbOut > 0) {

                $bname = $ID;

                $url = $result->getPdf();
               
                $img = "datas/" .$bname."_data.pdf";
               
                file_put_contents($img, file_get_contents($url));


                    $conn = new mysqli(Config::getHost(), Config::getUsername(), Config::getPassword(), Config::getDatabase());

                    $stmt = $conn->prepare("UPDATE Files SET status = ?, printfile = ?  WHERE id = ?");

                    $stmt->bind_param("sss", $NewStatus, $img, $ID);

                    $stmt->execute(); // Daten in Datenbanken senden

                    mysqli_close($conn);


                    $user = $_SESSION["email"];

                    $conn4 = new mysqli(Config::getHost(), Config::getUsername(), Config::getPassword(), Config::getDatabase());

                    $stmt4 = $conn4->prepare("SELECT * FROM Kunden WHERE mail = ?");

                    $stmt4->bind_param("s", $user);

                    $stmt4->execute(); // Daten in Datenbanken senden

                    $result = $stmt4->get_result();

                    $userid = $result->fetch_object();

                    $mail = $userid->mail;

                    $name = $userid->name;

                    mysqli_close($conn4);



            $empfaenger = $mail;
            $betreff = "Betreff";
            $from = "From: Movao <order@url.de>\r\n";
            $from .= "Reply-To: order@url.de; charset=utf-8\r\n";
            $from .= "Content-Type: text/html\r\n";
            $text = "TEXT";
            $text = utf8_decode($text);

            mail($empfaenger, $betreff, $text, $from);

   
}
       
          $i++;
       
         }

Vielen Dank im Voraus :)
 
In Zeile 48 (später noch einmal) weist Du der Variable $result einen neuen Wert zu. Du verwirfst damit alles außer der schon gelesenen ersten Zeile ...
 
  • Gefällt mir
Reaktionen: Drexel, WodkaGin und abcddcba
Super, daran lag es. :) Jetzt geht das Script.

Noch eine Verständnis-Frage. Ich möchte das Script als Cronjob ausführen. Wenn ich den Cronjob auf alle 30 Minuten stelle. Wird es zu Problemen führen, wenn das Script mal länger als eine halbe Stunde braucht? Sprich der Cronjob führt das Script um 14:00 Uhr aus. Um 14:30 ist das Script erst bei der Hälfte der Verarbeitung und jetzt startet der Cronjob das Script erneut. Läuft das Script dann doppelt und behindert sich gegenseitig?

Vielen Dank für Eure Hilfe :)
 
Zuletzt bearbeitet:
Das könnte passieren, ja. Du könntest aber z. B. einfach beim Cron-Start ein temporäres Lock-File schreiben und am Ende wieder löschen. Und ganz zu Beginn des Scriptes prüfst du, ob das Lock-File existiert. Wenn ja, machst du gar nichts, weil der alte Cronjob noch läuft. Wenn nicht, dann führst du ganz normal den Cronjob aus.

Also z. B. so:

PHP:
<?php

include "Config.php";

require_once 'api2pdf/Api2Pdf.php';
require_once 'api2pdf/ApiResult.php';


use Api2Pdf\Api2Pdf;


    // Lock-File prüfen
    if (file_exists('/tmp/cronjob_lock')) {
        exit;
    }

    // Lock-File schreiben
    file_put_contents('/tmp/cronjob_lock', time());

    $Status = "1";
    $NewStatus = "2";

    $mysqli4 = new mysqli(Config::getHost(), Config::getUsername(), Config::getPassword(), Config::getDatabase());

    $stmt = $mysqli4->prepare("SELECT * FROM Files WHERE Status = ? ");
  
    $stmt->bind_param('s', $Status);
  
    $stmt->execute();
  
    $result = $stmt->get_result();
  
    $i = 0;

    while ($all = $result->fetch_object())
      
    { 
        $ID = $all->ID;
      
        $Customer = $all->Customer;


        $apiClient = new Api2Pdf('');

        $apiClient->setInline(true);
        $apiClient->setFilename('test.pdf');
        $apiClient->setOptions(
            [
                'orientation' => 'landscape',
                'pageHeight'=> 303,
                'pageWidth'=> 216,

            ]
        );

        $result = $apiClient->wkHtmlToPdfFromHtml('');

        $mbOut = $result->getMbOut();

        if($mbOut > 0) {

            $bname = $ID;

            $url = $result->getPdf();
          
            $img = "datas/" .$bname."_data.pdf";
          
            file_put_contents($img, file_get_contents($url));


                $conn = new mysqli(Config::getHost(), Config::getUsername(), Config::getPassword(), Config::getDatabase());

                $stmt = $conn->prepare("UPDATE Files SET status = ?, printfile = ?  WHERE id = ?");

                $stmt->bind_param("sss", $NewStatus, $img, $ID);

                $stmt->execute(); // Daten in Datenbanken senden

                mysqli_close($conn);


                $user = $_SESSION["email"];

                $conn4 = new mysqli(Config::getHost(), Config::getUsername(), Config::getPassword(), Config::getDatabase());

                $stmt4 = $conn4->prepare("SELECT * FROM Kunden WHERE mail = ?");

                $stmt4->bind_param("s", $user);

                $stmt4->execute(); // Daten in Datenbanken senden

                $result = $stmt4->get_result();

                $userid = $result->fetch_object();

                $mail = $userid->mail;

                $name = $userid->name;

                mysqli_close($conn4);



            $empfaenger = $mail;
            $betreff = "Betreff";
            $from = "From: Movao <order@url.de>\r\n";
            $from .= "Reply-To: order@url.de; charset=utf-8\r\n";
            $from .= "Content-Type: text/html\r\n";
            $text = "TEXT";
            $text = utf8_decode($text);

            mail($empfaenger, $betreff, $text, $from);
        }
      
        $i++;
      
    }

    // Lock-File löschen
    unlink('/tmp/cronjob_lock');
 
Zuletzt bearbeitet:
Du nutzt eine Datenbank. Du könntest also auch in eine Datenbank-Tabelle deine Jobs loggen. Damit könntest Du auch feststellen, ob der vorherige Job abgeschlossen ist oder nicht und könntest darauf reagieren ...

Da während des Scripts auch Tabellen upgedated werden, würde ich es vermeiden, Jobs parallel laufen zu lassen. Ansonsten müsstest Du Dich darum kümmern, dass der gleiche Datensatz mehrfach verarbeitet werden könnte ...
 
Zurück
Oben