PHP/HTML: Visa bild när headern redan körts/skickats ?

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

PHP/HTML: Visa bild när headern redan körts/skickats ?

Inlägg av JimmyAndersson »

Jag använder Baachart för att skapa ett diagram på en sida. Jag har använt exempel-koden för linjediagrammet.

Koden för sidan är uppbyggd såhär:
1. PHP-del för att hämta data från en MySQL-databas mm.
2. HTML-del för att göra tabeller, knappar mm. (Se här.)

OBS: Diagrammet i länken är bara en bild för att se var diagrammet ska placeras. BaaChart har alltså inte genererat diagrammet på den sidan.


Lägger jag in koden för baachart (och särskillt $mygraph->drawGraph(diagram.png) ) innan HTML-delen börjar så visas diagrammet, men inte i den tabellcell jag vill. Dessutom så visas *enbart* diagrammet, inget annat på sidan.

Om jag däremot lägger in <?php $mygraph->drawGraph(diagram.png) ?> i en tabell (oavsett om resten av baachart ligger innan <HTML> eller i tabellen) så visas knappar mm, som på skärmdumpen, men där diagrammet ska visas syns istället:

Kod: Markera allt

Warning: Cannot modify header information -
headers already sent by (output started at stat_home.php:238)
in stat_home.php on line 276

Warning: Cannot modify header information -
headers already sent by (output started at stat_home.php:238)
in baaChart.php on line 237
‰PNG  IHDRXsÕ;‡†9PLTEÿÿÿZZZÿÿÿÿÿÿÿÿÿ̙™fÌfffÌÿfffffÝÝÝîîîÿÿÿÿÿÿ™£f±t
RNS@æØf 4IDATxœíÝÛr£8Fan:WSšyÿ§ ÍAbۀÄÏ뛩ˆÝtÌj£8€†Àã…
‰úïþ\«Š&±ƒ°
osv liknande png-rådata..   :-)


Google berättade att jag inte var ensam om att ha upptäckt detta.
Här hade något fått detta förslag som lösning:


I can only guess that line 9 is where you call

chart->display()

This method has a call to

header(("Content-Type: image/png");




Men jag förstår inte riktigt hur man gör det... Letade på php.net och kom fram till denna smått chansartade lösningen:

<?php
header("Content-Type: image/png");
$mygraph->drawGraph(diagram.png);
?>

Men det gjorde ingen skillnad.
Så hur gör man för att lösa det på rätt sätt? :)

Kortfattat så har jag förstått problemet som att jag vill generera och visa en bild efter att headern har "körts".



Slutligen en liten förklaring till vad jag pysslar med:

Data från mitt 1wire-nät sparas i en databas. På statistik-sidan (skärmdumpen) kan man välja vilka sensorers värden som ska visas i diagrammet och vad X/Y-axlarna ska visa. Man gör sina val och trycker Spara-knappen. Då ritas diagrammet (och resten av sidan) om. Det där sista finns bara i teorin pga problemet ovan..

Att det är lite glest vid Spara-knappen och att jag valt att ha den här strukturen i inmatningsfälten beror på "planerad utrymmesbrist". :) Det kommer dyka upp fler saker på den sidan senare.
Användarvisningsbild
AndLi
Inlägg: 18118
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Inlägg av AndLi »

Det finns ett php kommando som heter något i stil med delay header, eller möjligeh cache header.

Detta gör att headern inte skickas förrän du säger åt den att göra det!

edit: det kan vara session_start() med kompisar som jag använde när jag hade samma problem.
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

Du försöker väl inte lägga in en bild inbäddad i HTML? Du måste ju göra en länk i HTML till en bild som genereras av PHP.

index.html:

Kod: Markera allt

<table><tr><td>Diagram: <img src="diagram.php">></td></tr></table>
diagram.php:

Kod: Markera allt

<?php $mygraph->drawGraph(diagram.png) ?>
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

"Du försöker väl inte lägga in en bild inbäddad i HTML?"

Vet inte riktigt hur du menar, men BaaChart genererar bilden diagram.png
Den försöker jag sedan visa i HTML-delen.

En snabbgenomgång av koden för hela sidan:

Kod: Markera allt

<?php
// Hämta inställningsdata från databasen.
// Bl.a vilka kryssrutor som ska vara ikryssade.

// Förbered diagrammet.
include('baaChart.php');
$mygraph = new baaChart(600);
osv..
?>

<html>
<head> metagrejjer, läs in css-filen </head>
<body>
<table.... en lång samling kod som bygger upp tabell-strukturen.
<form... Formuläret med kryssrutor och sånt.. .

<table.... Ännu en tabell och här hittar vi bl.a:

<td align="center" valign="middle">
<?php $mygraph->drawGraph(diagram.png); ?>
<img src=visa_diagram.php width=600 height=371>
</td>

osv..
</body></html>


Jag testade att göra som du skriver, men istället för diagrammet visades ett rött kryss. = Bilden saknas.

Är det enbart det du visar som ska vara i diagram.php ?
(Förutom att du glömde ett semikolon :) )
Index.html borde vara filen med min kod ovan (plus din ändring i img-taggen) eller hur?
Bara kollar så jag inte har förstått fel. :)


AndLi:
Testade med bl.a session_start() men jag fick samma resultat ändå, oavsett var jag placerade den raden.
discomike
Inlägg: 445
Blev medlem: 22 juli 2007, 11:34:13
Ort: Göteborg

Inlägg av discomike »

speakman har rätt

du måste include:a baaChart.php å det i diagram.php filen med, å ev. databaskopplingar du gör för å hämta datan


(fyi, IE stödjer base64 encodeade embeddade bilder faktiskt men det är inget värt å använda)
bos
Inlägg: 2308
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Inlägg av bos »

JimmyAndersson skrev: <?php $mygraph->drawGraph(diagram.png); ?>
<img src=visa_diagram.php width=600 height=371>
Det här ser väldigt konstigt ut. Om drawGraph() ger dig en png-fil (alltså binärdata), så kommer detta att komma ut i html-koden, precis som skrivits innan.

Rad två ovan är korrekt tillvägagångssätt, under förutsättning att visa_diagram.php spottar ut en bild (binärdata) och korrekta headers.

På nåt sätt har du nog alltså fått in en bild som inline-html - och det vill du inte - vilket rent gissningsvis är det som är orsaken till dina problem.
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

discomike:
Hur löser man isåfall databaskopplingarna mm mellan de båda php-filerna?
(dvs filen med $mygraph->drawGraph(diagram.png) och filen med resten av sidan.)

Ett exempel:

Låt säga att huvudsidan (stat_home.php) har denna rad:
$xyz = "hej";

och diagram.php har denna rad:
if ($xyz == "hej") {do something..}


"do something" kommer ju aldrig att utföras eftesom det inte finns någon "koppling" mellan php-filerna. Jag vill inte ha hela databas-läsningen i diagram.php eftersom jag även använder resultatet av databas-läsningen till andra delar i stat_home.php och det är inte alltid som diagrammet ska visas, dvs då kommer inte databas-delen köras alls.....


Har letat på Google och php.net , men det är inte så lätt att hitta något när man inte vet namnet på det man söker.

edit: Såg att det dök upp ett till inlägg strax innan jag postade.

edit 2: Bos: Prexis. Det gäller bara att komma på hur man löser det. :)
Senast redigerad av JimmyAndersson 25 mars 2008, 22:47:41, redigerad totalt 1 gång.
bos
Inlägg: 2308
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Inlägg av bos »

Databaskoppel är persistenta i PHP5 (kanske 4 också), såvida du inte angett annat. Annars är det inte svårt ordnat med en global db-fil, där själva kopplet nås från alla funktioner som kör include() på filen.

Dvs:

(db.inc)

$db = open_database_connection(....)

(fil1.php)

require("db.inc");
echo db_query($db, "select * from foo");


Oavsett hur många gånger du inklucerar db-filen så får du ändå bara ett koppel (tack vare persistensen), så det är ingen risk att du gör slut på resurser.
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Nu förstår jag inte..
Innebär ditt förslag att jag får en koppling mellan php-filerna som om det var en och samma php-fil?

Dvs kan jag då göra det jag skrev i förra inlägget:

Låt säga att huvudsidan (stat_home.php) har denna rad:
$xyz = "hej";

och diagram.php har denna rad:
if ($xyz == "hej") {do something..}



Sedan förstår jag inte riktigt vilken php-fil som ska inkludera db.inc
Huvudsidan (stat_home.php , som skärmdumpen visar) eller diagram.php ..eller båda?

Ni skriver lite för kortfattade inlägg... :wink:
bos
Inlägg: 2308
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Inlägg av bos »

Kod: Markera allt

bos@bos:$ cat diagram.php 
<?php
include("stat_home.php");

if ($xyz == "hej") { echo "Hej!"; } 
?>
bos@bos:$ cat stat_home.php 
<?php
$xyz = "hej";
?>
Och sen:

Kod: Markera allt

bos@bos:$ php diagram.php 
Hej!
Svaret är alltså ja. Det kräver dock lite extra arbete med att ha mycket kod i funktioner, för om du har t.ex "echo hejsan" utanför en funktion, så kommer du få ett "hejsan" utskrivet för varje php-fil som inkluderar den.

Gällande vilken fil som ska inkludera vad; den fil som använder databasfunktioner ska inkludera db.inc. Används inte databasfunktioner, strunta i inkludering.

Jag rekommenderar att du läser i php-manualen om include(), include_once(), require() och require_once(). Dessa fyra är vitala när det gäller att skriva modulär kod som anropar / använder funktioner i andra filer.
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Tack för det snabba svaret. :)

Nu hänger jag med på hur du menar.
Men det återstår "lite" grubbel kring hur jag ska göra om min kod....


Låt säga att databas.php innehåller läsning/skrivning av databasen, då blir det såhär:

1) stat_home.php inkluderar databas.php och ställer in kryssrutors check-flagga så de är inställda som man sparade sist.
2) stat_home.php förbereder visning av diagrammet genom att inkludera diagram.php
3) diagram.php inkluderar databas.php för att läsa in vad diagrammet ska visa.

Men som du skrev:
om du har t.ex "echo hejsan" utanför en funktion, så kommer du få ett "hejsan" utskrivet för varje php-fil som inkluderar den.

Så när diagram.php inkluderar databas.php så kommer det även köras kod som bara stat_home.php har nytta av. Det går iofs att ha massa flaggor/variabler som håller koll på vad som ska köras, men .. det låter väldigt rörigt bara för att visa ett diagram.

Ska läsa php-manualen, men det vore bra om det fanns ett annat sätt att visa diagrammet.

Hmmm..... :humm:



edit: 007sweden gav mig en lysande bra och enkel lösning.
Klippt direkt från chatten:

23:51:43] >> ha get-taggar?
[23:52:00] << Det var ingen dum idé
[23:52:03] >> bild.php?grejj1=hej&grejj2=hejigen
[23:52:31] >> och sen $_GET["grejj1"]; i phpscriptet


Smidigare än så blir det inte. :)
bos
Inlägg: 2308
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Inlägg av bos »

I databas.php räcker det att ha en variabel som kopplas till databasen. I mina program har jag såhär:

Kod: Markera allt

$dbhost = "''";
$dbname = "dbname";
$dbuser = "myuser";
$dbpass = "mypassword";
$connect_params = "host=$dbhost dbname=$dbname user=$dbuser password=$dbpass";

$db = pg_connect($connect_params) or DB_error("Can't connect to database.");
Mer än så behövs inte där. $db kommer då bli ett globalt koppel för alla filer som inkluderar databas.php. Är det så att du behöver ytterligare db-saker som används här och var så gör du dem som funktioner.

Exempel hur jag använder min databas.php:

Kod: Markera allt

require("databas.php");

$q = "SELECT name FROM users WHERE username='$u';";
$r = pg_query($db, $q) or die("Ledsen error.");
$x = pg_fetch_object($r);
$n = $x->name;

echo "Du är inloggad som $n (<a href=\"?ut\">Logga ut</a>)";

Som synes använder jag PostgreSQL istället för MySQL, men principen är exakt samma.
discomike
Inlägg: 445
Blev medlem: 22 juli 2007, 11:34:13
Ort: Göteborg

Inlägg av discomike »

ja.

och om du bara vill passa lite enkla variabler som "hej" mellan sidorna kan du använda sessions-variabler

session_start();
$_SESSION['vemebäst'] = "discomike";

.......................................

session_start();
echo $_SESSION['vemebäst'];
Skriv svar