tworzę niewielki projekt z baz danych, który opiera się na bazie PostgreSQL i interfejsie webowym napisanym w języku PHP, który w założeniu ma być wirtualnym dziennikiem ocen (wiem, że nie jest to zbyt oryginalne ale wydawało mi się ciekawe na zapoznanie się z PostgreSQL'em). Natknąłem się na dziwny problem i ani w manualu ani nigdzie w googlach nie udało mi się znaleźć rozwiązania (sam problem jest trudny do sformułowania, bo nie wiem gdzie leży błąd).
Otóż, mam takie pliki (niektóre opisane bardziej w pseudokodzie, bo są dosyć długie) :
index.php :
<?php include "./header.php";?> <!-- w zaleznosci od tego kto jest zalogowany, pokazujemy rozne menu --> <?php { ?> <p>Najpierw się zaloguj !</p> <?php }else{ switch($_SESSION['uprawnienia']) { case 1: //uczen include('./menu_uczen.inc.php'); break; case 2: //rodzic include('./menu_rodzic.inc.php'); break; default: include('./blad.inc.html'); break; } } ?> </div> <!-- prawa kolumna zawierająca treść strony--> <div id="tresc"> <?php { include("./login.inc.html"); }else { switch($_SESSION['uprawnienia']) { case 1 : switch($_GET['id']){ case 'przeglad_oceny': { wypisz_oceny($_SESSION['id_osoby'], $_SESSION['uprawnienia'], $_GET['przedmiot']); } else { wypisz_oceny($_SESSION['id_osoby'], $_SESSION['uprawnienia']); } break; case 'przeglad_nieobecnosci': wypisz_nieobecnosci($_SESSION['id_osoby'], $_SESSION['uprawnienia']); break; default: break; } break; case 2 : { switch($_GET['id']){ case 'przeglad_oceny': wypisz_oceny_dziecka($_SESSION['id'], $_SESSION['uprawnienia']); break; case 'przeglad_nieobecnosci': wypisz_nieobecnosci_dziecka($_SESSION['id_osoby'], $_SESSION['uprawnienia']); break; default: break; } break; } default: { } } }else{ } } ?> </div> <?php include "./footer.php";?>
plik header.php załączany na początku pliku index.php:
?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" lang="pl"> .... i inne rzeczy, które powinny znaleźć się na początku strony oraz dołączenie jednego pliku : <?php include_once 'funkcje.php'; ?>
plik polaczenie.php załączany w pliku header.php :
<?php $polaczenie = pg_connect("host=localhost port=5432 dbname=wirtualny_dziennik user=postgres password=haslo") or die("Nie udało się połączyć z bazą danych!"); ?>
plik footer.php załączany pod koniec to sama stopka i zamykanie tagów :
oraz plik funkcje, w którym znajdują się różne funkcje wywoływane przez index.php :
<?php function wypisz_oceny($id, $uprawnienia, $przedmiot="all") { require 'polaczenie.php'; if($przedmiot=="all") { $query="SELECT nazwa_przedmiotu FROM przedmioty WHERE id_przedmioty IN". "(SELECT id_przedmioty FROM lekcje WHERE lekcje.id_klasy_w_szkole=". "(SELECT id_klasy_w_szkole FROM klasy WHERE id_osoby=$id))". "ORDER BY nazwa_przedmiotu"; { echo "<li><a href=\"./index.php?id=przeglad_oceny&przedmiot=".htmlentities($i[0],ENT_QUOTES,"UTF-8") ."\">$i[0]</a></li>"; } } else { $query="SELECT r.opis_oceny, o.ocena FROM rodzaje_ocen r JOIN oceny o ". "ON(r.id_rodzaje_ocen=o.id_rodzaje_ocen) WHERE (o.id_osoby=$id) AND r.id_lekcje IN ". "(SELECT id_lekcje FROM lekcje WHERE id_przedmioty= ". "(SELECT id_przedmioty FROM przedmioty WHERE nazwa_przedmiotu='$przedmiot'));"; }else { { } } } } function wypisz_oceny_dziecka($id, $uprawnienia) { require 'polaczenie.php'; { { $query="SELECT id_osoby_dziecko, imie FROM rodzice_i_dzieci JOIN osoby ON(rodzice_i_dzieci.id_osoby_dziecko=osoby.id_osoby) WHERE rodzice_i_dzieci.id_osoby_rodzic=".$_SESSION['id_osoby']; { { } { $query="SELECT nazwa_przedmiotu FROM przedmioty WHERE id_przedmioty IN". "(SELECT id_przedmioty FROM lekcje WHERE lekcje.id_klasy_w_szkole=". "(SELECT id_klasy_w_szkole FROM klasy WHERE id_osoby=$i[0]))". "ORDER BY nazwa_przedmiotu"; { echo "<li><a href=\"./index.php?id=przeglad_oceny&dziecko=".$i[0]."&przedmiot=".htmlentities($j[0],ENT_QUOTES,"UTF-8") ."\">$j[0]</a></li>"; } } else { } }else{ $query="SELECT nazwa_przedmiotu FROM przedmioty WHERE id_przedmioty IN". "(SELECT id_przedmioty FROM lekcje WHERE lekcje.id_klasy_w_szkole=". "(SELECT id_klasy_w_szkole FROM klasy WHERE id_osoby=".$_GET['dziecko']."))". "ORDER BY nazwa_przedmiotu"; { echo "<li><a href=\"./index.php?id=przeglad_oceny&dziecko=".$_GET['dziecko']."&przedmiot=".htmlentities($j[0],ENT_QUOTES,"UTF-8") ."\">$j[0]</a></li>"; } } }else{ wypisz_oceny($_GET['dziecko'], $_SESSION['uprawnienia'],$_GET['przedmiot']); } } ?>
oraz plik menu_uczen.inc.php (menu_rodzic wyglada identycznie)
<?php ?>
Jak można zauważyć, w pliku funkcje w każdej funkcji na początku używam :
co chyba nie jest zbyt dobrym rozwiązaniem (nie podoba mi się to ciągłe otwieranie połączenia z bazą danych).
require 'polaczenie.php';
Próbowałem w pliku header zamieścić require 'polaczenie.php'; jednak okazywało się, że podczas wywoływania funkcji wypisz_oceny_dziecka "zrywało się" połączenie z bazą danych. Używając funkcji pg_connection_status mogłem zauważyć, że połączenie z bazą danych nie istnieje, chociaż nigdzie go nie zamykałem.
Co więcej, gdy w funkcjach używam require_once zamiast require, to też mam taki sam błąd.
Używanie pg_pconnect albo ustawianie connect_timeout też nie pomaga. Nie mam pojęcia w którym momencie jest wyłączane połączenie z bazą danych (myślałem, że podczas ciągłego odświeżania strony index.php z różnymi parametrami, ale przecież require umieszczone na początku tej strony powinno rozwiązać problem ? ).
Jeżeli ktoś ma jakiś pomysł, skąd bierze się ten problem to byłbym bardzo wdzięczny za pomoc (chodzi mi o to, żebym w jednym miejscu nawiązał połączenie z bazą i żeby ono już zostało, zamiast łączyć się w każdej funkcji).