Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: IE7/8 i funkcja unset w PHP
Forum PHP.pl > Forum > PHP
qrzysztof
Wszyscy wiemy, że IE7/8 to badziewie jakich mało. Dotychczas myślałem, że te przeglądarkopodobne produkty wtrącają się tylko do HTML i CSS. Nic bardziej błędnego. Okazuje się, że potrafią namieszać również w kodzie PHP.

Mam poniższy kod:

  1. public function deleteQuestion ($id)
  2. {
  3.  
  4. if ( in_array($id, array_keys($this->_questions)) )
  5. {
  6. unset($this->_questions[$id]); #problematyczna linia
  7.  
  8. #usuniecie pytania z bazy
  9. $this->dbm->deleteQuestion($id);
  10.  
  11. return true;
  12. }
  13. return false;
  14. }


We wszystkich przeglądarkach działa poprawnie. Natomiast w IE7/8 po wejściu do tej funkcji a następnie do bloku warunkowego, zaznaczona przeze mnie linia powoduje wyjście z funkcji bez zgłoszenia błędu czy wyjątku. Jest to tym bardziej dziwne, że
Kod
$this->_questions[$id]
istnieje, a jeszcze bardziej ponieważ kolejna linia usuwająca pytanie z bazy jeszcze się wykonuje! Ale return true już najwyraźniej nie bo funkcja nie zwraca true!

Gdy zmienię kod na:
  1. if ( $this->questions[$id] )
  2. {
  3. unset($this->_questions[$id]); #problematyczna linia
  4. }


sytuacja nie ulega zmianie.

Zaznaczę, że do testów używam emulatorów IE7 na XP (ale różnych i we wszystkich jest tak samo), natomiast IE8 w pełnej wersji również na ten system.
nospor
IE nie ma nic do php.
  1. public function deleteQuestion ($id)
  2. {
  3.  
  4. var_dump($id);
  5. var_dump($this->_questions);
  6. if ( in_array($id, array_keys($this->_questions)) )
  7. {
  8. unset($this->_questions[$id]); #problematyczna linia
  9.  
  10. #usuniecie pytania z bazy
  11. $this->dbm->deleteQuestion($id);
  12.  
  13. return true;
  14. }
  15. return false;
  16. }

I nagle wszystko staje się jasne. Czemu nie robicie głupiego var_dump()? To takie trudne??
darko
Ee raczej się mylisz z tym wtrącaniem się w kod php, raczej chodzi o cache. Odpal debugger i wywołaj gdzieś
$temp = $myObj->deleteQuestion(123);
$TEST= 123;
(ustaw breakpointa dokładnie dla linii $TEST) sprawdź wartość zmiennej $temp, oczywiście poustawiaj odpowiednie wartości zmiennych.
nospor
I jeszcze
Temat: Jak poprawnie zada pytanie
Wyświetlanie wszystkich błędów, analiza zmiennych i kupa innych. - To podstawy.
qrzysztof
Cytat(nospor @ 9.09.2011, 10:10:43 ) *
I nagle wszystko staje się jasne. Czemu nie robicie głupiego var_dump()? To takie trudne??
Nie no, aż tak naiwny nie jestem. Wszystko sprawdziłem zanim napisałem.

To, że stanie się jasne na końcu nie ulega wątpliwości ale na razie nie jestem bliżej.

Zastosowałem var_dump w zalecanym miejscu w trochę zmodyfikowanej formie, aby nie zaciemniać obrazu:

  1. var_dump($id);
  2. var_dump(array_keys($this->_questions));


Dane wejściowe identyczne:

-trzy pytania w obiekcie i w bazie (2423, 2424, 2425)
-usuwane: 2425

Rezultat w IE
Kod
string(4) "2425" array(2) { [0]=> int(2423) [1]=> int(2424) }


Rezultat w FF
Kod
string(4) "2425" array(3) { [0]=> int(2423) [1]=> int(2424) [2]=> int(2425) }

nospor
No i już wiesz czemu nie działa unset - bo nie masz takiego elementu na liscie, który chcesz usunać. Już wiesz, że błedem nie jest unset a Twoja lista - czyż nie jest od razu jaśniej? Bo moim zdaniem jest, już nie krążysz przy unset, które nie jest niczemu winne


ps: zastosowałeś się do porad z linku co ci podałem? Wyswietlanie wszystkich błędów i itp?

Cytat
Nie no, aż tak naiwny nie jestem. Wszystko sprawdziłem zanim napisałem.
Widać nie sprawdzałeś. Jakbyś sprawdził to byś wiedział, że to nie unset.
qrzysztof
Nospor, sprawa nie jest taka prosta jak się na pierwszy rzut oka wydaje. Zwróć uwagę, że napisałem w pierwszym poście
Cytat(qrzysztof @ 9.09.2011, 10:05:41 ) *
Natomiast w IE7/8 po wejściu do tej funkcji a następnie do bloku warunkowego, zaznaczona przeze mnie linia powoduje wyjście z funkcji bez zgłoszenia błędu czy wyjątku.


P.S. Oczywiście, że tu musi chodzić o jakieś cache/sesje czy cookies. Ja nie sugeruję, że przeglądarka wchodzi mi na serwer i zmienia tam kod smile.gif
nospor
SKoro nie istnieje na liscie twoje ID, to kod nie ma prawa wejść do tego IFa.

Prosty test:
  1. public function deleteQuestion ($id)
  2. {
  3.  
  4. var_dump($id);
  5. var_dump($this->_questions);
  6. if ( in_array($id, array_keys($this->_questions)) )
  7. {
  8. die('JUPI, jestem!');
  9. unset($this->_questions[$id]); #problematyczna linia
  10.  
  11. #usuniecie pytania z bazy
  12. $this->dbm->deleteQuestion($id);
  13.  
  14. return true;
  15. }
  16. return false;
  17. }

Co się wyświetla?
qrzysztof
Wyświetla się

Kod
string(4) "2425" array(3) { [0]=> int(2423) [1]=> int(2424) [2]=> int(2425) } JUPI, jestem!
nospor
Dla IE?
To się zdecyduj, co ci wyświetla, bo teraz napisałeś:
array(3) { [0]=> int(2423) [1]=> int(2424) [2]=> int(2425) }
a wcześniej pisałeś:
array(2) { [0]=> int(2423) [1]=> int(2424) }
Więc która wkońcu wersja jest prawdziwa?
qrzysztof
Chciałbym się zdecydować, ale to niestety nie ode mnie zależy. Też mnie to dziwi ale takie są właśnie dane na wyjściu.
nospor
A jak skasujesz DIE to znowu wyświetlają się tylko 2 elementy?
Znaczy, że Twój kod wykonuje się dwa razy - za pierwszy razem jest ok, a za drugim nie ok smile.gif
qrzysztof
Ok, już sprawdzam...

Na razie nie znalazłem na to dowodów:

W kodzie mam:

  1. if ( !($testObject->deleteQuestion($id)) )
  2. {
  3. throw new ExtendedException('Nie posiadasz uprawnień do modyfikowania tego pytania.');
  4. }


Zmieniłem na:

  1. if ( !($testObject->deleteQuestion($id)) )
  2. {
  3. throw new ExtendedException('Nie posiadasz uprawnień do modyfikowania tego pytania.');
  4. }else
  5. {
  6. throw new ExtendedException('Wykonane przynajmniej raz dobrze');
  7. }


Dane wejściowe te same i w obu przypadkach wynik
Kod
Nie posiadasz uprawnień do modyfikowania tego pytania

nospor
zapytam ponownie:
czy bez DIE dla IE wyświetlają się dwa elementy na liście czy 3?
Czy z DIE znowu zaczynają się wyświetlać 3?

qrzysztof
Bez die: 2 elementy w tablicy
z die: 3 elementy

Oba przypadki odnoszą się do IE
drPayton
  1. var_dump(array_keys($this->_questions));

=>
Kod
string(4) "2425" array(3) { [0]=> int(2423) [1]=> int(2424) [2]=> int(2425) }


a:

  1. var_dump($this->_questions);

=>
Kod
string(4) "2425" array(3) { [0]=> int(2423) [1]=> int(2424) [2]=> int(2425) }


questionmark.gif

Jak się chcecie we 2 dogadać, to najpierw (do autora) zacznij robić tak, jak pisze nospor, bo inaczej się pokręcicie zaraz...
nospor
Cytat
Bez die: 2 elementy w tablicy
z die: 3 elementy
Czyli kod wykonuje ci się wiecej niż jeden raz - to oczywiste i stwierdzone naukowo. Teraz zastanów się czemu.
@drPayton bo on var_dump robi na array_keys(). Przecież pisał o tym.
qrzysztof
@drPayton dał jednak dobry trop:

O dziwo jeśli zrobię var_dump($this->_questions) to wszystko działa poprawnie. Sam fakt dodania tej linii do kodu! Wtedy zawsze pokazuje, że są 3 elementy w tablicy.

Ale jak usunę tę linię

  1. var_dump($this->_questions);


to znowu to samo.

To musi mieć jakiś związek z wyjściem. Tak samo z tym die. Jeśli jest coś więcej na wyjściu kodu to wszystko działa.

Kod nie wykonuje się dwa razy. Mam w kodzie tylko jedno użycie deleteQuestion i jeśli test, który zrobiłem parę postów wyżej nic nie wykazał to nie ma takiej możliwości.
drPayton
Control question:

$this->dbm != $this?

Czyli na pewno nie zapętlasz działania tego skryptu? (identyczne nazwy metod, mały błąd przy definicji $this->dbm i kaput...)
qrzysztof
@drPayton - o zapętlaniu nie ma mowy, choć jeszcze sprawdzę ten wątek.

Dlaczego podejrzewam funkcję unset? Ponieważ to die(), które @nospor zaproponował wykona się jeśli jest przed nią. Umieszczone po tej linii gdzie jest unset() już się nie wykona.

Edit: sprawdziłem zmieniając nazwy OBU deleteQuestion na różne. Bez zmian. Zresztą o zapętlaniu nie mogło być mowy. $dbm to obiekt kontaktujący się z bazą i operujący bezpośrednio na niej.
nospor
Cytat
Ponieważ to die(), które @nospor zaproponował wykona się jeśli jest przed nią. Umieszczone po tej linii gdzie jest unset() już się nie wykona.
No i teraz wkońcu podałeś konkretny powód.

Włączyłeś wyświetlanie wszystkich błędów jak cię prosiłem już o to kilka razy? Przejrzałeś logi?
qrzysztof
Ustawienie raportowania na E_ALL wyrzuciło parę błędów.

Jednak więcej w FF niż w IE. W obu przypadkach szereg "Undefined index" i "Undefined variable".

Nie wydają się mieć związku z tematem i raczej nikomu poza mną nic nie powiedzą ale wklejam dla większej przejrzystości:

Kod
Notice: Undefined index: 1 in F:\xampp\htdocs\edu\common\abstract\class.display.php on line 207

Notice: Undefined variable: scriptString in F:\xampp\htdocs\edu\common\abstract\class.display.php on line 215

Notice: Undefined variable: stylesheetString in F:\xampp\htdocs\edu\common\abstract\class.display.php on line 236

Notice: Undefined variable: conditionalStylesheetString in F:\xampp\htdocs\edu\common\abstract\class.display.php on line 257

Notice: Undefined index: enabled in F:\xampp\htdocs\edu\common\abstract\class.display.php on line 282

Notice: Undefined variable: keyboard in F:\xampp\htdocs\edu\common\abstract\class.display.php on line 347

Notice: Undefined variable: popup in F:\xampp\htdocs\edu\common\abstract\class.display.php on line 348

Notice: Undefined variable: systemMessage in F:\xampp\htdocs\edu\common\abstract\class.display.php on line 352

Notice: Undefined variable: code in F:\xampp\htdocs\edu\common\classes\class.breadcrumb.php on line 72


Natomiast zastanawia mnie jedno. Dlaczego te błędy pojawiają się tylko właśnie przy usuwaniu pytań. Wysłałem parę innych formularzy. Część z nich polegająca na usuwaniu innych obiektów z bazy i tych błędów nie było.

Edit: już wiem czemu tylko przy usuwaniu pytań się pojawia, bo w złym miejscu dałem
smile.gif Poprawiłem i teraz błędy są już wszędzie.

-----------------------------------------------------------------------------
Podsumujmy zatem naszą arcyciekawą (dzięki IE) sytuację:

Aplikacja wchodzi w tejże "przeglądarce" (7/8) prawidłowo do funkcji deleteQuestion i do bloku warunkowego if. Gdy już wejdzie do bloku if to w poniższym kodzie die() przerwie działanie.




  1. public function deleteQuestion ($id)
  2. {
  3. if ( in_array($id, array_keys($this->_questions)) )
  4. {
  5. die('JUPI, jestem!');
  6. unset($this->_questions[$id]); #problematyczna linia
  7.  
  8. #usuniecie pytania z bazy
  9. $this->dbm->deleteQuestion($id);
  10.  
  11. return true;
  12. }
  13. return false;
  14. }


Natomiast tu już nie przerwie:

  1. public function deleteQuestion ($id)
  2. {
  3. if ( in_array($id, array_keys($this->_questions)) )
  4. {
  5.  
  6. unset($this->_questions[$id]); #problematyczna linia
  7. die('JUPI, jestem!');
  8. #usuniecie pytania z bazy
  9. $this->dbm->deleteQuestion($id);
  10.  
  11. return true;
  12. }
  13. return false;
  14. }


To die() w tym drugim przypadku wykonuje się ale jakby tylko na poziomie funkcji deleteQuestion(). Nic po tej instrukcji już się nie wykona, czyli:
  1. #usuniecie pytania z bazy
  2. $this->dbm->deleteQuestion($id);
  3.  
  4. return true;

nie zostanie wykonane. Natomiast poza funkcją deleteQuestion kod okazuje się dalej wykonywać jakby tego die() nie było w ogóle.


Funkcja deleteQuestion na 100% wykonuje się raz!

Raportowanie błędów na poziomie E_ALL nie wykazało istotnych błędów.

edit-----------------------------------------------------
Problem zostawiam nierozwiązany bo odkryłem, że problem występuje tylko lokalnie - u mojego providera nie. Obsługę IE7 wyłączam 1 stycznia 2012 a IE8 1 stycznia 2013 - a do tego czasu pozostanę najprawdopodobniej u tego providera.

Ale włos się się jeży na myśl co to microsoftowskie g**no potrafi.
melkorm
Za przeproszeniem: Pieprzysz farmazony że to aż strach czytać.


1. Popraw błędy które się Tobie wyświetlają.
2. Pokaż więcej kody szczególnie tych funkcji które wykonujesz.
3. Przeglądarka do kodu na serwerze ma tyle co piernik do wiatraka.
4. Opisz normalnie (logicznie) problem.
qrzysztof
1. Nie za bardzo mi się w tej chwili chce, choć kiedyś do tego wrócę i na pewno poprawię. Choć nie mają one związku z opisywaną sytuacją to mają z pewnością (marginalny ale jednak) potencjał problemotwórczy.

2. Pokazałem to co istotne. Cała aplikacja ma przynajmniej kilka tysięcy linii kodu, nikt tego raczej nie będzie analizował.
3. Temu ile ma wspólnego poświęciłem już jedno zdanie i nie będę się powtarzał.
4. Nie wiem co rozumiesz pod pojęciem normalnie (logicznie). Coś tu można jeszcze jaśniej napisać niż ja to zrobiłem? Nie sądzę.
melkorm
Cytat
To die() w tym drugim przypadku wykonuje się ale jakby tylko na poziomie funkcji deleteQuestion(). Nic po tej instrukcji już się nie wykona, czyli:

A jak ma się wykonać skoro przerywasz skrypt?

Cytat
Natomiast poza funkcją deleteQuestion kod okazuje się dalej wykonywać jakby tego die() nie było w ogóle.

Jeżeli die się nie wykonuje to znaczy że warunek nie został spełniony.
qrzysztof
No nie do końca.

Tak jak pisałem. Die() się wykonuje, ale na poziomie funkcji. Co przez to rozumiem?

- die() przerywa funkcję niczym break pętlę,
- funkcja zostaje przerwana ale kod skryptu wykonuje się dalej
- nie wyświetla się komunikat z die() - wynika to poniekąd z tego, że skrypt wykonuje się dalej
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.