FPDF Fatal error

Irgendwelche Probleme mit XAMPP für Linux? Dann ist hier genau der richtige Ort um nachzufragen.

FPDF Fatal error

Postby tomatensalat » 01. April 2020 05:09

Hallo zusammen

Ich arbeite mit Manjaro Linux 19.0.2 (Kyria) und XAMPP for Linux 7.4.2-0.

FPDF zeigt mir unter lampp folgenden Fehler an:

Fatal error: Uncaught Exception: FPDF error: Some data has already been output, can't send PDF file (output started at :0) in /opt/lampp/htdocs/lrdb/fpdf.php:271 Stack trace: #0 /opt/lampp/htdocs/lrdb/fpdf.php(1049): FPDF->Error('Some data has a...') #1 /opt/lampp/htdocs/lrdb/fpdf.php(999): FPDF->_checkoutput() #2 /opt/lampp/htdocs/lrdb/dokument-pdf.php(244): FPDF->Output('I', 'RE-1984-2020-03...') #3 {main} thrown in /opt/lampp/htdocs/lrdb/fpdf.php on line 271


Da FPDF die Ausgabe auf dem Server einwandfrei ausführt, dachte ich erst, da es lokal einfach ein Berechtigungsproblem ist. So habe ich 'mich' für das gesamte htdocs-Verzeichnis als Besitzer eintragen lassen. Doch das brachte keine Lösung. Ich vermute zwar immer noch das es einzig daran liegt, doch jetzt bin ich auf Eure Profi-Tipps angewiesen.

Ich bin übrigens kein Profi und habe mir einzig ein kleines Rechnungsprogramm (Ihr würdet wohl sagen als Bastelei) angelegt. Es funktioniert jedoch gut und das programmieren in meinem bescheidenen Rahmen macht echt Spass!
:D
tomatensalat
 
Posts: 5
Joined: 01. April 2020 04:42
XAMPP version: 7.4.2-0
Operating System: Manjaro 19.0.2 Kyria

Re: FPDF Fatal error

Postby Nobbie » 01. April 2020 12:58

Wenn es nur ein kleines Script ist, stelle es doch mal hier rein und welche FPDF Installation hast Du? Und wo ist alles installiert? Nur mit dieser wilden Fehlermeldung fange ich nichts an.
Nobbie
 
Posts: 11565
Joined: 09. March 2008 13:04

Re: FPDF Fatal error

Postby tomatensalat » 01. April 2020 13:06

Hi Nobbie, Danke für Deine rasche Antwort. Ich nutze die aktuelle Fpdf-Version 1.82. Installiert ist es lokal auf meinem Notebook im Standard-Verzeichnis /opt/lampp. Wie gesagt, das Script läuft auf meinem Hosting einwandfrei. Da der Fehler offensichtlich, oder zumindest so wie ich das laienhaft annehme, irgendwie mit dem 'Output', also der Ausgabe, ein Problem hat, dachte ich an ein lokales Berechtigungsproblem.
tomatensalat
 
Posts: 5
Joined: 01. April 2020 04:42
XAMPP version: 7.4.2-0
Operating System: Manjaro 19.0.2 Kyria

Re: FPDF Fatal error

Postby Nobbie » 01. April 2020 13:11

Ich habe jetzt mal FPDF 1.82 heruntergeladen und in htdocs/fpdf182 installiert (das ist die Default EInstellung) und habe alle Tutorials angeklickt, läuft alles fehlerfrei. Die Dateirechte habe ich bei htdocs auf 0777 gesetzt mit User root und Group root. Das Verzeichnis fpdf182 und alles darunter hat 0775 als Dateiberechtigung und User und Group sind jeweils meine eigene UserID.
Nobbie
 
Posts: 11565
Joined: 09. March 2008 13:04

Re: FPDF Fatal error

Postby Nobbie » 01. April 2020 13:26

Ich habe aber auch so schon den Fehler gefunden, an Hand der Fehlermeldung. Du machst in Deinem Dokument (in dem PHP Script) irgendwo am Anfang einen Fehler. Du sendest dort irgendwelche Daten schon an den Browser, das kann beispielsweise einfach eine leere Zeile am Scriptanfang sein, dass kann ein unerlaubtes HTML Tag sein, vielleicht eine Überschrift, irgendetwas steht am Anfang Deines Scripts. Und das führt genau zu diesem Fehler, das steht auch im tuto1.html extra am Ende geschrieben:

"Caution: in case when the PDF is sent to the browser, nothing else must be output by the script, neither before nor after (no HTML, not even a space or a carriage return). If you send something before, you will get the error message: "Some data has already been output, can't send PDF file". If you send something after, the document might not display.


Dass das auf dem Server im Internet trotzdem läuft, liegt wahrscheinlich daran, dass dort der Output gepuffert wird. Das machen viele Hoster, die schicken nicht jeden Output direkt zum Browser, sondern sammeln erst einmal alles ein in einem Cache und das wird dann meistens auch noch gepackt (der Browser bekommt eine entsprechende Mitteilung, dass er das auch versteht), das spart Traffic. Und dadurch wird nicht schon etwas zum Browser geschickt, bevor FPDF etwas senden möchte. FPDF muss selbst noch vor dem ersten Output mit dem Browser verabreden, dass jetzt eine PDF Datei als Inhalt kommt. Diese "Verabredung" (ein Teil des sog. HTTP Protokolls) muss aber stattfinden, bevor überhaupt irgendein Inhalt versendet wurde, anders kann es auch nicht gehen, sonst weiß der Browser nicht, was für eine Art dieser Inhalt ist.

Man könnte jetzt Xampp auch so einstellen, dass es sich so verhält wie der Server und die Daten puffert. Aber das halte ich für den falschen Weg, denn spätestens wenn Du auf einen Provider triffst, der das NICHT so macht, läuft Dein Script endgültig nicht. Besser ist es, diesen Fehler auszubügeln. Das kann nicht sooo schwer sein, das ist irgendeine Kleinigkeit wahrscheinlich ganz am Anfang.
Nobbie
 
Posts: 11565
Joined: 09. March 2008 13:04

Re: FPDF Fatal error

Postby tomatensalat » 01. April 2020 13:44

Nobbie, Danke vielmals! Jetzt habe ich wieder etwas gelernt. Ich habe nun ebenfalls die fpdf-Tutorial-Testdatei kopiert und die läuft einwandfrei. Mein Script werde ich nun Stück für Stück analysieren, und mit all Deinen wertvollen Hinweisen werde ich das sicherlich schnell herausfinden. Ich werde hier später notieren was in meinem Script den Fehler ausgelöst hat. Danke für Deine sehr wertvolle Hilfe und Unterstützung.
tomatensalat
 
Posts: 5
Joined: 01. April 2020 04:42
XAMPP version: 7.4.2-0
Operating System: Manjaro 19.0.2 Kyria

Re: FPDF Fatal error

Postby tomatensalat » 01. April 2020 15:36

Ich komme doch nochmal mit einer Frage. Es ist mir nun klar dass es an den Variablen liegt die ich am Anfang definiere. In der Fpdf-Dokumentation habe ich (noch) nichts über Variablenübergaben gefunden. Oder funktioniert dies einzig über $_POST? Gibt es eine korrektere oder einfache Art Variablen in fpdf selbst zu definieren/verwenden? :wink: ... oder wie wird das korrekt gemacht? Bin schon gespannt, obwohl ich mich nun wohl definitiv als 'Bastler' oute! :lol:

Code: Select all
<?php
include("einbinden/db.php");

// Variablen: Mensch
$abfrage   = "SELECT * FROM Mensch WHERE mID = " . $_GET['mID'];
$ergebnis  = mysqli_query($db, $abfrage) or die ('m:' . mysqli_error($db));
while($row = mysqli_fetch_object($ergebnis))
{
$mID           = $row->mID;
$mWM           = $row->mWM;
$mName         = $row->mName;
$mVorname      = $row->mVorname;
$mFirma        = $row->mFirma;
$mFirmenslogan = $row->mFirmenslogan;
$mStrasse      = $row->mStrasse;
$mPLZ          = $row->mPLZ;
$mOrt          = $row->mOrt;
$mPostfach     = $row->mPostfach;
}

// Variablen: Dokument
$abfrage   = "SELECT * FROM Dokument WHERE dID = " . $_GET['dID'];
$ergebnis  = mysqli_query($db, $abfrage) or die ('d:' . mysqli_error($db));
while($row = mysqli_fetch_object($ergebnis))
{
$dDatum     = $row->dDatum;
$dArt       = $row->dArt;
$dReferenz  = $row->dReferenz;
$dTitel     = $row->dTitel;
$dNotizVor  = $row->dNotizVor;
$dNotizNach = $row->dNotizNach;
$dStatus    = $row->dStatus;
$dEndbetrag = $row->dEndbetrag;
}

// Variablen: DokumentTexte
$abfrage = "SELECT * FROM DokumentTexte WHERE dtxtID = 1";
$ergebnis = mysqli_query($db, $abfrage) or die ('txt:' . mysqli_error($db));
while($row = mysqli_fetch_object($ergebnis))
{
$dtxtREtitel         = $row->dtxtREtitel;
$dtxtREslogan        = $row->dtxtREslogan;
$dtxtREadrbank       = $row->dtxtREadrbank;
$dtxtREnFusszeile    = $row->dtxtREnFusszeile;
$dtxtREkBestaetigung = $row->dtxtREkBestaetigung;
$dtxtREkAnnullation  = $row->dtxtREkAnnullation;
$dtxtREkFusszeile    = $row->dtxtREkFusszeile;
$dtxtREaBestaetigung = $row->dtxtREaBestaetigung;
$dtxtREaAnnullation  = $row->dtxtREaAnnullation;
$dtxtREaFusszeile    = $row->dtxtREaFusszeile;
}

// Variablen: DokumentPositionen
$abfrage   = "SELECT * FROM DokumentPosition WHERE dpDokNr = " . $_GET['dID'] . " ORDER BY dpReihenfolge";
$ergebnis  = mysqli_query($db, $abfrage) or die ('dp:' . mysqli_error($db));
while($row = mysqli_fetch_object($ergebnis))
{
$dpAID          = $row->dpAID;
$dpName         = $row->dpName;
$dpEinzelpreis  = $row->dpEinzelpreis;
$dpAnzahl       = $row->dpAnzahl;
$dpPreis        = $row->dpPreis;
}

// Variable der HG feststellen
$abfrage   = "SELECT aHauptgruppe, aKursArt FROM Artikel WHERE aID = " . $dpAID;
$ergebnis  = mysqli_query($db, $abfrage) or die ('hg:' . mysqli_error($db));
while($row = mysqli_fetch_object($ergebnis))
{
$aHauptgruppe = $row->aHauptgruppe;
$aKursArt     = $row->aKursArt;
}

// Variablen für korrekten Text
if($aKursArt=='Ausbildung'){$Wort='zur ';}else{$Wort='zum ';}
if($aKursArt!=''){$TitelZusatz=$aKursArt . ": ";}

// PDF AUSGABE =============================================================
require('fpdf.php');

$pdf=new FPDF('P', 'mm', 'A4');
$pdf->SetMargins(20,10,15);
$pdf->AddPage();

// Logo ------------------------------------
$pdf->Image('intern/logo.png', 20, 10, 18);

// Titelzeile ------------------------------
$pdf->SetFont('Arial','',12);
$pdf->Cell(0,6,html_entity_decode($dtxtREtitel),0,1,R);

$pdf->SetFontSize(9);
$pdf->Cell(0,6,html_entity_decode($dtxtREslogan),0,1,R);
$pdf->Ln(12);

// Dokument-Art ----------------------------
$pdf->SetFont('Arial','B',13);
$pdf->Cell(0,4,$dArt,0,1,R);
$pdf->Ln(6);

// Dokument-Informationen ------------------
$pdf->SetFont('Arial','',8.5);
$YvorInfo = $pdf->GetY();
$InfoBlock = html_entity_decode($_GET['dID'] . "\n" . date('d.m.y',strtotime($dDatum)) . "\n" . $_GET['mID'] . "\n" . $dReferenz . "\n\n" . $dtxtREadrbank);
$pdf->MultiCell(0,4,$InfoBlock,0,'R');
$pdf->Ln(6);
$YnachInfo = $pdf->GetY();

// Dokument-Information Bezeichner ---------
$pdf->SetY($YvorInfo);
$pdf->Cell(160,4,"Dokumentnummer :",0,1,'R');
$pdf->Cell(160,4,"Datum :",0,1,'R');
$pdf->Cell(160,4,"Kundennummer :",0,1,'R');
$pdf->Cell(160,4,"Referenz :",0,1,'R');

// Adresse ---------------------------------
$AdrName = $mVorname . " " . $mName;
$AdrStrasse = $mStrasse;
$AdrOrt = $mPLZ . " " . $mOrt;

$pdf->SetFontSize(9);
$pdf->SetXY(20,$YvorInfo);
$pdf->SetY(55);
if($mFirma <> "")
{
$pdf->Cell(85,4,html_entity_decode($mFirma),0,1);
$pdf->Cell(85,4,html_entity_decode($mFirmenslogan),0,1);
}
$pdf->Cell(85,4,html_entity_decode($AdrName),0,1);
$pdf->Cell(85,4,html_entity_decode($AdrStrasse),0,1);
$pdf->Cell(85,4,$mPostfach,0,1);
$pdf->Cell(85,4,html_entity_decode($AdrOrt),0,1);

$pdf->SetY($YnachInfo);

// Betreff ---------------------------------
$pdf->SetFont('Arial','B',11);
$pdf->Cell(0,4,html_entity_decode($TitelZusatz . $dTitel),0,1,'R');
$pdf->Ln(5);

// Positionen ------------------------------
$pdf->SetFont('Arial','',9);
$abfrage = "SELECT * FROM DokumentPosition WHERE dpDokNr = " . $_GET['dID'] . " ORDER BY dpReihenfolge";
$ergebnis = mysqli_query($db, $abfrage);

// Notiz vor Positionen -------------------
if($dNotizVor <> "")
{
$pdf->MultiCell(0,4,$dNotizVor,0);
$pdf->Ln(4);
}

// Positionen -----------------------------
$pdf->SetFont('Arial','B',9);

$pdf->Cell(10,5,"ID",0,0);
$pdf->Cell(110,5,"Name",0,0);
$pdf->Cell(20,5,"Preis",0,0,'R');
$pdf->Cell(15,5,"Anzahl",0,0,'R');
$pdf->Cell(20,5,"Gesamt",0,1,'R');
$pdf->Cell(0,4,'',T,1);

$pdf->SetFont('Arial','',9);

while($row = mysqli_fetch_object($ergebnis))
{
$dpAID = $row->dpAID;
$dpName = html_entity_decode($row->dpName);
$dpEinzelpreis = $row->dpEinzelpreis;
$dpAnzahl = $row->dpAnzahl;
$dpPreis = $row->dpPreis;

$pdf->SetDrawColor(255,255,255);
$pdf->Cell(0,1,'','B',1);
$pdf->SetFillColor(245,245,245);

$pdf->Cell(10,5,number_format($row->dpAID,0,"",""),'R',0,'',1);
$pdf->Cell(110,5,html_entity_decode($TitelZusatz . $dpName),'R',0,'',1);
$pdf->Cell(20,5,number_format($row->dpEinzelpreis,2,".","'"),'R',0,'R',1);
$pdf->Cell(15,5,number_format($row->dpAnzahl,2,".","'"),'R',0,'R',1);
$pdf->Cell(20,5,number_format($row->dpPreis,2,".","'"),0,1,'R',1);
}

$ergebnis2 = mysqli_query($db,"SELECT mRabatt FROM Mensch WHERE mID = " . $_GET['mID']);
while($row = mysqli_fetch_object($ergebnis2)){
  $mRabatt = $row->mRabatt;
  $RabattBetrag = $mRabatt * $dEndbetrag / 100;
  $RabattBetrag = $RabattBetrag - ($RabattBetrag * 2);
}
if($mRabatt >= 1)
{
$pdf->Cell(10,5,'','R',0,'',1);
$pdf->Cell(110,5,html_entity_decode('Wiederverkäuferrabatt'),'R',0,'',1);
$pdf->Cell(20,5,number_format($mRabatt,0,".","'"),'R',0,'R',1);
$pdf->Cell(15,5,'%',2,".","'",'R',0,'R',1);
$pdf->Cell(20,5,number_format($RabattBetrag,2,".","'"),0,1,'R',1);
$dEndbetrag = $dEndbetrag - $RabattBetrag;
}

// Total -----------------------------------
$pdf->SetDrawColor(0,0,0);

$pdf->Cell(0,4,'',B,1);
$pdf->SetX(-50);
$pdf->Cell(15,5,'Total:',0,0,'R');
$pdf->SetFont('Arial','B',9);
$pdf->Cell(20,5,number_format($dEndbetrag,2,".","'"),0,1,'R');
$pdf->Ln(4);

$pdf->SetFont('Arial','',9);

// Notiz nach Positionen -------------------
if($dNotizNach <> "")
{
$pdf->MultiCell(0,4,html_entity_decode($dNotizNach),0);
$pdf->Ln(8);
}

// Annullationstext ------------------------
if($aHauptgruppe!=15 and $aHauptgruppe!=17){
$pdf->MultiCell(0,4,html_entity_decode($dtxtREnFusszeile),0,1);
$pdf->Ln(8);
}

if($aHauptgruppe==15){
$pdf->MultiCell(0,4,html_entity_decode($dtxtREkAnnullation),0,1);
$pdf->Ln(8);
$pdf->MultiCell(0,4,html_entity_decode($dtxtREkFusszeile),0,1);
$pdf->Ln(8);
}
if($aHauptgruppe==17){
$pdf->MultiCell(0,4,html_entity_decode($dtxtREaAnnullation),0,1);
$pdf->Ln(8);
$pdf->MultiCell(0,4,html_entity_decode($dtxtREaFusszeile),0,1);
$pdf->Ln(8);
}
// Solange keine LS und GS benötigt werden, lass ich es mal bei RE beruhen. ;-)
$DokNameID = "RE";

// PDF abschliessen und speichern ----------
ob_clean();
flush();
$DokName = $DokNameID . "-" . $_GET['dID'] . "-" . $dDatum . "-" . $mName . "_" . $mVorname . ".pdf";
$pdf->Output($DokName,'I');
?>
tomatensalat
 
Posts: 5
Joined: 01. April 2020 04:42
XAMPP version: 7.4.2-0
Operating System: Manjaro 19.0.2 Kyria

Re: FPDF Fatal error

Postby Nobbie » 01. April 2020 17:45

tomatensalat wrote:In der Fpdf-Dokumentation habe ich (noch) nichts über Variablenübergaben gefunden. Oder funktioniert dies einzig über $_POST? Gibt es eine korrektere oder einfache Art Variablen in fpdf selbst zu definieren/verwenden? :wink: ... oder wie wird das korrekt gemacht?


Ich verstehe noch nicht einmal die Frage, so chaotisch ist das...

FPDF hat mit $_POST oder $_GET oder irgendwelchen Variablen gar nichts zu tun. Die Darstellung von Variablenwerten erfolgt ja beispielsweise im Aufruf der Methode "cell" der Klasse pdf:

Code: Select all
$pdf->Cell(85,4,html_entity_decode($mFirma),0,1);


Da wird beispielsweise der Inhalt der Variablen $mFirma an eine Zelle im PDF Dokument übertragen. Und der Inhalt von $mFormat ist weiter oben durch einen Select auf eine Tabelle bereit gestellt worden. Mehr gibt es da nicht.

Ob Du oben dann $_GET oder $_POST benutzt, das hängt davon ab, wie denn die Variablen an dieses Script übergeben werden. $_POST ist typischerweise das Resultat aus einem Formular mit entsprechenden Eingabefeldern, $_GET wird normalerweise direkt vom Anwender in der URL des Browsers angegeben. Das sieht dann ungefähr so aus, nennen wir Dein Script "test.php" (es wird anders heißen, aber ich weiß es nicht):

Code: Select all
http://localhost/test.php?mID=5&dID=17


Da werden die Variablen mID und dID durch die URL bestückt und die werden im Script durch $_GET['mID'] und $_GET['dID'] abgefragt.

tomatensalat wrote:obwohl ich mich nun wohl definitiv als 'Bastler' oute!


Sind wir ehrlich - selbst das ist noch gestratzt. Das Script hat Dir irgendjemand zusammengeschustert und Du weißt nicht wo vorne und hinten ist?! Wahrscheinlich hast Du das Script ohne jegliche Eingabe von Parametern gestartet, dadurch meldet Apache bei den Variablen $_GET[...] dass sie leer sind - und diese Fehlermeldung lässt nachher FPDF abstürzen. Auf dem Server ist Apache/PHP wahrscheinlich so eingestellt, dass die entsprechenden Warnungen (es sind eigentlich keine Fehler, nur Warnungen), dass $_GET keine Werte hat, abgeklemmt. Oder es wird richtig gestartet mit richtiger URL oder richtigem Formular und das fehlt vielleicht lokal. Ich weiß es nicht. Kommt ja nur bröckchenweise hier an.

Etwas chaotisch ist übrigens jeweils der "while-Loop" um die mysql Fetch Anweisungen und die darin stehende Zuweisung der Resultate an immer wieder der gleichen globalen Variablen. Wahrscheinlich liefert der Select sowieso nur einen einzigen Treffer, denn es überlebt nur der jeweils letzte Treffer, alle Vorgänger werden überklatscht.
Nobbie
 
Posts: 11565
Joined: 09. March 2008 13:04

Re: FPDF Fatal error

Postby tomatensalat » 02. April 2020 18:37

Danke Nobbie. Da hat mich ein Profi jetzt aber ganz schön vor Tatsachen gestellt. ;-) Nun, ich habe das Script natürlich selbst erstellt bzw. mit Deinen Worten ausgedrückt, zusammengeschustert. Ich weiss zwar was jede Zeile macht, doch es ist mir bewusst das ein Profi das mit garantierter Sicherheit korrekter lösen würde. Dennoch, es funktioniert einwandfrei - auch wenn mehrere Dokumentpositionen vorhanden sind. Ich denke ich habe meine Frage offensichtlich nicht verständlich gestellt. Diesmal helfen mir Deine Ausführen nicht, da ich weiss was Du beschreibst - ich werde mir die Fehler/Warnungen, wie auch Deine davor wertvollen Hinweise, nochmals zur Brust nehmen. Im Augenblick bin ich natürlich froh, dass unser Server mein Unwissen etwas kaschiert. Danke Nobbie für Deine Zeit.
tomatensalat
 
Posts: 5
Joined: 01. April 2020 04:42
XAMPP version: 7.4.2-0
Operating System: Manjaro 19.0.2 Kyria

Re: FPDF Fatal error

Postby Nobbie » 02. April 2020 19:34

tomatensalat wrote:Dennoch, es funktioniert einwandfrei


Und wie versorgst Du die Variablen $_GET und/oder $_POST? Das hast Du uns immer noch nicht gezeigt und das ist wahrscheinlich genau die Stelle, wo es "knackt".
Nobbie
 
Posts: 11565
Joined: 09. March 2008 13:04


Return to XAMPP für Linux

Who is online

Users browsing this forum: No registered users and 1 guest