header('Location:') jump ignored?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Margaret MacDonald

    header('Location:') jump ignored?

    I'm seeing a problem that has me flummoxed. The only thing I can
    think of is that I'm violating some rule I don't know about.

    I have some code that does some processing and then does a
    header('Locatio n: ...) jump to page A on success or falls through to
    the jump to page B. This is the code:

    if ( mysql_query( 'LOCK TABLES tableX WRITE', $link ) )
    {
    mysql_query( $q, $link ) ; // store the record
    $ID = mysql_insert_id ( $link ) ; // save the new id

    if ( mysql_affected_ rows($link) == 1 )
    {
    unlock_tables() ;
    $_SESSION['ErrMsg'] = 'New ID is ' . $ID ;
    header( 'Location: PageA.php' ) ;
    $_SESSION['ErrMsg'] .= ' Error: ignored jump' ;
    }
    else // the store failed
    { error handling }
    }
    // second chance (for debugging) to do the right thing
    header( 'Location: PageA.php' ) ;
    $_SESSION['ErrMsg'] .= ' and it ignored it AGAIN!' ;

    // and we shouldn't get here at all -- but we do!
    header( 'Location: PageB.php ) ;


    Unfortunately, as I know from the telltales I stuff into session, the
    store works but the interpreter ignores both header calls that would
    jump to A and finally jumps to B instead. Unless I'm more tired than
    I'm aware, or more ignorant, this doesn't make sense.

    Any straw gratefully clutched.

    Margaret
    --
    (To mail me, please change .not.invalid to .net, first.
    Apologies for the inconvenience.)
  • PagCal

    #2
    Re: header('Locatio n:') jump ignored?

    If you display anything by the script first (such as echo 'hello
    world<br>';) the header won't redirect after that.


    Margaret MacDonald wrote:[color=blue]
    > I'm seeing a problem that has me flummoxed. The only thing I can
    > think of is that I'm violating some rule I don't know about.
    >
    > I have some code that does some processing and then does a
    > header('Locatio n: ...) jump to page A on success or falls through to
    > the jump to page B. This is the code:
    >
    > if ( mysql_query( 'LOCK TABLES tableX WRITE', $link ) )
    > {
    > mysql_query( $q, $link ) ; // store the record
    > $ID = mysql_insert_id ( $link ) ; // save the new id
    >
    > if ( mysql_affected_ rows($link) == 1 )
    > {
    > unlock_tables() ;
    > $_SESSION['ErrMsg'] = 'New ID is ' . $ID ;
    > header( 'Location: PageA.php' ) ;
    > $_SESSION['ErrMsg'] .= ' Error: ignored jump' ;
    > }
    > else // the store failed
    > { error handling }
    > }
    > // second chance (for debugging) to do the right thing
    > header( 'Location: PageA.php' ) ;
    > $_SESSION['ErrMsg'] .= ' and it ignored it AGAIN!' ;
    >
    > // and we shouldn't get here at all -- but we do!
    > header( 'Location: PageB.php ) ;
    >
    >
    > Unfortunately, as I know from the telltales I stuff into session, the
    > store works but the interpreter ignores both header calls that would
    > jump to A and finally jumps to B instead. Unless I'm more tired than
    > I'm aware, or more ignorant, this doesn't make sense.
    >
    > Any straw gratefully clutched.
    >
    > Margaret[/color]

    Comment

    • Margaret MacDonald

      #3
      Re: header('Locatio n:') jump ignored?

      PagCal wrote:
      [color=blue]
      >If you display anything by the script first (such as echo 'hello
      >world<br>';) the header won't redirect after that.[/color]

      Thanks for your quick response.

      In this case, that's not a problem. Since I don't do any i/o it
      actually does redirect. The problem is that it ignores the
      redirection I expect!
      [color=blue]
      >
      >
      >Margaret MacDonald wrote:[color=green]
      >> I'm seeing a problem that has me flummoxed. The only thing I can
      >> think of is that I'm violating some rule I don't know about.
      >>
      >> I have some code that does some processing and then does a
      >> header('Locatio n: ...) jump to page A on success or falls through to
      >> the jump to page B. This is the code:
      >>
      >> if ( mysql_query( 'LOCK TABLES tableX WRITE', $link ) )
      >> {
      >> mysql_query( $q, $link ) ; // store the record
      >> $ID = mysql_insert_id ( $link ) ; // save the new id
      >>
      >> if ( mysql_affected_ rows($link) == 1 )
      >> {
      >> unlock_tables() ;
      >> $_SESSION['ErrMsg'] = 'New ID is ' . $ID ;
      >> header( 'Location: PageA.php' ) ;
      >> $_SESSION['ErrMsg'] .= ' Error: ignored jump' ;
      >> }
      >> else // the store failed
      >> { error handling }
      >> }
      >> // second chance (for debugging) to do the right thing
      >> header( 'Location: PageA.php' ) ;
      >> $_SESSION['ErrMsg'] .= ' and it ignored it AGAIN!' ;
      >>
      >> // and we shouldn't get here at all -- but we do!
      >> header( 'Location: PageB.php ) ;
      >>
      >>
      >> Unfortunately, as I know from the telltales I stuff into session, the
      >> store works but the interpreter ignores both header calls that would
      >> jump to A and finally jumps to B instead. Unless I'm more tired than
      >> I'm aware, or more ignorant, this doesn't make sense.
      >>
      >> Any straw gratefully clutched.
      >>
      >> Margaret[/color][/color]

      --
      (To mail me, please change .not.invalid to .net, first.
      Apologies for the inconvenience.)

      Comment

      • David Mackenzie

        #4
        Re: header('Locatio n:') jump ignored?

        On Tue, 03 Aug 2004 12:25:04 GMT, Margaret MacDonald
        <scratch65536@a tt.not.invalid> wrote:
        [color=blue]
        >I'm seeing a problem that has me flummoxed. The only thing I can
        >think of is that I'm violating some rule I don't know about.
        >
        >I have some code that does some processing and then does a
        >header('Locati on: ...) jump to page A on success or falls through to
        >the jump to page B. This is the code:
        >
        >if ( mysql_query( 'LOCK TABLES tableX WRITE', $link ) )
        >{
        > mysql_query( $q, $link ) ; // store the record
        > $ID = mysql_insert_id ( $link ) ; // save the new id
        >
        > if ( mysql_affected_ rows($link) == 1 )
        > {
        > unlock_tables() ;
        > $_SESSION['ErrMsg'] = 'New ID is ' . $ID ;
        > header( 'Location: PageA.php' ) ;
        > $_SESSION['ErrMsg'] .= ' Error: ignored jump' ;
        > }
        > else // the store failed
        > { error handling }
        >}
        >// second chance (for debugging) to do the right thing
        >header( 'Location: PageA.php' ) ;
        >$_SESSION['ErrMsg'] .= ' and it ignored it AGAIN!' ;
        >
        >// and we shouldn't get here at all -- but we do!
        >header( 'Location: PageB.php ) ;
        >
        >
        >Unfortunatel y, as I know from the telltales I stuff into session, the
        >store works but the interpreter ignores both header calls that would
        >jump to A and finally jumps to B instead. Unless I'm more tired than
        >I'm aware, or more ignorant, this doesn't make sense.[/color]

        From the manual entry for header():

        <quote>
        The optional replace parameter indicates whether the header should
        replace a previous similar header, or add a second header of the same
        type. By default it will replace, but if you pass in FALSE as the
        second argument you can force multiple headers of the same type.
        </quote>

        This suggests that your last header() call to redirect to B is
        replacing your previous redirects to A.

        Put an exit() after your header() to force the script to terminate.

        --
        David ( @priz.co.uk )

        Comment

        • Juha Suni

          #5
          Re: header('Locatio n:') jump ignored?

          Margaret MacDonald wrote:[color=blue]
          > I'm seeing a problem that has me flummoxed. The only thing I can
          > think of is that I'm violating some rule I don't know about.[/color]

          Actually yes, that is what is happening.
          [color=blue]
          > I have some code that does some processing and then does a
          > header('Locatio n: ...) jump to page A on success or falls through to
          > the jump to page B. This is the code:[/color]

          Analyzing a few snippets of your code:
          [color=blue]
          > if ( mysql_query( 'LOCK TABLES tableX WRITE', $link ) )
          > {
          > mysql_query( $q, $link ) ; // store the record
          > $ID = mysql_insert_id ( $link ) ; // save the new id
          >
          > if ( mysql_affected_ rows($link) == 1 )
          > {
          > unlock_tables() ;
          > $_SESSION['ErrMsg'] = 'New ID is ' . $ID ;
          > header( 'Location: PageA.php' ) ;[/color]

          Here you set the header to PageA.php. It is set correctly as it should.
          However, since you dont tell the script to exit(), the script continues
          running.
          [color=blue]
          > $_SESSION['ErrMsg'] .= ' Error: ignored jump' ;
          > }
          > else // the store failed
          > { error handling }
          > }
          > // second chance (for debugging) to do the right thing
          > header( 'Location: PageA.php' ) ;[/color]

          Now you set the same header again. still, the script keeps running.
          [color=blue]
          > $_SESSION['ErrMsg'] .= ' and it ignored it AGAIN!' ;
          >
          > // and we shouldn't get here at all -- but we do!
          > header( 'Location: PageB.php ) ;[/color]

          Now you set the same header third time. By default setting the same
          header again replaces the header, as it should. There is a way to force
          php to send the same header more than once, although that is usually not
          very smart, especially with the location-header.

          Now that the script execution ends, the headers are sent, and the
          location header points to the last one you set it to, PageB.php.

          What you propably want to do is to add exit(); after each all three
          header calls and you should be fine.

          HTH

          --
          Suni

          Comment

          • Juha Suni

            #6
            Re: header('Locatio n:') jump ignored?

            Just a sidenote:

            The just released PHP5 contains a function headers_list() that would
            have made debugging your problem very easy.

            --
            Suni

            Comment

            • Margaret MacDonald

              #7
              Re: header('Locatio n:') jump ignored?

              Juha Suni wrote:
              [color=blue]
              >Margaret MacDonald wrote:[color=green]
              >> I'm seeing a problem that has me flummoxed. The only thing I can
              >> think of is that I'm violating some rule I don't know about.[/color]
              >
              >Actually yes, that is what is happening.
              >[color=green]
              >> I have some code that does some processing and then does a
              >> header('Locatio n: ...) jump to page A on success or falls through to
              >> the jump to page B. This is the code:[/color]
              >
              >Analyzing a few snippets of your code:
              >[color=green]
              >> if ( mysql_query( 'LOCK TABLES tableX WRITE', $link ) )
              >> {
              >> mysql_query( $q, $link ) ; // store the record
              >> $ID = mysql_insert_id ( $link ) ; // save the new id
              >>
              >> if ( mysql_affected_ rows($link) == 1 )
              >> {
              >> unlock_tables() ;
              >> $_SESSION['ErrMsg'] = 'New ID is ' . $ID ;
              >> header( 'Location: PageA.php' ) ;[/color]
              >
              >Here you set the header to PageA.php. It is set correctly as it should.
              >However, since you dont tell the script to exit(), the script continues
              >running.[/color]

              aaaAAAAAaaaaa! *THAT* was the piece I was missing. I thought (don't
              ask me why) the header call with a location argument was the actual
              jump.

              As Mark Twain didn't quite say, it's not our ignorance but our
              meta-ignorance that will get us, every time.

              Thank you very much for deconfusing me.





              [color=blue]
              >[color=green]
              >> $_SESSION['ErrMsg'] .= ' Error: ignored jump' ;
              >> }
              >> else // the store failed
              >> { error handling }
              >> }
              >> // second chance (for debugging) to do the right thing
              >> header( 'Location: PageA.php' ) ;[/color]
              >
              >Now you set the same header again. still, the script keeps running.
              >[color=green]
              >> $_SESSION['ErrMsg'] .= ' and it ignored it AGAIN!' ;
              >>
              >> // and we shouldn't get here at all -- but we do!
              >> header( 'Location: PageB.php ) ;[/color]
              >
              >Now you set the same header third time. By default setting the same
              >header again replaces the header, as it should. There is a way to force
              >php to send the same header more than once, although that is usually not
              >very smart, especially with the location-header.
              >
              >Now that the script execution ends, the headers are sent, and the
              >location header points to the last one you set it to, PageB.php.
              >
              >What you propably want to do is to add exit(); after each all three
              >header calls and you should be fine.
              >
              >HTH[/color]

              --
              (To mail me, please change .not.invalid to .net, first.
              Apologies for the inconvenience.)

              Comment

              • Margaret MacDonald

                #8
                Re: header('Locatio n:') jump ignored?

                David Mackenzie wrote:
                [color=blue]
                >On Tue, 03 Aug 2004 12:25:04 GMT, Margaret MacDonald
                ><scratch65536@ att.not.invalid > wrote:
                >[color=green]
                >>I'm seeing a problem that has me flummoxed. The only thing I can
                >>think of is that I'm violating some rule I don't know about.
                >>
                >>I have some code that does some processing and then does a
                >>header('Locat ion: ...) jump to page A on success or falls through to
                >>the jump to page B. This is the code:
                >>
                >>if ( mysql_query( 'LOCK TABLES tableX WRITE', $link ) )
                >>{
                >> mysql_query( $q, $link ) ; // store the record
                >> $ID = mysql_insert_id ( $link ) ; // save the new id
                >>
                >> if ( mysql_affected_ rows($link) == 1 )
                >> {
                >> unlock_tables() ;
                >> $_SESSION['ErrMsg'] = 'New ID is ' . $ID ;
                >> header( 'Location: PageA.php' ) ;
                >> $_SESSION['ErrMsg'] .= ' Error: ignored jump' ;
                >> }
                >> else // the store failed
                >> { error handling }
                >>}
                >>// second chance (for debugging) to do the right thing
                >>header( 'Location: PageA.php' ) ;
                >>$_SESSION['ErrMsg'] .= ' and it ignored it AGAIN!' ;
                >>
                >>// and we shouldn't get here at all -- but we do!
                >>header( 'Location: PageB.php ) ;
                >>
                >>
                >>Unfortunately , as I know from the telltales I stuff into session, the
                >>store works but the interpreter ignores both header calls that would
                >>jump to A and finally jumps to B instead. Unless I'm more tired than
                >>I'm aware, or more ignorant, this doesn't make sense.[/color]
                >
                >From the manual entry for header():
                >
                ><quote>
                >The optional replace parameter indicates whether the header should
                >replace a previous similar header, or add a second header of the same
                >type. By default it will replace, but if you pass in FALSE as the
                >second argument you can force multiple headers of the same type.
                ></quote>
                >
                >This suggests that your last header() call to redirect to B is
                >replacing your previous redirects to A.
                >
                >Put an exit() after your header() to force the script to terminate.[/color]

                Thanks, David. It's the 'put an exit() after your header()' part that
                I was missing. I didn't understand that that call to header doesn't
                terminate execution...and since the 20 other cases where I make a
                similar call are working correctly purely by accident.... :-}

                Margaret
                --
                (To mail me, please change .not.invalid to .net, first.
                Apologies for the inconvenience.)

                Comment

                • Michael Fesser

                  #9
                  Re: header('Locatio n:') jump ignored?

                  .oO(Juha Suni)
                  [color=blue]
                  >Margaret MacDonald wrote:
                  >[color=green]
                  >> header( 'Location: PageA.php' ) ;[/color]
                  >
                  >Here you set the header to PageA.php. It is set correctly as it should.[/color]

                  Nope, it's _not_ set correctly (even if it's not the real problem in
                  this case). The location-header requires an absolute URL including the
                  scheme (http://) and hostname. Most browsers also accept the "short"
                  version, but it's broken and not standards-compliant.

                  Micha

                  Comment

                  • Juha Suni

                    #10
                    Re: header('Locatio n:') jump ignored?

                    Michael Fesser wrote:[color=blue]
                    > .oO(Juha Suni)
                    >[color=green]
                    >> Margaret MacDonald wrote:
                    >>[color=darkred]
                    >>> header( 'Location: PageA.php' ) ;[/color]
                    >>
                    >> Here you set the header to PageA.php. It is set correctly as it
                    >> should.[/color]
                    >
                    > Nope, it's _not_ set correctly (even if it's not the real problem in
                    > this case). The location-header requires an absolute URL including the
                    > scheme (http://) and hostname. Most browsers also accept the "short"
                    > version, but it's broken and not standards-compliant.[/color]

                    Yes indeed, I meant to mention that in my post too, but forgot. Thanks
                    for the correction. Many people tend to use relative urls for location
                    header, where they would propably be better of with a custom function or
                    use of an included config file that would specify the "root-url" and add
                    the specified relative url to that for the header call.

                    for example:

                    function relative_redire ct($relurl) {
                    $rooturl = 'http://www.mysite.com. invalid/mydir/';
                    // possibly add a if file_exists()-check for local
                    // redirections for easier debugging and/or exception handling
                    header('Locatio n: ' . $rooturl . $relurl);
                    exit();
                    }

                    --
                    Suni

                    Comment

                    • John Wellesz

                      #11
                      Re: header('Locatio n:') jump ignored?

                      [color=blue]
                      > for example:
                      >
                      > function relative_redire ct($relurl) {
                      > $rooturl = 'http://www.mysite.com. invalid/mydir/';
                      > // possibly add a if file_exists()-check for local
                      > // redirections for easier debugging and/or exception handling
                      > header('Locatio n: ' . $rooturl . $relurl);
                      > exit();
                      > }
                      >[/color]

                      if you use php as a cgi with mod fastcgi you can do:

                      header( 'Location: /PageA.php' ) ;

                      and fastcgi will make an internal redirection to PageA.php, the client
                      browser won't see anything.

                      Comment

                      Working...