Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php+mysql+blob] załączniki w polu blob
Forum PHP.pl > Forum > PHP
hettmix
Witam.

Walczę z pewnym tematem i już brakuje mi pomysłów. Może mnie ktoś naprowadzi.
Posiadam w bazie tabelę, w której przechowuję załączniki (pliki różnego formatu) dodawane przez użytkowników.
Skrypt odpowiedzialny za upload plików do bazy wygląda tak:
  1. <?php
  2. require "/volume1/web/Joomla_1.5/connection/connection.php";
  3. connection();
  4.  
  5. if(isset($_POST['znajdz']) && $_FILES['plik_zalacznika']['size'] > 0)
  6. {
  7.  
  8. $fileName = $_FILES['plik_zalacznika']['name'];
  9. $tmpName = $_FILES['plik_zalacznika']['tmp_name'];
  10. $fileSize = $_FILES['plik_zalacznika']['size'];
  11. $fileType = $_FILES['plik_zalacznika']['type'];
  12.  
  13. $fp = fopen($tmpName, 'r');
  14. $content = fread($fp, filesize($tmpName));
  15. $content = addslashes($content);
  16. fclose($fp);
  17.  
  18. {
  19. $fileName = addslashes($fileName);
  20. }
  21.  
  22. $query = "INSERT INTO tbl_zalaczniki_sprawy_porz (zalaczniki_nazwa_pliku, zalaczniki_rozmiar_pliku, zalaczniki_typ_pliku, zalaczniki_plik ) ".
  23. "VALUES ('$fileName', '$fileSize', '$fileType', '$content')";
  24.  
  25. mysql_query($query) or die('Error, query failed');
  26.  
  27.  
  28. echo "<br>File $fileName uploaded<br>";
  29. }
  30. ?>

Pliki zapisywane są w polu typu blob (jest to świadomy wybór), a cały skrypt działa prawidłowo bez żadnych problemów.
Schody zaczynają się podczas pobierania plików z bazy.
Skrypt odpowiedzialny za to wygląda tak:
  1. <?php
  2. require "/volume1/web/Joomla_1.5/connection/connection.php";
  3. connection();
  4.  
  5. if(isset($_GET['id']))
  6. {
  7.  
  8. $id = trim($_GET['id']);
  9.  
  10.  
  11. $query = "SELECT zalaczniki_nazwa_pliku, zalaczniki_typ_pliku, zalaczniki_rozmiar_pliku, zalaczniki_plik " .
  12. "FROM tbl_zalaczniki_sprawy_porz WHERE id = '$id'";
  13.  
  14. $result = mysql_query($query) or die('Error, query failed');
  15. list($name, $type, $size, $content) = mysql_fetch_array($result);
  16.  
  17.  
  18. header("Content-length: $size");
  19. header("Content-type: $type");
  20. header("Content-Disposition: attachment; filename=$name");
  21. print $content;
  22.  
  23. }
  24.  
  25. ?>

Mianowicie, mogę pobrać pliki z bazy i zapisać je na dysku lecz części z nich nie mogę otworzyć mimo, że mają taki sam rozmiar jak oryginały. Bez problemu otwierają się pliki *.pdf, ale już np. *.png lub *.jpg lub *.xls są błędne. Sam zapis do bazy jest prawidłowy, bo gdy pobieram zapisane w bazie pliki za pośrednictwem phpMyAdmin na dysk, to mogę je wszystkie później otworzyć bez żadnego problemu. Kombinuję już na różne sposoby i nie wiem co jest tego przyczyną.
Czy wpływ na to może mieć konfiguracja serwera (jest to serwerek Synology DS712+) np. ustawienia dotyczące mime type ?.
KotWButach
używasz adslashes a zapominasz o stripslashes ?
http://www.php.net/manual/pl/function.stripslashes.php


a tak poza tym dlaczego przechowujesz pliki img pdf i inne w bazie? Zamiast trzymać je na dysku a w bazie tylko adresy?
franki01
Spróbuj do trybu otwierania pliku w fopen dodać literkę "b":
  1. fopen($tmpName, 'rb');


Żeby sprawdzić czy plik dobrze się wysyła i pokazuje, zapisz do bazy danych md5 treści wysyłanego pliku. Następnie przy pokazywaniu też wygeneruj sobie md5 tego pliku i porównaj.
hettmix
Cytat(KotWButach @ 7.10.2012, 18:54:06 ) *
używasz adslashes a zapominasz o stripslashes ?
http://www.php.net/manual/pl/function.stripslashes.php


a tak poza tym dlaczego przechowujesz pliki img pdf i inne w bazie? Zamiast trzymać je na dysku a w bazie tylko adresy?


Zastosowanie stripslashes nie rozwiązuje problemu, a dodatkowo plik zapisane teraz na dysku różnią się wielkością od oryginałów.
Pisałem już że zapis plików w bazie jest świadomym wyborem - załączników będzie niewiele i o małym rozmiarze, a poza tym wygodniej
jest mi korzystać z wbudowanych mechanizmów bezpieczeństwa bazy.

Cytat(franki01 @ 8.10.2012, 00:58:03 ) *
Spróbuj do trybu otwierania pliku w fopen dodać literkę "b":
  1. fopen($tmpName, 'rb');


Żeby sprawdzić czy plik dobrze się wysyła i pokazuje, zapisz do bazy danych md5 treści wysyłanego pliku. Następnie przy pokazywaniu też wygeneruj sobie md5 tego pliku i porównaj.


Zastosowanie fopen z opcją 'rb' nie rozwiązało problemu.
Jak już pisałem rozmiar zapisywanych na dysk plików jest ten sam, ale zmienia się struktura plików bo nie można ich poprawnie otworzyć - poza plikami *.pdf które otwierają się prawidłowo w skojarzonym programie.

OK problem rozwiązany - okazało się że wina leży po stronie systemu kodowania plików ze skryptami. Zmiana z UTF-8 na UTF-8 (bez BOM) załatwiło sprawę.
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.