ServerSideInclude-problem (ordningen) - headers sent osv.

Tråden skapades och har fått 8 svar. Det senaste inlägget skrevs .
1
  • Medlem
  • Stockholm
  • 2003-11-22 23:02

Hej!

För nuvarande så har jag en lösning som ser ut ungefär så här:

html_header();
	require($_GET['goto']);
html_footer();

function html_header() {
    ?>
    <html>
    <head>
    <title><?php echo $title; ?></title>
    </head>
    <body>
    <?php
}

function html_footer() {
?>
	</body>
	</html>
	<?php
}

mitt problem är att $title hämtas i det dokument som man inkluderar med require() och dessvärre skrivs $title i html_header() innan värdet från filen lästs in.

Jag önskar ha en lösning som gör att man
1. först laddar in filen (require) och sen skriver ut sidan som ska visas. Dvs vidinloggning/utloggning så skrivs menyer med mera ut först efter inloggning/utloggning skett
2. $title ska hämtas in från filen man inkluderar och skrivas in i sidans <title>-tag.
3. i de inkluderade filerna kan skicka vidare klienten med tex header("Location: start.php");. I dagsläget så klagar den på att headers already sent. vilket är så sant...

Någon som har tips?

mvh
ivar

Jag är inte säker på att jag förstått ditt problem helt rätt, men om du ska skicka en header-location så måste det vara det allra första du skriver ut i din kod, du får inte ens skicka ett mellanslag till användaren före det.

Förövrigt är SSI, Server Side Includes, något helt annat.

Du kan nog använda output-buffering för att göra det du vill. Kolla på följande fnktioner:

ob_start();
ob_end_flush();

De går att läsa om på:

http://se.php.net/manual/en/ref.outcontrol.php

Annars är templates ett smidigt sätt att göra det du vill. Ingen sida förutom den man går till skickar html till användaren, de inkluderade sidorna bara returnerar text till sidan som inkluderar dem så att sidan som inkluderar alltsammans kan välja när saker och ting ska skrivas ut vilket förslagsvis sker absolut sist så att du har möjlighet att göra det du vill dvs. vidarebefodra användare med header('location: annan_sida.html');

  • Medlem
  • Stockholm
  • 2003-11-23 11:19
Citat:

Skrevs ursprungligen av Adrian B
Jag är inte säker på att jag förstått ditt problem helt rätt, men om du ska skicka en header-location så måste det vara det allra första du skriver ut i din kod, du får inte ens skicka ett mellanslag till användaren före det.

Förövrigt är SSI, Server Side Includes, något helt annat.

Precis, du förstod inte mitt problem. headers måste skickas innan output till användaren sker men det ärinte samma sak som att det måste vara det allra första man skriver i sin kod (misstänker att du vet det men formulerade dig otydligt).
SSI (Server Side Includes) antog jag var när jag i min index.php inkluderade filer (vilket sker på server-sidan såklart).

Citat:

Skrevs ursprungligen av Gabriel Falkenberg
Du kan nog använda output-buffering för att göra det du vill. Kolla på följande fnktioner:

ob_start();
ob_end_flush();

De går att läsa om på:

http://se.php.net/manual/en/ref.outcontrol.php

Annars är templates ett smidigt sätt att göra det du vill. Ingen sida förutom den man går till skickar html till användaren, de inkluderade sidorna bara returnerar text till sidan som inkluderar dem så att sidan som inkluderar alltsammans kan välja när saker och ting ska skrivas ut vilket förslagsvis sker absolut sist så att du har möjlighet att göra det du vill dvs. vidarebefodra användare med header('location: annan_sida.html');

Tackar. Tror ocså att det kan vara lösningen. Har suttit och läst hela morgonen om det (sitter på jobbet) så det blir till att prova när jag kommer hem.
Det är ju en template-lösning jag kör. Bara det att filerna som inkluderas inte är vanlig text utan det är dynamiska sidor(mer php). Till exempel så laddas menyn på sidan in INNAN jag laddar in det sökta dokumentet...

Tex skulle

index.php?goto=logout

leda till att man i index.php skriver ut html_header() sen så inkluderar man menyn och i samma veva skrivs menyn ut och slutligen inkluderas filen logout(.php) som känner av vem man är inloggad som och uppdaterar databasen och nollställer lite värden (vilket innebär att en annan slags meny ska skrivas ut eftersom man inte längre är inloggad).

require("meny.php");
html_header();
meny(); //funtionen ligger i det inkluderade meny.php
// meny() skriver ut en meny som är olika för vem man är inloggad som
// och ja, menyn måste srivas ut först  
require($_GET['goto']); // tex require("logout.php") som resulterar i att en utloggning ser.
html_footer();

Exemplet ovan resulterar i att menyn för en inloggad person skrivs ut och sen loggas man ut.
Självklart ska man loggas ut först och sen skrivs menyn ut.

Jag ska som sagt prova ob_start() när jag kommer hem. Hoppas det löser mitt problem.

Löser ju defenitivt problemet med header("Location: ")
vilket får mig att tänka på att mitt problem går att lösa genom att i logout.php och login.php avsluta med just en header("Location:").

Tror som sagt output buffer control grejjar biffen men är det någon som har andra förslag?

Citat:

Skrevs ursprungligen av ivar
Precis, du förstod inte mitt problem.

Hade det på känn...

Citat:

Skrevs ursprungligen av ivar
headers måste skickas innan output till användaren sker men det ärinte samma sak som att det måste vara det allra första man skriver i sin kod (misstänker att du vet det men formulerade dig otydligt).

Jo, jag vet, jag skrev ju att headern är det första man "skriver ut", dvs inte det första man skriver i sin kod utan det som kommer ut av koden (vilket inte var tillräckligt tydligt som sagt).

Citat:

Skrevs ursprungligen av ivar
SSI (Server Side Includes) antog jag var när jag i min index.php inkluderade filer (vilket sker på server-sidan såklart).

Ah, well det är fel. SSI är en teknik som fanns före PHP och som användes för att göra precis samma sak som du tänker på, dvs inkludera andra filer på serversidan. Om du nån gång surfat och hamnat på sidor som slutar med .shtml så brukar det betyda att de använder sig av SSI. Man kunde bygga en hel del smarta funktioner med SSI, men när PHP kom var det ju ungefär en miljon gånger bättre så numera lever nog SSI en rätt tynande tillvaro...

Men allt detta snack löser ju inte ditt problem, förstås. Dock tror jag att jag inte förstår problemet ännu, framförallt inte varför du måste skriva ut menyn först...

  • Medlem
  • Stockholm
  • 2003-11-23 13:52

Hihi, okej.

Jag tar och postar ett ordentligt inlägg när jag kommer hem (om ett litet slag) med screenshot och ett sista försök till varför menyn skrivs ut före huvudinnehållet på sidan

hörs snart igen

  • Medlem
  • Stockholm
  • 2003-11-23 15:04

nevermind.. problemet löstes med ob_start och ob_flush

anledningen till att menyn skrivs ut först är att det är i den ordningen som sidan byggs upp.
Ungefär så här:

<?php html_header(); ?><table>
<tr><td><?php require("meny.php"); ?> </td></tr>
<tr><td><?php require("logout.php"); ?></td></tr>
</table>
<?php html_footer(); ?>

då så hämtas (och skrivs) menyn först och sen körs koden i logout där man loggas ut.

Dock när man trycker på logout.php ska ju menyn ändras och visa "login".

Problemet är löst och tack för hjälpen.

Det skulle vara schysst om du kunde posta och beskriva lite mer i detalj hur du gjorde, har aldrig använt output-buffering själv så det skulle vara intrerssant att se hur du använde det.

  • Medlem
  • Stockholm
  • 2003-11-23 17:56

Javisst, självklart.

Jag läste en artikel på devshed [/ServerSide/PHP] där det framgick att det fanns fler fördelar än att bara låta sin sida processa och att börja utskrift efter allt laddats in.

Man kan använda bufferten för att ladda in allt som ska skrivas ut på sidan och sedan komprimera detta och skicka och på så vis minska nätverkstrafiken. Vet inte exakt vilka webläsare som stödjer tekniken (de flesta?). Inga problem uppstår dock om webläsaren inte stödjer tekniken på PHP känner av det och låter bli att komprimera.

Jag använder mig av en index.php som i sin tur inkluderar allt som ska visas på sidan
Min index.php fick högst upp det här tillagt:

ini_set("zlib.output_compression_level", 3);
ob_start("ob_gzhandler");

och längst längst ner på sidan skrev jag in

ob_flush();

att skicka headers fungerar nu finfint dock så lyckas jag inte sätta variabeln $title så den skrivs ut korrekt.

Jag måste ju skriva ut html_header() först, sen innehållet på sidan, dvs require($fil) , och sen skriver jag ut html_footer()... i html_header() så används variabeln $title för att sätta hemsidans rubrikrad/titelrad men variabeln hämtas in från dokumentet som require'as ... hur går man runt detta? jag kan inte require'a dokumentet innan html_header för då hamnar det ju i fel ordning (dvs först skriv huvudinnehållet på sidan ut, sen html_header() )

1
Bevaka tråden