Czemu funkcja przekierowuje mnie na stronę główną?

0

Czołem!
Mam pytanie o

header("Location: ".$url);

Czy idzie jakoś zdebugować to czy ta funkcja wykonuje się poprawnie? Ona nic nie zwraca i nie jestem pewien czy to to..

Case jest taki:
Generowany jest link, a następnie jest przekierowanie. I w 90% przypadków jest ok, natomiast 10% przypadków kończy się przekierowaniem na stronę główną.

W kodzie mam:

private function redirect() {
    $url = $this->getUrl(); // np. https://4programmers.net/Forum/PHP/
    header('Location: '.$url);
    exit();
}
3

Funkcja header wysyła zwyczajnie nagłówek odpowiedzi serwera do przeglądarki i jeśli przeglądarka z jakiegoś powodu żle go zinterpretuje, to nie będzie o tym wiadomo podczas wysyłania nagłówka. Popularny błąd przy wysyłaniu nagłówka w PHP to użycie funkcji header, gdy już wysłano jakąś treść i zarazem zakończono wysyłanie nagłówków, ale wtedy powinien być komunikat błędu PHP, chyba że z jakiegoś powodu się on nie wyświetla, a dodatkowego nagłówka nie ma i przeglądarka nigdzie nie przekierowuje.

0
Manna5 napisał(a):

ale wtedy powinien być komunikat błędu PHP, chyba że z jakiegoś powodu się on nie wyświetla

Właśnie o to chodzi. Nie wyświetla żadnego błędu, php error log też niczego nie wyłapuje..
Jest jakieś obejście tego problemu?

2

Możesz zobaczyć w przeglądarce na zakładce network nagłówki, ale jak już to funkcja getUrl działa źle a nie header.
Zamień po prostu header na echo i sprawdzaj

0

Problemów może być kilka:

  1. czy w kodzie header jest wywoływany raz czy już nie jest czasem podany wcześniej
  2. znaki nowej linii lub jakiś BOM
  3. jeśli debugujesz to w CLI nie przejdzie
  4. adres jest niepełny lub błędny
  5. jeżeli output_buffering w konfigu PHP jest ustawiony na więcej niż 0 może być kłopot

Co stoi na przeszkodzie, aby zrobić to tak?

private function redirect() {
    $url = $this->getUrl(); // np. https://4programmers.net/Forum/PHP/
    echo '<meta http-equiv="Refresh" content="0; url='.$url.'" />';
    #lub jeśli masz echo gdzieś indziej do tej funkcji to return
    exit();
}
0
RafiDS napisał(a):

Czy idzie jakoś zdebugować to czy ta funkcja wykonuje się poprawnie? Ona nic nie zwraca i nie jestem pewien czy to to..

Funkcja działa na pewno tak jak powinna, czyli ustawia nagłówek.

Jedyne co może się nie udać, to jakbyś zrobił coś takiego:

echo "body"; // tu wysyłasz body
header();    // a tu header

Ale jeśli czegoś takiego nie robisz, to nie musisz się martwić - header() ustawi nagłówek poprawnie 😀.

RafiDS napisał(a):

Generowany jest link, a następnie jest przekierowanie. I w 90% przypadków jest ok, natomiast 10% przypadków kończy się przekierowaniem na stronę główną.

W kodzie mam:

private function redirect() {
    $url = $this->getUrl(); // np. https://4programmers.net/Forum/PHP/
    header('Location: '.$url);
    exit();
}

To pierwszym miejscem gdzie bym szukał, jest ta metoda getUrl() - zobacz sobie co dokładnie ona zwraca.

Bo jeśli ona w jakimś wypadku zwróci pusty string, null, 0 albo false, to wynikowy kod będzie tak: header('Location: ');, czyli zostaniesz przekierowany na url "", który jest względny, i to Cię przekieruje na stronę główną.

0

Ok, to rozumiem.
Aktualnie mam tak:

$url = $this->getUrl();
$log = 'URL: '.$url.PHP_EOL;
file_put_contents(__DIR__.'/log/log_'.$date.'.log', $log, FILE_APPEND);
echo '<meta http-equiv="Refresh" content="0; url='.$url.'" />';

Dałem sobie logowanie przed i za każdym razem otrzymuję poprawny url do przekierowania.
Po zmianie header() na echo <meta /> jest zdecydowana poprawa ale jeszcze nie do końca, bo zdarzyło mi się 1/10 prób, że nie przeniosło...

0

Pokaż kod methody getUrl().

0

Kod jest dość prosty, pobiera link do płatności p24.

private function getUrl()
{
     return Przelewy24Class::getHostForEnvironment() . 'trnRequest/' . $this->token;
}

I tu za każdym razem dostaję poprawny link. Jak sobie skopiuję link z logera wyżej to normalnie się odpala i mogę wykonać płatność.

3
RafiDS napisał(a):

Po zmianie header() na echo <meta /> jest zdecydowana poprawa ale jeszcze nie do końca, bo zdarzyło mi się 1/10 prób, że nie przeniosło...

  1. Odpal aplikację z header() tak jak miałeś wcześniej.
  2. Otwórz narzędzia developerskie w przeglądarce
  3. Skorzystaj z aplikacji, i spróbuj wywołać przekierowanie
  4. W momencie kiedy zauważasz że przekierowanie się nie udało:
    • Otwórz zakładkę network, znajdź żądanie HTTP
    • Zwróć uwagę na nagłówki, czy jest wszystko tak jak powinno być?
0

A jak w ogóle wywolujesz całość? To jest jakiś JS który to wywoła? Czy trzeba np. na jakiś button kliknąć?

0
jurek1980 napisał(a):

A jak w ogóle wywolujesz całość? To jest jakiś JS który to wywoła? Czy trzeba np. na jakiś button kliknąć?

Tak, mamy stronę podsumowania.
Klikamy <button type='submit'></button> i po weryfikacji leci na samym końcu funkcja w php redirect() jak wyżej.

1

Czyli masz przycisk i formularz. Przekierowanie idzie wtedy formularz -> kod tam wykonany -> redirect().
Sprawdziłbym jeszcze raz wywołania. W tej funkcji redirect dodaj sobie np. jakiegoś ifa na długość stringa zwracanego przez bramkę płatności i np. jeśli to będzie string krótszy niż 6 znaków to przerwij skrypt i printuj / dumpuj to co bramka zwróciła.
Być może problem masz już wcześniej. Być może jednak bramka z jakiegoś względu nie zawsze lub w ogóle nie zwraca poprawnego Urla.
Sprawdź też nagłówki jakie dostaje przeglądarka.

0
jurek1980 napisał(a):

Czyli masz przycisk i formularz. Przekierowanie idzie wtedy formularz -> kod tam wykonany -> redirect().
Sprawdziłbym jeszcze raz wywołania. W tej funkcji redirect dodaj sobie np. jakiegoś ifa na długość stringa zwracanego przez bramkę płatności i np. jeśli to będzie string krótszy niż 6 znaków to przerwij skrypt i printuj / dumpuj to co bramka zwróciła.
Być może problem masz już wcześniej. Być może jednak bramka z jakiegoś względu nie zawsze lub w ogóle nie zwraca poprawnego Urla.
Sprawdź też nagłówki jakie dostaje przeglądarka.

W poprzednim poście pisałem, że dodałem coś takiego:

$url = $this->getUrl();
$log = 'URL: '.$url.PHP_EOL;
file_put_contents(__DIR__.'/log/log_'.$date.'.log', $log, FILE_APPEND);
echo '<meta http-equiv="Refresh" content="0; url='.$url.'" />';

I za każdym razem mam poprawny link, bo wiem kiedy nie nastąpiło przekierowanie. Jak sobie go skopiuję i odpalę w przeglądarce to normalnie mogę opłacić zakup.. ;/

0

Ok. Tylko albo już wcześniej wysyłasz nagłówki z Location, albo wysyłasz jakieś białe znaki itp.
Albo w ogóle nie dochodzisz do tego miejsca o cudów nie ma.
Klasa z jakiej pobierasz ten token może np. przerywać działanie lub w finally samemu robić przekierowanie. Nie wiemy co się dzieje pod spodem.

Inaczej by to zadziałało.

0

Pokaż więcej kodu, albo zajrzyj w końcu w nagłówki na zakładce Network i porównaj co się dzieje w momencie przekierowania i w momencie kiedy nie ma przekierowania.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.