Avatar billede bars Nybegynder
23. oktober 2003 - 12:09 Der er 27 kommentarer og
1 løsning

Problemer med header funktion

Har lavet en hjemmeside hvor top og bund bliver lagt ind som require-filer.

I selve indholdsdelen har jeg en gang imellem brug for at kunne redirecte brugeren til samme eller en anden side.

header("Location: side.php");

Problemet i dette er bare at jeg i min top.php begynder at sende header-information og det derfor ligger i min cache når jeg vil redirecte og når så ikke ved hvad den skal gøre med dette, kommer der en fejlmeddelse.

Hvordan kommer jeg uden om dette problem?
Avatar billede bars Nybegynder
23. oktober 2003 - 12:12 #1
Fejlmeddelsen lyder:
Warning: Cannot modify header information - headers already sent by (output started at /home/testmig.dk/public_html/daterting/top.php:5) in /home/testmig.dk/public_html/daterting/deletePost.php on line 17
Avatar billede amix Nybegynder
23. oktober 2003 - 12:14 #2
Hmm du skal være påpasselig med at sende headers. Du kan ikke sende 2 headers - så kommer den med en fejlmeddelse.

Så dvs. du skal optimere koden således den kun sender 1 header pr gang.
Avatar billede amix Nybegynder
23. oktober 2003 - 12:15 #3
Det er fordi du sender 2 eller flere headers til serveren...

Hmm hvorfor sætter du headers i top.php??
Avatar billede bars Nybegynder
23. oktober 2003 - 12:19 #4
amix >> Jeg har kun én header. Problemet er at der bliver gemt noget "cache" i top-filen. Og når jeg så beder den om at redirecte ved den ikke hvad den skal gøre ved det gemte.

Findes der en anden funktion, eller noget der kan nulstille cachen ?
Avatar billede amix Nybegynder
23. oktober 2003 - 12:20 #5
Ja du kan godt slette cachen... men hvad er det for noget cache som gemmes i top-filen? Kunne du muligvis poste koden?
Avatar billede bars Nybegynder
23. oktober 2003 - 12:21 #6
amix >> Sætter jo sidens titel og henter f.eks. også et flash banner, i top.php - hvilket jo bliver forstået som en header information.
Avatar billede amix Nybegynder
23. oktober 2003 - 12:26 #7
Uhm hvorfor gøre den det?? Det burde den da ikke gøre...
Post lige koden i top.php omkring linie 5 og deletePost.php omkring linie 17
Avatar billede exp Juniormester
23. oktober 2003 - 12:29 #8
Der findes en løsning, men den er kun for folk der:
1. ikke har struktureret deres indhold ordentligt
2. er for dovne til at rette ovenstående
3. lader hånt om sikkerheden
Avatar billede fangel Nybegynder
23. oktober 2003 - 12:36 #9
alle kald til headers SKAL laves før NOGET output - selv så lidt som et ' ' (blank space) og du får den fejl!

derfor skal du strukture dit script således at alle header kald (header(), cookie(), session_start() og lignene) kommer før alt output! sådan er det bare - det må man leve med

---

'hack' løsningen er output-buffering, men til 'små' projekter er dette overkill (skyde spurve med kanoner) - brug kun output-buffering hvis du kombinere det med fx error-handling (og det tvivler jeg på du vil)

Morten
Avatar billede bars Nybegynder
23. oktober 2003 - 12:41 #10
Linie 5 i top.php:
<script language="JavaScript" src="valider.js"></script>

Linie 17 i deletePost.php:
header("location: index.php");
Avatar billede amix Nybegynder
23. oktober 2003 - 12:47 #11
Hmm du har et eller andet i valider.js som sender en header til serveren - og dette er ikke specielt smart.
Avatar billede bars Nybegynder
23. oktober 2003 - 12:59 #12
Jamen kan det virkelig passe at man slet ikke i php kan sende brugeren hen til en anden side bare fordi jeg har er begyndt at hente noget af den første side?
Avatar billede amix Nybegynder
23. oktober 2003 - 13:20 #13
Uhm det er netop problemet - serveren kan kun tage imod en header.

Altså det er ligesom hvis du først bruger header("location: index.php"); og dernæst prøver at sætte en cookie - - - det går bare ikke!
Avatar billede jensgram Nybegynder
23. oktober 2003 - 13:21 #14
bars > Ja, du må over i JavaScript for at gøre det!

Brug evt. dette:

    function SmartLoad($getVarString = '', $loadUri= '')
    {
        if (strlen($loadUri) > 0) { // Did the user want to load another page?
            $location = $loadUri; // Set the URI to be loaded to the one passed by the user ($getVarString is ignored)
        } else {
            $location = 'http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']); // Set the URI to be loaded to the absolute URI of the current page
            if (strlen($_SERVER['QUERY_STRING']) > 0) { // Is there any GET-vars?
                $location .= '?' . $_SERVER['QUERY_STRING']; // If yes - include GET-vars
            }
            if (strlen($getVarString) > 0 && strlen($_SERVER['QUERY_STRING']) > 0) { // Did the user want to add GET-vars?
                $location .= '&' . $getVarString; // Concatenate with en ampersand if there were already GET-vars
            } elseif (strlen($getVarString) > 0) {
                $location .= '?' . $getVarString; // Concatenate with a question mark if not
            }
        }
        if (headers_sent() != false) { // Is any output sent to the client?
            print "\n\n<script language=\"javascript\" type=\"text/javascript\">\n// <![CDATA[\n\tdocument.location.href = \"" . addslashes($location) . "\"; // Load new URI\n// ]]>\n</script>\n\n"; // If yes - load the page with JavaScript (this does not close <html>-tags etc...)
        } else {
            header('Location: ' . $location); // If no output is sent, the client will be redirected with header()
        }
        exit; // Terminate the script after redirection
    }



/*
        void SmartLoad([string getVarString [, string loadUri]])
            This function will send an HTTP location-header with a new URI if no output has been sent to the browser. Otherwise it will print a JavaScript, which will load the new URI.
            The URI is the URI of the current script if loadUri is empty. If getVarString is set it will be put at the end of the original URI. Multiple GET-vars should be separated with an ampersand (e.g.: 'var1=val1&var2=val2').
            If an URI is passed to loadUri the user will be sent to this location. getVarString is not taken into consideration, since GET-vars can just be passed in loadUri.

    // Example; SmartLoad()
    SmartLoad('newGETvar=true&anotherGETvar=someValue'); // Will reload the page with two new GET-vars - the reload-method depends on already sent headers
    SmartLoad('', 'http://www.jensgram.dk'); // Will load www.jensgram.dk - the method still depends on already sent headers (anything passed to the first parameter (getVarString) is ignored!)

*/
Avatar billede jensgram Nybegynder
23. oktober 2003 - 13:23 #15
PS: Det skulle ikke være nødvendigt at rette i ovenstående, men det er ikke en helt optimal løsning!
Avatar billede avminarm Juniormester
23. oktober 2003 - 13:24 #16
prøv lige at tjekke ob_start(); og denne artikel: http://webcafe.dk/tipsogtricks/php/phpheaders.html + denne http://www.reginscorner.dk/index.php/Scripts?Headers+h%E5ndtering inden du gør andet - jeg er ret sikker på det er det du leder efter
Avatar billede fangel Nybegynder
23. oktober 2003 - 13:32 #17
amix -> ked af at sige det - men du har misforstået ideen med headere... !

---

HTTP protokollen (den protokol som bruges til at overføre sider med) er lavet så fremgangs måden er som denne:

1) klienten beder om en side - sendes normalt 3-5 headers (min mozilla 1.5 har sendt 10 for at se denne side)

2) serveren ser om siden findes, hvis den gør 2.1, ellers 2.2
  2.1)
    1) serveren udsender en '200 OK' header + evt andre headere (har modtaget 15 på denne side) det er her PHP kan udsende flere headere (som mange som lystet)
    2) serverem sender siden til brugeren, dvs siden kommer ud som '[header] + [indhold] - det skal komme i denne orden, ellers virker det ikke !
  2.2)
    1) serveren udsender '404 Not Found' header + en 404 fejl side - stadig alle headere før indhold !

3) klienten modtager disse headere (kan fx være en cookie header) - browseren læser headere og parser siden efter hvad der står i disse headere

--

dette var en hurtig gennemgang af http...

hvis du nu har startet noget output vil det for browseren se således ud

--
200 OK

NOGET INDHOLD
location: side.php
MERE INDHOLD
---

hvordan er det at du vil have at klienten skal kunne se forskel på dette ? så vil location: side.php nemli' bare blive opfattet som en del af indholdet, da header afsnittet er afsluttet !

---

derfor SKAL alle headere kommer før noget output - da HTTP simpelthen er lavet sådan... du skriver bare en ny protokol hvis du er uening i opbygningen !

---

amix -> håber at også du fik lidt ud af dette - der sendes altså ikke headere TIL serveren, men FRA serveren... og der kan sendes så mange som man lyster

og fejlen skyldes ikke at js-scriptet sender en fejl, men at js-scriptet er noget output, og at header-fasen er afsluttet . og js-scriptet er det første der udsendes - derfor der står (output startet at [js-script])

Morten Fangel
Avatar billede fangel Nybegynder
23. oktober 2003 - 13:34 #18
avminarm -> ja - ob_start() vil afløse problemet - men det er faktisk overkill - se min kommentar 12:36

Morten
Avatar billede avminarm Juniormester
23. oktober 2003 - 14:02 #19
dea_pg>> hvorfor er det egentlig overkill??
Avatar billede bars Nybegynder
23. oktober 2003 - 14:21 #20
Nu har jeg rykket alt header ned i bunden efter min header(), men det der fik det til at virke var egentlig blot tomme linier.

Så vidt jeg kan se er der ikke nogen der har nævnt dette problem nogen steder i dette spørgsmål, så det var jo reelt mig selv der fandt løsningen. Skal jeg give point eller tage dem selv?
Avatar billede fangel Nybegynder
23. oktober 2003 - 14:21 #21
fordi serveren jo skal cache alt indhold, og det optager derfor mere ram + cpu... hvis det bare ryger 'direkte' ud til brugeren skal der ikke tænkes mere over dette (ud over at mange små echo kald også er langsomme)...

det er en balance gang mellem antal af besøg, dovenskab, behov og hvor kompliceret scriptet er...

Morten
Avatar billede amix Nybegynder
23. oktober 2003 - 14:22 #22
dea_pg >> my bad, det var ikke det jeg mente - - - at den kun kan sende _en_ header...

Da jeg sagde det mente jeg f.eks.
header("location: index.php");
header("location: post.php");

Og ligesom det heller ikke går:
header("location: index.php");
setcookie("muuh", "hey");

Jeg forstå udmærket at man kan sende flere headers f.eks.:
setcookie("muuh1", "hey");
setcookie("muuh2", "hey");
header("location: index.php");
setcookie("muuh3", "hey");
Avatar billede amix Nybegynder
23. oktober 2003 - 14:23 #23
bah - - :
setcookie("muuh1", "hey");
setcookie("muuh2", "hey");
header("location: index.php");
Avatar billede fangel Nybegynder
23. oktober 2003 - 14:23 #24
citat fra min kommentar 12:26
---
alle kald til headers SKAL laves før NOGET output - selv så lidt som et ' ' (blank space) og du får den fejl!
---

og du flyttede ikke header ned efter header() - du rykkede output ned efter header() - det er 2 vidt forskellige ting - igen, se min gennemgang af http...

Morten
Avatar billede fangel Nybegynder
23. oktober 2003 - 14:24 #25
amix -> du kan sagtens have cookie() efter header()
Avatar billede amix Nybegynder
23. oktober 2003 - 14:35 #26
det kan man også :-/
Bah jeg lukker noget lort ud engang imellem... er mega træt

Endvidere ved jeg også godt at det er serveren som sender headers - - - men altså koden bliver jo først sendt fra browseren til serveren hvorefter headers kommer til "php praseren" og bliver sendt tilbage fra serveren... Men fuck det, jeg tror jeg skal have noget søvn Ø__Ø
Avatar billede bars Nybegynder
23. oktober 2003 - 14:48 #27
dea_pg >> Så er det vel dig der skal have point. Kan du ikke lave et svar!
Avatar billede fangel Nybegynder
23. oktober 2003 - 15:02 #28
jo, gerne - svaa'r
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester