Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: mod_fcgid: stderr: PHP Fatal error - czyli problem z hostingiem
Forum PHP.pl > Forum > Serwery WWW > Apache
Kulfon
Napisałem sobie skrypt. Łączy się z bazą danych, odczytuje i wypisuje dane z 4 tabel (dosłownie 10 rekordów), wypisuje 4 formularze - po jednym do modyfikacji danych w każdej tabeli. Na lokalu <wamp 2.1 PHP 5.3.3 MySQL 5.5.8 i Apache 2.2.17> wszystko pięknie śmiga.

Po krótkich testach chciałem zobaczyć jak będzie to wyglądało w internecie i wrzuciłem na swój serwer. Wypełniłem trochę danymi i się bawiłem i przez około 20 minut wszystko działało ładnie, po czym po którymś przesłaniu danych w formularzu pusta strona (biała). I tyle mi się wyświetla. Jak już łaskawie ukaże mi się formularz logowania to po zalogowaniu się dalej pusto.

Treść dziennika logów:
[Tue Jan 10 16:05:22 2012] [warn] [client 31.175.91.238] mod_fcgid: stderr: PHP Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 66846721 bytes) in /ścieżka_do_folderu/plik_z_funkcjami_dołączonymi_do_skryptu on line 69
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 66846721 bytes) in /ścieżka_do_folderu/plik_z_funkcjami_dołączonymi_do_skryptu on line 69


Skrypt wygląda tak:
index.php

  1. <?php
  2.  
  3. if(isset($_POST['check']))
  4. {
  5. if(($_POST['username']==$form_user) && ($_POST['pass']==$form_pass))
  6. {
  7. $_SESSION['logged'] = true;
  8. $_SESSION['login'] = $_POST['username'];
  9. }
  10. else
  11. {
  12. echo('Błędne dane');
  13. }
  14. }
  15.  
  16. if(isset($_SESSION['logged']) && (!empty($_SESSION['login'])))
  17. {
  18. include('db_select.inc'); // połączenie się z bazą
  19. include('funckje.php');
  20.  
  21. dodaj('typ1');
  22. dodaj('typ2');
  23.  
  24. mysql_close($connection);
  25. }
  26. else
  27. {
  28.  
  29. echo(' <form method="POST" action="" class="login">
  30. <fieldset>
  31. <input class="dane" type="text" name="username" value="Login" onfocus="if (this.value == \'Login\') {this.value = \'\';}" onblur="if (this.value == \'\') {this.value = \'Login\';}" />
  32. <input class="dane" type="password" name="pass" value="Hasło" onfocus="if (this.value == \'Hasło\') {this.value = \'\';}" onblur="if (this.value == \'\') {this.value =\'Hasło\';}" />
  33. <input class="login-button" type="submit" value="Zaloguj">
  34. </fieldset>
  35.  
  36. <input class="hidden" type="hidden" value="1" name="check">
  37. </form>
  38. ');
  39. }
  40.  
  41. ?>


funkcje.php
  1. <?php
  2.  
  3. function cennik($rodzaj)
  4. {
  5.  
  6. if($rodzaj == 'tpy1'){
  7. $query_typ = 'SELECT * FROM typ;';
  8. $query_kategoria = 'SELECT * FROM kategoria;';
  9. }
  10. if($rodzaj == 'typ2')
  11. {
  12. $query_typ = 'SELECT * FROM typind;';
  13. $query_kategoria = 'SELECT * FROM kategoria2;';
  14. }
  15.  
  16. $result_typ = mysql_query($query_typ);
  17. $result_kategoria = mysql_query($query_kategoria);
  18.  
  19. if(!$result_typ or !$result_kategoria){die("Nie można wykonać zapytania! <br />". mysql_error());}
  20. $i = 0;
  21. while($result_row = mysql_fetch_row($result_typ)){
  22. $result_array[$i] = $result_row[1];
  23. $result_array[$i+1] = $result_row[2];
  24. $result_array[$i+2] = $result_row[3];
  25. $i=$i+3;
  26. }
  27.  
  28. $j = 0;
  29. while($result_row = mysql_fetch_row($result_kategoria))
  30. {
  31. $result_array_tytul[$j+1] = $result_row[0];
  32. $result_array_tytul[$j] = $result_row[1];
  33. $j=$j+2;
  34. }
  35.  
  36. echo(' <h4>Tytuł</h4>
  37. <div id="tabela_html">
  38. <div id="tytul_gora">Tabela<p>'.date("d.m.Y").'r.</p></div>');
  39.  
  40. for($i; $i>=0;)
  41. {
  42. if($j>=2){
  43. echo('<div class="kategoria"><h6 class="tytul_kat">'.$result_array_tytul[$j-2].'</h6>');
  44. }
  45.  
  46. while($result_array[$i] == $result_array_tytul[$j-1]){
  47.  
  48. echo('<div class="pozycja"><span class="tytul">'.$result_array[$i-2].'</span><span class="cena">'.$result_array[$i-1].'</span></div>');
  49. $i=$i-3;
  50. if($i <=0) {break;}
  51. }
  52. echo('</div>'); // wg. logów tutaj jest błąd
  53. $j=$j-2;
  54. }
  55.  
  56. echo('</div>');
  57.  
  58. }
  59.  
  60.  
  61.  
  62.  
  63. function lista_kategorii($rodzaj)
  64. {
  65. if($rodzaj == 'typ1'){
  66. $query_kategoria = 'SELECT * FROM kategoria;';
  67. }
  68. if($rodzaj == 'typ2')
  69. {
  70. $query_kategoria = 'SELECT * FROM kategoria2;';
  71. }
  72.  
  73. $result_kategoria = mysql_query($query_kategoria);
  74.  
  75. if(!$result_kategoria){die("Nie można wykonać zapytania! <br />". mysql_error());}
  76. $j = 0;
  77. while($result_row = mysql_fetch_row($result_kategoria))
  78. {
  79. $result_array_tytul[$j+1] = $result_row[0];
  80. $result_array_tytul[$j] = $result_row[1];
  81. $j=$j+2;
  82. }
  83.  
  84. $select = '<select name="kategoria">
  85. <option></option>';
  86.  
  87. for($j; $j>=2; $j=$j-2)
  88. {
  89. $select.= '<option value="'.$result_array_tytul[$j-1].'">'.$result_array_tytul[$j-2].'</option>';
  90. }
  91.  
  92. $select.= '</select>';
  93.  
  94. return $select;
  95. }
  96.  
  97. function dodaj($rodzaj)
  98. {
  99. $potwierdzenie = '';
  100.  
  101. if($rodzaj == 'typ1'){
  102. $query_typ = 'SELECT * FROM typ;';
  103. $query_kategoria = 'SELECT * FROM kategoria;';
  104. $rodzaj2 = 'kategoria';
  105. $option = lista_kategorii('typ1');
  106. }
  107. if($rodzaj == 'typ2')
  108. {
  109. $query_typ = 'SELECT * FROM typind;';
  110. $query_kategoria = 'SELECT * FROM kategoria2;';
  111. $rodzaj2 = 'kategoria2';
  112. $option = lista_kategorii('typ2');
  113. }
  114.  
  115. if (isset($_POST['nazwa']))
  116. {
  117. if($_POST['ktoredodaj'] == 'kategoria'){
  118. if($_POST['nazwa'] != '')
  119. {
  120. $insert = 'INSERT INTO '.$_POST['rodzaj'].' VALUES (';
  121. $id = 'NULL, ';
  122. $nazwa = $_POST['nazwa'];
  123. $query = $insert.$id.'"'.$nazwa.'");';
  124.  
  125. mysql_query($query);
  126.  
  127. $potwierdzenie ='Nowa kategoria została zapisana!';
  128. unset($_POST['nazwa']);
  129. unset($_POST['rodzaj']);
  130. }
  131. else
  132. {
  133. echo('<p style="color:red; font-weight: bold; padding: 5px;">Wpisz nazwę kategorii!</p>');
  134. }
  135. }
  136. else
  137. {
  138. if($_POST['ktoredodaj'] == 'pozycja')
  139. {
  140. if($_POST['nazwa'] != '')
  141. {
  142. if($_POST['rodzaj'] == 'kategoria') $tabela = 'typ';
  143. if($_POST['rodzaj'] == 'kategoria2') $tabela = 'typ2';
  144. $insert = 'INSERT INTO '.$tabela.' VALUES (';
  145. $id = 'NULL, ';
  146. $nazwa = $_POST['nazwa'];
  147. $cena = $_POST['cena'];
  148. $id_kat = $_POST['kategoria'];
  149. $query = $insert.$id.'"'.$nazwa.'", '.$cena.', '.$id_kat.');';
  150. mysql_query($query);
  151.  
  152. $potwierdzenie ='Nowa pozycja została zapisana!';
  153. unset($_POST['nazwa']);
  154. unset($_POST['rodzaj']);
  155. }
  156. else
  157. {
  158. echo('<p style="color:red; font-weight: bold; padding: 5px;">Wszystkie pola musza być uzupełnione!</p>');
  159. }
  160. }
  161. }
  162. }
  163. else
  164. {
  165. $_POST['rodzaj'] = '';
  166. $_POST['nazwa'] = '';
  167. }
  168.  
  169. echo('
  170. <h4>Nowa kategoria</h4>
  171. <p style="color:green; font-weight: bold; padding: 5px;">'.$potwierdzenie.'</p>
  172. <form action="#nowe" method="POST" class="dodaj_kategorie">
  173. Nazwa kategorii:</td><td><input size="30" type="text" name="nazwa" value="" />
  174. <input type="hidden" name="rodzaj" value="'.$rodzaj2.'" />
  175. <input type="hidden" name="ktoredodaj" value="kategoria" />
  176. <input type="submit" value="Dodaj nową kategorię" />
  177. </form>
  178.  
  179. <h4>Nowa pozycja</h4>
  180. form action="#nowe" method="POST" class="dodaj_kategorie">
  181. Nazwa pozycji:<input type="text" name="nazwa" value="" />
  182. Cena: <input type="text" name="cena" value="" />
  183. <input type="hidden" name="rodzaj" value="'.$rodzaj2.'" />
  184. <input type="hidden" name="ktoredodaj" value="pozycja" />
  185. Wybierz kategorię: '.$option.'
  186. <input type="submit" value="Dodaj nową pozycję" />
  187. </form>
  188.  
  189. ');
  190.  
  191. }
  192.  
  193. ?>

Macie jakieś pomysły/sugestie jak rozwiązać ten problem?


za każdym razem gdy prześlę formularz to strona się przeładowuje i łączy się ponownie z bazą danych tzn tak jak na schemacie:
-łączy z bazą
-wyświetla formularz
-zamyka polaczenie
i tak w kółko za każdym przesłaniem formularza.
Czy to może szkodzić mojemu skryptowi? Tzn czy jest on przez to duży, zajmuje dużo zasobów i czy można by to zrobić lepiej? (raz łączyć z bazą danych i przeładowywać stronę bez tracenia tego połączenia)? Czy może to w niczym nie przeszkadza jak sobie dwa razy dziennie połączę się z bazą danych po 5 razy w ramach tego skryptu?


//EDIT: poprawione, wcześniej nie miałem dostępu do źródeł skryptu dlatego tak to napisałem.
nospor
Pokaż lepiej dokładnie jak wygląda twój skrypt a nie walisz pseudokod, z którego nic nie wynika.

1) Nie edytuj posta jako odpowiedź na mojego posta, bo niby skad mam wiedzieć, że edytowałes?
Pisz normalnie jak człowiek kolejnego posta, wówczas wiadomo, że jest nowa rzecz w temacie

2) Wcześniej pokazałeś kod, na którym wywałał się skrypt. Teraz tego kodu nie widzę.
Kulfon
Już poprawiłem
Plik funkcje.php - komentarzem zaznaczyłem gdzie jest błąd
Linia 52
erix
  1. for($i; $i>=0;){

I jeszcze się dziwisz, że pożera pamięć w nieskończoność?
Kulfon
Ale później jest kolejna pętla i przy spełnionym warunku (jeżeli już mi wypisze wszystkie pozycje z kategorii) to:
  1. $i=$i-3;
erix
Nie wydziwiaj, tylko zacznij od zapisania tego po ludzku, bo na 90% jest któraś z pętli nieskończona.
Kulfon
Zaraz to wszystko sprawdzę jeszcze raz smile.gif

Swoją drogą to do pewnego momentu działało a ja nic nie zmieniałem w kodzie wtedy więc czemu nagle zaczęło mu coś nie pasować? Gdyby pętla była nieskończona to w ogóle by nie ruszyło tylko od razu wypluło ten błąd (przynajmniej tak mi się wydaje).
erix
Użyj debuggera i uruchom krok po kroku cały skrypt.

Po to są narzędzia, żeby z nich korzystać.
Kulfon
Hmm póki co xDebug'a nie udało mi się odpalić u siebie...
Mam wamp'a 2.1
phpinfo(); wyrzuca że xDebug jest zainstalowany <http://wklej.org/id/666164/>
html_errors = On
display_errors = 1
tak mam ustawione w php.ini
coś jeszcze powinienem skonfigurować <zrobić inaczej?>


Zauważyłem jeszcze jedną rzecz:
w pliku index.php wywołuję 2 razy funkcję

  1. cennik('typ1');
  2. cennik('typ2');


lokalnie działa to w porządku
na serwerze natomiast wywala błąd


na serwerze wszystko działa jeżeli zakomentuję drugie wywołanie funkcji
  1. cennik('typ1');
  2. //cennik('typ2');


wtedy także nie ma błędu o przepełnionej pamięci


EDIT://
Wyczyściłem bazę danych na serwerze. Wysłałem pliki jeszcze raz i wszystko działa jak należy (jak przed błędem)
Mimo tego, czy możecie mi powiedzieć co mogło być domniemana przyczyną takich błędów?
nospor
O to:
  1.  
  2. for($i; $i>=0;)
  3. {
  4. if($j>=2){
  5. echo('<div class="kategoria"><h6 class="tytul_kat">'.$result_array_tytul[$j-2].'</h6>');
  6. }
  7.  
  8. while($result_array[$i] == $result_array_tytul[$j-1]){
  9.  
  10. echo('<div class="pozycja"><span class="tytul">'.$result_array[$i-2].'</span><span class="cena">'.$result_array[$i-1].'</span></div>');
  11. $i=$i-3;
  12. if($i <=0) {break;}
  13. }
  14. echo('</div>'); // wg. logów tutaj jest błąd
  15. $j=$j-2;
  16. }

Zrozum wkoncu ze tu ci się zapetla. A zapetla się, bo $i zmniejszasz warunkowo w petli while, do której albo może nie wejsc w ogole, albo wejdzie za malo razy by zmniejszyc dostatecznie to $i
Teraz ci działa, bo baze wyczyściłeś i pewnie wszystkie zależności warunkowe masz ok. A przestało ci działać, bo w pewnym momencie tak zmieniłeś dane w bazie, że zależności warunkowe zrobiły się złe i $i nie zostało dostatecznie zmniejszone by wyjść z pętli.
Kulfon
Ok, dziękuję, wreszcie do mnie dotarła głupota jaką zrobiłem....
Pytanie tylko czy da się to zrealizować w inny sposób? Moglibyście mnie naprowadzić na jakieś lepsze rozwiązanie?
2 tabele, jedna przechowuje nazwy nagłówków druga trzyma nazwy pozycji
wypisuję nagłówek i potem pozycje które odpowiadają temu nagłówkowi - to miała w założeniu realizować ta konstrukcja.
Da się w takim razie zrobić to inaczej?
erix
Cytat
wypisuję nagłówek i potem pozycje które odpowiadają temu nagłówkowi - to miała w założeniu realizować ta konstrukcja.

Jedną pętlą nawet tongue.gif

Kod
bufor nagłówka = d...a;
iteruj po wyniku
      jeśli nagłówek_wyniku != bufor nagłówka
             rozpocznij nową grupę
      bufor nagłówka = nagłówek_wyniku


I można tak w nieskończoność, bez liczenia czegokolwiek. [;
Kulfon
A jeszcze troszkę bardziej na php z pseudo kodu? ;p Chyba już rozumiem jak to ma iść i zaraz spróbuję to przepisać, ale mimo wszystko jakbyś mógł jeszcze mi to przybliżyć to byłbym wdzięczny. Napiszę za jakiś czas co mi z tego wyszło smile.gif
erix
I tak praktycznie gotowca dostałeś.
Kulfon
Dobra, zobaczymy co mi z tego wyjdzie, a jakby co to napiszę jeszcze smile.gif
nospor
Tutaj opisałem dokładnie Twój problem
http://nospor.pl/grupowanie-wynikow.html
Kulfon
Dzięki wielkie za pomoc, skrypt działa smile.gif
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.