jiriki: GD-Bib: Erzeugen von Bild klappt nur offline, nicht online

Hey Leute,

Hab jetzt wirklich zwei Stunden rumgetestet, aber es will einfach nicht. Jetzt hoff ich auf Euch erfahrenen Köpfe, die mir schon öfters aus der Patsche geholfen haben:

Ich möchte über PHP&GD-Lib ein Bild erstellen. Das PHP-Script print.php beginnt mit

  
header( "Content-type: image/jpeg" );  
// Starte Session-Verwaltung  
session_start();  
// Einbinden der Logindaten  
require_once( "Grummel/admin.inc" );  
// Starte DB-Anbindung  
$link = mysql_connect( $mysql_server, $mysql_user, $mysql_pw );  
mysql_select_db( $db_name, $link ) or die( "Datenbank konnte nicht gefunden werden." );  
..  

wonach einige Datenbankanfragen kommen zu dem spezifischen Benutzer und dann werden die Daten über

  
$pic_path = "Pics/Members/wappen.jpg";  
$image = imagecreatefromjpeg( $pic_path );  
[..]  
imageline([..]);  
[..]  
imagestring([..]);  
// Ausgabe des Bildes im Browser  
imagejpeg( $image );  
// Freigabe des Speicherplatzes  
imagedestroy( $image );  

direkt im Browser in einem JPEG-Bild ausgegeben.
Offline bei meinem WinXP&IIS5.1-System läuft es reibungslos, aber online auf einem UNIX-System wird bei Aufruf von print.php lediglich der Pfad zu print.php ausgegeben:

http://[domain]/print.php

Online ist auf jeden Fall:

  • die GD-Bib in der gleichen Version installiert wie offline
  • der Pfad $pic_path korrekt (mit file_exists() überprüft)

Desweiteren hab ich alle Ausgaben der MySQL-Abfragen überprüft, indem ich den header auf "text/html" gesetzt habe, und da sind alle Abfragen richtig. Auch die GD-Funktionen liefern im HTML-Header-Modus keine Fehlermeldungen und zu guter Letzt werden mir im HTML-Header-Modus Zig Zeilen von kodiertem Kauderwelsch ausgegeben, welches ich als Ausgabe von imagejpeg() interpretiere.

Sowohl offline als auch online ist die Umgebungsvariable "register_globals" auf "Off" gesetzt.

Alle Ideen für weitere mögliche Fehlerquellen empfange ich mit Kusshand.

Grüßle

  1. Hallo,

    $pic_path = "Pics/Members/wappen.jpg";
    $image = imagecreatefromjpeg( $pic_path );
    [..]
    imageline([..]);
    [..]
    imagestring([..]);
    // Ausgabe des Bildes im Browser
    imagejpeg( $image );
    // Freigabe des Speicherplatzes
    imagedestroy( $image );

      
    
    > Offline bei meinem WinXP&IIS5.1-System läuft es reibungslos, aber online auf einem UNIX-System wird bei Aufruf von print.php lediglich der Pfad zu print.php ausgegeben:  
      
    ich sehe keinen Ansatz einer Fehlerbehandlung in Deinem Code. Du könntest beispielsweise vor der Ausgabe des Bildes im Browser das Bild als Datei speichern.  
      
    Grundsätzlich ginge ich das Problem auch ganz anders an. Die Bilderzeugung sollte völlig unabhängig von irgendwelchen Sessions und Datenbankabfragen erfolgen. Die Werte, die aus diesen Quellen kommen, übergäbe ich z.B. dem Konstruktor (falls ich die Bilderzeugung über eine Klasse regelte) oder als Funktionsparameter (wenn es eine einzige Funktion wäre). Dadurch verringerst Du die Skriptkomplexität und verbesserst die Möglichkeiten der Fehlersuche.  
      
      
    Freundliche Grüße  
      
    Vinzenz
    
    1. echo $begrüßung;

      Du könntest beispielsweise vor der Ausgabe des Bildes im Browser das Bild als Datei speichern.

      In einer Produktivumgebung sollte man das vermeiden, oder aber man muss dafür sorgen, dass die Requests sich nicht gegeseitig beim Datei-Handling ins Gehege kommen. Aber auch zu Testzwecken ist das nicht besonders sinnvoll. Zum einen ist so ein Schreibvorgang eine weitere potentielle Fehlerquelle, was beispielsweise Berechtigungen angeht. Zum anderen ist der Nutzen zweifelhaft. Was soll denn mit der Datei passieren? Am Server anschauen? Beim Hoster wohl kaum. Downloaden? Da gibt es keinen Unterschied zwischen dem direkten Empfangen der Daten und dem zwischengepufferten, außer den zusätzlichen Fehlermöglichkeiten.

      ich sehe keinen Ansatz einer Fehlerbehandlung in Deinem Code.

      Das ist schon eher zielführend.

      • Auswerten der und reagieren auf die Rückgabewerte der Funktionen.
      • Schauen, was beim Client ankommt. Den Content-Type-Header zeitweilig außer Kraft setzen oder die Quelltextansicht des Browsers verwenden.

      header( "Content-type: image/jpeg" );
      mysql_select_db( $db_name, $link ) or die( "Datenbank konnte nicht gefunden werden." );

      Das beißt sich. "or die()" ist selten eine geeignete Reaktion auf Fehler. Und ein Text entspricht nicht dem Content-Type image/jpeg.

      echo "$verabschiedung $name";

      1. Hallo,

        Du könntest beispielsweise vor der Ausgabe des Bildes im Browser das Bild als Datei speichern.
        In einer Produktivumgebung sollte man das vermeiden, oder aber man muss dafür sorgen, dass die Requests sich nicht gegeseitig beim Datei-Handling ins Gehege kommen.

        ja, das ist natürlich richtig.

        Aber auch zu Testzwecken ist das nicht besonders sinnvoll. [...] Was soll denn mit der Datei passieren? Am Server anschauen? Beim Hoster wohl kaum. Downloaden? Da gibt es keinen Unterschied zwischen dem direkten Empfangen der Daten und dem zwischengepufferten, außer den zusätzlichen Fehlermöglichkeiten.

        Doch, ich halte das für eine sehr schlaue Teststrategie. Denn so kann ich im Browserfenster eventuelle Fehlermeldungen verfolgen, und zum Schluss trotzdem noch das erzeugte Bild anschauen und beurteilen.

        So long,
         Martin

        --
        Kleine Geschenke erhalten die Freundschaft.
        Große verderben sie aber meist auch nicht.
        1. Hallo Martin,

          Du könntest beispielsweise vor der Ausgabe des Bildes im Browser das Bild als Datei speichern.

          Doch, ich halte das für eine sehr schlaue Teststrategie.

          danke für die Blumen, die Du meinen unausgegorenen Gedanken, die ich verfrüht veröffentlicht hab', spendierst. Im Produktivbetrieb ist sowas wirklich sehr heikel, hier sollte der Zugriff auf das Skript unbedingt soweit eingeschränkt werden, wie möglich, sprich: Single-User-Betrieb für den Entwickler :-)

          Denn so kann ich im Browserfenster eventuelle Fehlermeldungen verfolgen, und zum Schluss trotzdem noch das erzeugte Bild anschauen und beurteilen.

          Nach Möglichkeit sollte der Produktivcode so robust sein, dass solche Verzweiflungsmaßnahmen gar nicht nötig wären. Wie üblich greift das KISS-Prinzip. Erster Schritt wäre die Entkopplung der Bilderzeugung von der Datenbeschaffung.

          Freundliche Grüße

          Vinzenz

      2. Hallo dedlfix,

        Du könntest beispielsweise vor der Ausgabe des Bildes im Browser das Bild als Datei speichern.

        In einer Produktivumgebung sollte man das vermeiden, oder aber man muss dafür sorgen, dass die Requests sich nicht gegeseitig beim Datei-Handling ins Gehege kommen. Aber auch zu Testzwecken ist das nicht besonders sinnvoll.

        stimmt, hab' ich nicht dran gedacht. Debuggen in der Produktivumgebung ist immer heikel.

        header( "Content-type: image/jpeg" );
        mysql_select_db( $db_name, $link ) or die( "Datenbank konnte nicht gefunden werden." );

        *das* hab' ich auch noch übersehen, Schande über mich.

        Das beißt sich. "or die()" ist selten eine geeignete Reaktion auf Fehler. Und ein Text entspricht nicht dem Content-Type image/jpeg.

        macht sich aber nett :-)

        Deswegen empfehle ich einen anderen Ansatz zur Bilderzeugung, der von irgendwelchen Sessions und Datenbanken überhaupt nichts weiß.

        Freundliche Grüße

        Vinzenz

      3. Das beißt sich. "or die()" ist selten eine geeignete Reaktion auf Fehler. Und ein Text entspricht nicht dem Content-Type image/jpeg.

        Ja, ich geb zu, das resultierende Design der Fehlermeldung wäre mangelhaft.

        Ansonsten ists echt zum Mäusemelken. Ich habs nun auch noch auf nem andren Online-Server getestet, und da funktioniert das Script auch ohne Probleme.
        Und wenn mich nicht alles täuscht (ich verlier bei drei Tabs, die alle die gleiche Seite anzeigen, welche jedoch auf drei verschiedenen Servern liegen dann nochmal die Übersicht), dann lief es bis gestern auch noch auf dem Problem-Server.

        Seitdem hab ich auf dem Problemserver lediglich die register_globals auf off gesetzt und zwei Dateien geändert, die meiner Meinung nach nichts mit der Sache zu tun haben.

        *weiterimDunkelntapp*

        1. Hi,

          Ansonsten ists echt zum Mäusemelken. Ich habs nun auch noch auf nem andren Online-Server getestet, und da funktioniert das Script auch ohne Probleme.

          Kann man sich das mal online anschauen?

          Seitdem hab ich auf dem Problemserver lediglich die register_globals auf off gesetzt und zwei Dateien geändert, die meiner Meinung nach nichts mit der Sache zu tun haben.

          Nicht "Meinen", sondern Verifizieren.
          Sonst bleibt's naemlich bei

          *weiterimDunkelntapp*

          MfG ChrisB

          --
          „This is the author's opinion, not necessarily that of Starbucks.“
          1. Nicht "Meinen", sondern Verifizieren.
            Sonst bleibt's naemlich bei

            *weiterimDunkelntapp*

            Ja, also die haben nix damit zu tun.

            Witzigerweise hab ich jetzt auch seit der gleichen Zeit ein Darstellungsproblem mit dem phpMyAdmin. Auf dem Problemserver hat er viel zu große Schrift und deutlich weniger Formatierung (vor allem bei der Darstellung der Tabellendaten) (Link) als bei den andren beiden Servern (Link).

            Ein weiterer Unterschied zwischen den Seiten auf den beiden Onlineservern ist, dass beim Problemserver die PHP-Session-ID per URL weitergegeben wird, während das bei dem anderen Online-Server nicht der Fall ist (per Cookie, nehm ich mal an).

            Hat das vielleicht mit irgendwelchen Schreibrechten auf irgendein Verzeichnis zu tun?

            Grüßle

  2. Habs immer noch nicht gelöpst. Unglaublich.

    Ein weiteres Symptom des großen ganzen Problems ist, dass explizit auf dem Problemserver die PHP-SessionID per GET/POST weitergegeben wird ,und nicht per Cookie, so wie bei den andren beiden Servern, obwohl alle drei exakt die gleichen Einstellungen unter "Sessions" in der php.ini respektive phpinfo() haben.

    Directive               Local Value     Master Value
    session.auto_start      Off             Off
    session.bug_compat_42   On              On
    session.bug_compat_warn On              On
    session.cache_expire    180             180
    session.cache_limiter   nocache         nocache
    session.cookie_domain   no value        no value
    session.cookie_lifetime 0               0
    session.cookie_path     /               /
    session.cookie_secure   Off             Off
    session.entropy_file    no value no value
    session.entropy_length  0         0
    session.gc_divisor      100             100
    session.gc_maxlifetime  1440            1440
    session.gc_probability  1               1
    session.name            PHPSESSID       PHPSESSID
    session.referer_check   no value        no value
    session.save_handler    files           files
    session.save_path       /tmp            /tmp
    session.serialize_handler php           php
    session.use_cookies     On              On
    session.use_only_cookiesOff             Off
    session.use_trans_sid   On              On

    Und ich geh jedesmal mit dem gleichen Firefox und den gleichen amorösen Einstellungen zu Cookies auf die Seiten, also sollte von Clientseite nix gegen Cookies sprechen.

    Grüßle

    1. Hallo,

      Habs immer noch nicht gelöpst. Unglaublich.

      ich rate Dir erneut dazu, Dein Skript umzubauen. Mache die Bilderstellung von Session und DB-Zugriff unabhängig. Du schreibst doch einfach Texte in die Grafik. Übergib nach dem Auslesen aus Session/DB diese Texte an die Funktion, die das Bild erzeugt. Noch schicker wäre eine Klasse, der Du im Konstruktor die entsprechenden Texte übergibst. Somit kannst Du die Bilderzeugung unabhängig von irgendwelchen Sessions und Datenbankzugriffen testen. Bei Deinem derzeitigen Code ist beides Voraussetzung - und das ist schlecht für die Fehlersuche.

      Freundliche Grüße

      Vinzenz

    2. Hi,

      Habs immer noch nicht gelöpst. Unglaublich.

      Ja, scheint mir auch so.
      Dass du immer noch nicht viel mehr herausgefunden hast, als dass es auf dem einen Server "nicht funzt", finde ich schon bedenklich.

      Wenn PHP auf Grund irgendeines Fehlers nicht dazu kommt, die Grafik zu generieren - dann sollte sich doch irgendwo auch eine Meldung zum Fehler ausfindig machen lassen.

      Noch mal die Frage: Gibt es das Bild-generierende Script mal online zu sehen?

      MfG ChrisB

      --
      „This is the author's opinion, not necessarily that of Starbucks.“
      1. Noch mal die Frage: Gibt es das Bild-generierende Script mal online zu sehen?

        Gerne.

        Aufrufender Links aus my_paid_items.php:
        --

          
        <form method="post" action="print.php" name="print_bills" target="_blank">  
          <input type="image" src="Pics/Members/list_paid_items.png" style="border-width: 0px;" name="print" />  
        </form>  
        
        

        --

        print.php:
        --

          
        <?php  
        session_start();  
        if( isset( $_SESSION[ "username" ] ) && isset( $_SESSION[ "password" ] ) )  
        {  
          include( "Docs/Members/members_print_bill.php" );  
        }  
        ?>  
        
        

        --

        members_print_bill.php:
        Kurze Erklärung:
        Zuerst ruft PHP die Informationen bezüglich des Mitglieds und seiner Pferde ab, für die im aktuellen Jahr bezahlt wurden. Dann werden die Daten kurz formatiert und anschließend das Bild mit Vorlage des "wappen.jpg" ausgegeben.
        --

          
        <?php  
          
        // Ausgabe des Dokumenttyps  
        header( "Content-type: image/jpeg" );  
          
        require_once( "data.php" );  
          
        // Starte DB-Anbindung  
        $link = mysql_connect( $mysql_server, $mysql_user, $mysql_pw );  
        mysql_select_db( $db_name, $link ) or die( "Datenbank konnte nicht gefunden werden." );  
          
        // Adresse des Kunden / Mitglieds  
        // ************************************************************************************************************  
        $fields = array( "fname", "lname", "farm", "street", "zip", "city", "state" );  
        $query = "SELECT ";  
                    foreach( $fields as $var ) $query .= "u.".$var.", ";  
                    for( $i=0; $i<count( $fields )-1; $i++ ) $query .= "tu.".$fields[$i]." as tu_".$fields[$i].", ";  
        $query .=   "tu.".$fields[ $i ]." as tu_".$fields[$i]."  
                    FROM m_user as u LEFT JOIN m_temp_user as tu ON ( u.ownerno = tu.ownerno AND ( tu.status = \"data_change\" OR tu.status = \"registered\" ) )  
                    WHERE u.ownerno = \"".$_SESSION[ "ownerno" ]."\"  
                    ORDER BY tu.applied DESC;";  
          
          
        $temp = mysql_query( $query );  
        $result = mysql_fetch_array( $temp, MYSQL_ASSOC );  
          
        $query = "SELECT name, regnumber FROM stallions WHERE ownerno = \"".$_SESSION[ "ownerno" ]."\" AND paid REGEXP DATE_FORMAT( CURDATE(), \"%y\" );";  
        $temp_stallions = mysql_query( $query );  
        $query = "SELECT name, regnumber FROM m_regist_mares WHERE ownerno = \"".$_SESSION[ "ownerno" ]."\" AND paid REGEXP DATE_FORMAT( CURDATE(), \"%y\" );";  
        $temp_mares = mysql_query( $query );  
          
        $data = array();  
        foreach( $fields as $var )  
        {  
          $data[ $var ] = !empty( $result[ "tu_".$var ] ) ? $result[ "tu_".$var ] : $result[ $var ];  
        }  
          
        $address = array();  
        $name = array();  
          
        if(! empty( $data[ "farm" ] ) ) array_push( $address, $data[ "farm" ] );  
        if(! empty( $data[ "fname" ] ) ) array_push( $name, $data[ "fname" ] );  
        if(! empty( $data[ "lname" ] ) ) array_push( $name, $data[ "lname" ] );  
        if( count( $name ) > 0 ) array_push( $address, implode( " ", $name ) );  
        if(! empty( $data[ "street" ] ) ) array_push( $address, $data[ "street" ] );  
          
        if( strtoupper( trim( $data[ "zip" ] ) ) == "CANADA" )  
        {  
          if( preg_match( "!^([\w\s\.\-áàéèêíìîóòúùåçõãïø]+)\s*,\s*(\w+)\s+(\w[\w\s]+\w)\s*$!", $data[ "city" ], $result ) )  
          {  
            $data[ "city" ] = $result[1];  
            $data[ "state" ] = $result[2];  
            $data[ "zip" ] = $result[3];  
            $data[ "country" ] = "CANADA";  
          }  
        }  
        array_push( $address, $data[ "city" ].", ".$data[ "state" ]." ".$data[ "zip" ] );  
        if( isset( $data[ "country" ] ) )  
          array_push( $address, $data[ "country" ] );  
        // ************************************************************************************************************  
          
        $pic_path = "Pics/Members/wappen.jpg";  
        $pic_info = getimagesize( $pic_path );  
        $pic_width = $pic_info[0];  
        $pic_height = $pic_info[1];  
          
        $image = imagecreatefromjpeg( $pic_path );  
          
        $color_white = imagecolorallocate($image, 255, 255, 255);  
        $color_grey = imagecolorallocate($image, 192, 192, 192);  
        $color_blue = imagecolorallocate($image, 0, 0, 255);  
        $color_black = imagecolorallocate($image, 0, 0, 0);  
          
        // Dokumentrahmen  
        // ***************************  
        // Zeichne Rahmen  
        imageline( $image, 1, 1, 1, ( $pic_height-1 ), $color_blue);  
        imageline( $image, 1, 1, ( $pic_width-1 ), 1, $color_blue);  
        imageline( $image, ( $pic_width-1 ), 1, ( $pic_width-1 ), ( $pic_height-1 ), $color_blue);  
        imageline( $image, 1, ( $pic_height-1 ), ( $pic_width-1 ), ( $pic_height-1 ), $color_blue);  
          
        $current_line = 20;  
          
        // Dokumentkopf  
        imagestring( $image, 5, 98, $current_line, $firma1." / ".$firma2, $color_black );  
        imageline( $image, 20, $current_line+20, $pic_width-20, $current_line+20, $color_black);  
        imagestring( $image, 3, 20, $current_line+25, $street, $color_black );  
        imagestring( $image, 3, 20, $current_line+40, $place, $color_black );  
        imagestring( $image, 3, 340, $current_line+25, "phone:", $color_black ); imagestring( $image, 3, 400, 45, $phone, $color_black );  
        imagestring( $image, 3, 340, $current_line+40, "fax:", $color_black ); imagestring( $image, 3, 400, 60, $fax, $color_black );  
        imagestring( $image, 3, 730, $current_line+25, "date:", $color_black ); imagestring( $image, 3, 781, 45, date( "m/d/Y" ), $color_black );  
          
        // Anschrift des Mitglieds  
        // *******************************  
        // Rahmen  
        $current_line += 80;  
        imagestring( $image, 5, 20, $current_line, "Member:", $color_black );  
        imageline( $image, 20, $current_line+20, 380, $current_line+20, $color_blue);  
        imageline( $image, 20, $current_line+20, 20, $current_line+20+count( $address ) * 25, $color_blue);  
        imageline( $image, 20, $current_line+20+count( $address ) * 25, 380, $current_line+20+count( $address ) * 25, $color_blue);  
        imageline( $image, 380, $current_line+20+count( $address ) * 25, 380, $current_line+20, $color_blue);  
          
        // Inhalt  
        $current_line += 30;  
        foreach( $address as $var )  
        {  
          imagestring( $image, 5, 30, $current_line, $var, $color_black );  
          $current_line += 20;  
        }  
          
        // Preisliste  
        // *******************************  
        // Rahmen  
        $current_line -= count( $address ) * 20 + 30;  
          
        imagestring( $image, 5, 500, $current_line, "Late fees (if paid after April 1st):", $color_black );  
        imageline( $image, 500, $current_line+20, 780, $current_line+20, $color_blue);  
        imageline( $image, 500, $current_line+20, 500, $current_line+20+3 * 25, $color_blue);  
        imageline( $image, 500, $current_line+20+3 * 25, 780, $current_line+20+3 * 25, $color_blue);  
        imageline( $image, 780, $current_line+20+3 * 25, 780, $current_line+20, $color_blue);  
          
        // Inhalt  
        imagestring( $image, 5, 510, $current_line+30, "Membership:", $color_black );  
        imagestring( $image, 5, 720, $current_line+30, "100.-", $color_black );  
        imagestring( $image, 5, 510, $current_line+50, "Mare:", $color_black );  
        imagestring( $image, 5, 729, $current_line+50, "60.-", $color_black );  
        imagestring( $image, 5, 510, $current_line+70, "Stallion:", $color_black );  
        imagestring( $image, 5, 720, $current_line+70, "400.-", $color_black );  
          
          
        $current_line += 40+count( $address )*20+30;  
          
        imagestring( $image, 5, 20, $current_line, "This invoice (all fees on this page are listed in US$):", $color_black );  
          
        $current_line += 35;  
          
        $total_amount = 0;  
        $total_items = 0;  
          
        $costs_member = 80;  
        $costs_stallion = 300;  
        $costs_mare = 30;  
          
        // Auflisten der bezahlten Posten  
        if( strstr( $_SESSION[ "paid" ], date( "Y" ) ) )  
        {  
          imagestring( $image, 5, 30, $current_line, "- Membership fee (".date("Y").")", $color_black );  
          imagestring( $image, 5, 770, $current_line, $costs_member.".-", $color_black );  
          $current_line += 20;  
          $total_amount += $costs_member;  
          $total_items++;  
        }  
        while( $stallion = mysql_fetch_array( $temp_stallions, MYSQL_ASSOC ) )  
        {  
          imagestring( $image, 5, 30, $current_line, "- Annual fee for ".$stallion[ "name" ]." (".date("Y").")", $color_black );  
          imagestring( $image, 5, 761, $current_line, $costs_stallion.".-", $color_black );  
          $current_line += 20;  
          $total_amount += $costs_stallion;  
          $total_items++;  
        }  
        while( $mare = mysql_fetch_array( $temp_mares, MYSQL_ASSOC ) )  
        {  
          imagestring( $image, 5, 30, $current_line, "- Annual fee for ".$mare[ "name" ]." (".date("Y").")", $color_black );  
          imagestring( $image, 5, 770, $current_line, $costs_mare.".-", $color_black );  
          $current_line += 20;  
          $total_amount += $costs_mare;  
          $total_items++;  
        }  
          
        $current_line -= $total_items*20+15;  
        imageline( $image, 20, $current_line, $pic_width-20, $current_line, $color_blue);  
        imageline( $image, 20, $current_line, 20, $current_line+15+$total_items * 20+15, $color_blue);  
        imageline( $image, 20, $current_line+15+$total_items * 20+15, $pic_width-20, $current_line+15+$total_items * 20+15, $color_blue);  
        imageline( $image, $pic_width-20, $current_line+15+$total_items * 20+15, $pic_width-20, $current_line, $color_blue);  
          
        $current_line += $total_items*20+30+20;  
        $length_total_amount = strlen( $total_amount );  
        imageline( $image, 20, $current_line, $pic_width-20, $current_line, $color_blue);  
        imageline( $image, 20, $current_line, 20, $current_line+30, $color_blue);  
        imageline( $image, 20, $current_line+30, $pic_width-20, $current_line+30, $color_blue);  
        imageline( $image, $pic_width-20, $current_line+30, $pic_width-20, $current_line, $color_blue);  
        imagestring( $image, 5, 30, $current_line+6, "TOTAL:", $color_black );  
        imagestring( $image, 5, 770-($length_total_amount-2)*9, $current_line+6, $total_amount.".-", $color_black );  
          
        // Ausgabe des Bildes im Browser  
        imagejpeg( $image );  
        // Freigabe des Speicherplatzes  
        imagedestroy( $image );  
          
        mysql_close( $link );  
        ?>  
        
        

        --

        Und da es bei den andren Servern funktioniert, gehe ich davon aus, dass es keine syntaktischen Fehler hat.

        Grüßle und Danke

        1. Hallo,

          Noch mal die Frage: Gibt es das Bild-generierende Script mal online zu sehen?

          $query = "SELECT ";
                      foreach( $fields as $var ) $query .= "u.".$var.", ";
                      for( $i=0; $i<count( $fields )-1; $i++ ) $query .= "tu.".$fields[$i]." as tu_".$fields[$i].", ";
          $query .=   "tu.".$fields[ $i ]." as tu_".$fields[$i]."
                      FROM m_user as u LEFT JOIN m_temp_user as tu ON ( u.ownerno = tu.ownerno AND ( tu.status = "data_change" OR tu.status = "registered" ) )
                      WHERE u.ownerno = "".$_SESSION[ "ownerno" ].""
                      ORDER BY tu.applied DESC;";

          es ist überhaupt keine gute Idee, Zeichenketten in SQL-Statements in doppelte Anführungszeichen zu packen. Nicht nur, dass die meisten SQL-Dialekte das sowieso nicht erlauben, bei MySQL ist die Verwendung abhängig vom Modus, in dem MySQL läuft. Ist der ANSI-Mode aktiv, dann ist die Verwendung nicht erlaubt, siehe Handbuchabschnitt Strings. Somit kann der gleiche Code auf Server A laufen und auf Server B nicht.

          Es ist hingegen eine gute Idee, Zeichenketten in SQL-Statements *immer* in einfache Anführungszeichen einzuschließen. Das ist *immer* erlaubt. Es ist auch viel einfacher: man muss nicht nachdenken, welche man verwendet.

          Zusätzlich ist es eine hervorragende Idee, alle Daten aus variablen Quellen - wie hier der Session - immer kontextgemäß aufzubereiten. Bei Dir wäre dies die Aufbereitung mit mysql_real_escape_string. Zuvor gilt es die berüchtigten Magic Quotes richtig zu behandeln, d.h. auszuschalten bzw. ihre Auswirkungen rückgängig zu machen. Es ist viel einfacher, diese Behandlung *immer* vorzunehmen, weil man nicht zu überlegen braucht, ob man vielleicht darauf verzichten könnte. Somit gibt es auch nie den Fall, dass man auf die Behandlung verzichtet hat, obwohl sie erforderlich gewesen wäre.

          $temp = mysql_query( $query );
          $result = mysql_fetch_array( $temp, MYSQL_ASSOC );

          Hier fehlt eine Fehlerbehandlung komplett. Du nimmst an, dass es nicht zu Fehlern kommt. Es gibt keinen Anlass, so optimistisch zu sein.

          $query = "SELECT name, regnumber FROM stallions WHERE ownerno = "".$_SESSION[ "ownerno" ]."" AND paid REGEXP DATE_FORMAT( CURDATE(), "%y" );";

          ist REGEXP wirklich nötig? Es gibt YEAR().

          Wie ich es mir gedacht habe, wäre es sehr leicht, Datenbeschaffung und Bilderzeugung zu trennen. Ein nettes assoziatives Array als Übergabeparameter für die Bilderzeugungsfunktion täte es auch. Somit wäre Debugging viel viel einfacher. Ich rate Dir dringend dazu, Deinen Code in dieser Hinsicht zu verbessern.

          Freundliche Grüße

          Vinzenz

        2. Hi,

          Noch mal die Frage: Gibt es das Bild-generierende Script mal online zu sehen?

          Gerne.

          Ich meinte *online*, nicht den Code.

          (Und zur Sicherheit: Die fehlerhafte Version waere erst mal die interessantere.)

          MfG ChrisB

          --
          „This is the author's opinion, not necessarily that of Starbucks.“