Piszę aplikację php, która ma wyświetlać pdfy, trzymane w polach BLOB w bazie danych. Założenia są takie:
1) Pliki, po kliknięciu w linka do danego pdfa wyświetlają się oknie przeglądarki (nie żadne okienko typu otwórz/zapisz, tylko koniecznie w oknie przeglądarki -> header content-desposition: inline; )
2) Pliki są przetrzymywane w bazie danych i w żadnym innym miejscu - w polach blob, a nie w żadnych plikach albo innych cudnych rozwiązaniach
3) Łączność z bazą danych rozwiązana jest przez warstwę abstrakcji do połączenia z bazą danych
4) Całość działa na templatach - każda strona serwisu jest edytowalna, jako jeden template - jak się pojawia coś, co jest pętlą - jest to wydzielonym blokiem w templacie
I powyższa specyfikacja niestety nie może ulec zmianie, ponieważ nie jest to zależne ode mnie...
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Ok - to teraz rozwiązania, na których się oparłem, pisząc ją
do łączności z bazą wybrałem PEAR DB (kompatybilne mniej więcej z MDB) - jak się zaczęły problemy, to kombinowałem również z ADODB i w razie czego jestem gotowy przepisać na nią całą aplikację... w tej chwili jest napisana pod PEAR DB
System templatów - PEAR HTML_Template_IT (są blokowe i łatwe do nauczenia)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Ok - a teraz problemy, z którymi się borykam i nie mogę na nie znaleźć rozwiązania, toteż zwracam się z prośbą o pomoc do was, drodzy forumowicze - raczej żadko zadaję pytania na forum, bo zazwyczaj szukam tak długo, aż znajdę jakieś rozwiązanie - ale tym razem nic mi nic nie podpowiada....
1) Problem jest taki, że ładuję sobie poprzez f_open i base64_encode pdfa do bloba w bazie i potem chcę go pobrać przez base64_decode z bazy danych i wyświetlam w nowym oknie przeglądarki headerami, ustawiając je na pdf. Ładowanie pdfa do bazy zrealizowałem w następujący sposób (poniższy kod używa PEAR/DB):
Kod
function dodaj_pdfa ($nazwa, $tmp_plik, $znak, $opis, $licznik, $data, $typ) {
global $phptype;
global $dbhost;
global $database;
global $username;
global $password;
$dsn = "$phptype://$username:$password@$dbhost/$database";
$db = DB::connect($dsn);
if (DB::isError($db)) {
die($db->getMessage());
}
$nazwa_w_baze_sql = "insert into `pdfy` (`id`,`nazwa_pdf`,`znak`,`opis`,`pdf_data`,`typ`) values ('" . $licznik . "','" . $nazwa . "','" . $znak . "','" . $opis . "','" . $data ."','". $typ ."')";
$plik_w_baze_sql = "insert into `pliki` (`id`,`plik_pdf`) values ('" . $licznik . "','" . $tmp_plik ."')";
$nazwa_w_baze_query = $db->query($nazwa_w_baze_sql);
if (DB::isError($nazwa_w_baze_query)) {
$blad = $nazwa_w_baze_query->getMessage();
die ('wystapił błąd w zapisywaniu nazwy pdfa do bazy, treść błędu: '. $blad);
}
$plik_w_baze_query = $db->query($plik_w_baze_sql);
if (DB::isError($plik_w_baze_query)) {
$blad = $plik_w_baze_query->getMessage();
die ('wystapił błąd w zapisywaniu pdfa do bazy, treść błędu: '. $blad);
}
$db->disconnect;
$db_wyjscie = array();
$db_wyjscie[0] = 1;
$db_wyjscie[1] = $ilosc;
return $db_wyjscie;
}
global $phptype;
global $dbhost;
global $database;
global $username;
global $password;
$dsn = "$phptype://$username:$password@$dbhost/$database";
$db = DB::connect($dsn);
if (DB::isError($db)) {
die($db->getMessage());
}
$nazwa_w_baze_sql = "insert into `pdfy` (`id`,`nazwa_pdf`,`znak`,`opis`,`pdf_data`,`typ`) values ('" . $licznik . "','" . $nazwa . "','" . $znak . "','" . $opis . "','" . $data ."','". $typ ."')";
$plik_w_baze_sql = "insert into `pliki` (`id`,`plik_pdf`) values ('" . $licznik . "','" . $tmp_plik ."')";
$nazwa_w_baze_query = $db->query($nazwa_w_baze_sql);
if (DB::isError($nazwa_w_baze_query)) {
$blad = $nazwa_w_baze_query->getMessage();
die ('wystapił błąd w zapisywaniu nazwy pdfa do bazy, treść błędu: '. $blad);
}
$plik_w_baze_query = $db->query($plik_w_baze_sql);
if (DB::isError($plik_w_baze_query)) {
$blad = $plik_w_baze_query->getMessage();
die ('wystapił błąd w zapisywaniu pdfa do bazy, treść błędu: '. $blad);
}
$db->disconnect;
$db_wyjscie = array();
$db_wyjscie[0] = 1;
$db_wyjscie[1] = $ilosc;
return $db_wyjscie;
}
i to jest w porządku - ładnie się ładuje, plik siedzi w bazie i tutaj raczej problemu nie ma - udało mi się go wyświetlić za pomocą następnego kodu, bez użycia warstwy abstrakcji, który działa :
Kod
function wyswietl_pdf($id) {
$polaczenie = mysql_connect("www.mojastrona.pl", "mojlogin", "mojehaslo") or die (' Nie można połączyć się z databazą
! ');
mysql_select_db("baza", $polaczenie) or die ('Nie można wybrać databazy
!');
$zassany_pdf_query = mysql_query("select * from `pliki` where `id`='". $id ."' limit 1") or die ('<br><font color="red" face="arial" size="3">BŁĄD: APLIKACJA ZAKOŃCZYŁA SWOJE DZIAŁANIE.<br>Rodzaj błędu: nie mozna pobrac pliku z bazy <br> Błąd z mysql: ' . mysql_error() . '</font>');
$zassany_pdf = mysql_fetch_assoc($zassany_pdf_query);
$pdf_wyswietlany = base64_decode($zassany_pdf['plik_pdf']);
mysql_close();
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-type: application/pdf");
header("Content-Transfer-Encoding: binary");
echo $pdf_wyswietlany;
ob_end_flush();
}
$polaczenie = mysql_connect("www.mojastrona.pl", "mojlogin", "mojehaslo") or die (' Nie można połączyć się z databazą

mysql_select_db("baza", $polaczenie) or die ('Nie można wybrać databazy

$zassany_pdf_query = mysql_query("select * from `pliki` where `id`='". $id ."' limit 1") or die ('<br><font color="red" face="arial" size="3">BŁĄD: APLIKACJA ZAKOŃCZYŁA SWOJE DZIAŁANIE.<br>Rodzaj błędu: nie mozna pobrac pliku z bazy <br> Błąd z mysql: ' . mysql_error() . '</font>');
$zassany_pdf = mysql_fetch_assoc($zassany_pdf_query);
$pdf_wyswietlany = base64_decode($zassany_pdf['plik_pdf']);
mysql_close();
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-type: application/pdf");
header("Content-Transfer-Encoding: binary");
echo $pdf_wyswietlany;
ob_end_flush();
}
Więc zachwycony swoimi wynikami przepisałem sobie kod na warstwę abstrakcji (PEAR/DB) i zamiast oczekiwanego rezultatu na ekranie zobaczyłem Zonk, w postaci kodu źródłowego pdfa, którego przeglądarka nie zinterpretowała i wywaliła, jak leciało

Kod
function wyswietlacz_db($id){
global $phptype;
global $dbhost;
global $database;
global $username;
global $password;
$dsn = "$phptype://$username:$password@$dbhost/$database";
$db = DB::connect($dsn);
if (DB::isError($db)) {
die($db->getMessage());
}
$pokaz_query_sql = "select `plik_pdf` from `pliki` where `id` = ". $id ." limit 1";
$pokaz_pdf_query = $db->query($pokaz_query_sql);
if (DB::isError($pokaz_pdf_query)) {
$blad = $pokaz_pdf_query->getMessage();
die ('wystapił błąd w zapytaniu do bazy, nie można pobrać treści pliku. Treść błędu: '. $blad);
}
$pdf = $pokaz_pdf_query->fetchRow(DB_FETCHMODE_ASSOC);
$pdf_wyswietlany = base64_decode($pdf['plik_pdf']);
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-type: application/pdf');
header("Content-disposition: inline");
header('Content-Transfer-Encoding: BASE64');
echo $pdf_wyswietlany;
ob_end_flush();
ob_end_clean();
$db->disconnect;
}
global $phptype;
global $dbhost;
global $database;
global $username;
global $password;
$dsn = "$phptype://$username:$password@$dbhost/$database";
$db = DB::connect($dsn);
if (DB::isError($db)) {
die($db->getMessage());
}
$pokaz_query_sql = "select `plik_pdf` from `pliki` where `id` = ". $id ." limit 1";
$pokaz_pdf_query = $db->query($pokaz_query_sql);
if (DB::isError($pokaz_pdf_query)) {
$blad = $pokaz_pdf_query->getMessage();
die ('wystapił błąd w zapytaniu do bazy, nie można pobrać treści pliku. Treść błędu: '. $blad);
}
$pdf = $pokaz_pdf_query->fetchRow(DB_FETCHMODE_ASSOC);
$pdf_wyswietlany = base64_decode($pdf['plik_pdf']);
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-type: application/pdf');
header("Content-disposition: inline");
header('Content-Transfer-Encoding: BASE64');
echo $pdf_wyswietlany;
ob_end_flush();
ob_end_clean();
$db->disconnect;
}
kombinowałem na wszystkie strony i za nic nie mogłem znaleźć żadnego rozwiązania na mój problem... Potem stwierdziłem, że jak się nie da przy pomocy PEAR/DB, to może zmienię warstwę abstrakcji na inną i najwyżej przepiszę połączenia z bazą... Wybrałem ADODB i napisałem te funkcję na nowo, ale efekt taki sam - źródło pdfa na ekranie...
Kod
function wyswietlacz_pdf($id, $dod) {
global $phptype;
global $dbhost;
global $database;
global $username;
global $password;
$dsn = "$phptype://$username:$password@$dbhost/$database";
$db = ADONewConnection($dsn);
$db->debug = false;
if ($dod == 0) {
$pdf_sql = "select `plik_pdf` from `pliki` where `id` = ". $id ." limit 1";
}
if ($dod == 1) {
$pdf_sql = "select `plik_pdf` from `pliki_dod` where `id` = ". $id ." limit 1";
}
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$pdf = $db->execute($pdf_sql);
if($db===false) die ('wystapił błąd w zapytaniu do bazy: '. $pdf_sql);
$pdf_wyswietlany = base64_decode($pdf->fields['plik_pdf']);
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-type: application/pdf');
header('Content-Transfer-Encoding: binary');
echo $pdf_wyswietlany;
ob_end_flush();
$db->close();
global $phptype;
global $dbhost;
global $database;
global $username;
global $password;
$dsn = "$phptype://$username:$password@$dbhost/$database";
$db = ADONewConnection($dsn);
$db->debug = false;
if ($dod == 0) {
$pdf_sql = "select `plik_pdf` from `pliki` where `id` = ". $id ." limit 1";
}
if ($dod == 1) {
$pdf_sql = "select `plik_pdf` from `pliki_dod` where `id` = ". $id ." limit 1";
}
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$pdf = $db->execute($pdf_sql);
if($db===false) die ('wystapił błąd w zapytaniu do bazy: '. $pdf_sql);
$pdf_wyswietlany = base64_decode($pdf->fields['plik_pdf']);
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-type: application/pdf');
header('Content-Transfer-Encoding: binary');
echo $pdf_wyswietlany;
ob_end_flush();
$db->close();
Podejrzewam, że te warstwy abstrakcji "coś robią" z moim pdfem, przechowywanym w blobie w mysqlu i dlatego wywala mi kaszkę ze źródła pliku na ekran.... headery wydają się być ok - bo przecież z połączeniem wywołanym z php poprzez mysql_query, to działa - kombinowałem też bez rezultatów z opcjami content-transfer-encoding z binary na 7bit, 8bit, base64 i BASE64... próbowałem też dorzucać nagłówki content-desposition: inline, attachment - z tym że attachment być nie może, ponieważ pdfy muszą się wyświetlać pod przegladarką, a nie za pomocą zewnętrznego programu... więc nie wiem, co w nich można jeszcze zmienić, aby mi tego pdfa wyświetliło....
Inną rzeczą, która mi przychodzi do głowy może być złe przypisanie danych pobranych z bazy do tablicy, bo jak zrobiłem wcześniej bez warstwy abstrakcji mysql_fetch_array(), to też mi wywalało źródło - dopiero przypisanie do tablicy asocjacyjnej, mysql_fetch_assoc dało żądany rezultat w postaci prawidłowo wyświetlonego pdfa - toteż nie wiem, czy nie popełniam błędu przy ustawianiu fetch_mode na assoc w przypadku warstw abstrakcji - może tam powinno być coś innego? - też tego wykminić nie mogę....
chyba, że jest błąd przy ładowaniu pliku, ale raczej nie, bo przecież z polecenia wykonanego pod mysqlem się wyświetla poprawnie, jedynie jest problem przy warstwach abstrakcji...
A niestety z warstw abstrakcji zrezygnować nie mogę, ponieważ mam to narzucone z góry...
ok - drugi problem, który mam, to templaty, a dokładniej pętla wykonana na jednym bloku, w którym alternatywnie jest ładowany blok z inną treścią podczas edycji... - opisuję go w innym poście
Jeżeli ktoś zna jakikolwiek sposób na rozwiązanie któregokolwiek z powyższych problemów, to proszę o posta w tej sprawie

Pozdrawiam,
Daniofantasy
Nie bardzo wiem, od czego zacząć - manuale tych klas, co używam też mi niewiele mówią - ma ktoś jakiś pomysł?
minęło kilka dni i żadnych postępów... ma ktoś może jakiś pomysł...?