Autor Zpráva
tom.rossi
Profil *
Ahoj všem, potřebuji pořešit jeden problém:
Mám intranet postavený na Apache, PHP, MSSQL (neřešte proč zrovna tahle kombinace, prostě se s tím musím porvat chtě nechtě tak jak to je)
1.) Zadání: dokumenty MS Office (doc,docx,xls,xlsx) a pdf ukládány do MSSQL a otevírány přes webové rozhraní (PHP)
2.) Otevírání dokumentů funguje, ale obsah není nic pro oko estéta s výjimkou pdf, které se otevírají korektně (MS Office docs prostě nejsou čitelné).
3.) Vrtám se s tím už moc dlouho na to abych doufal, že to vyřeším sám. Poradí prosím někdo?

Btw google mi funguje, ale nenašel jsem odpověď. Ukázku kódu přikládám očesanou o zachytávání vyjímek a jiné pro tento účel nepodstatné vaty

Díky.

  
   $q="SELECT pripona FROM documenty WHERE UID=N'".$fullPath."'";
  $result = sqlsrv_query($conn,$q);
  $row = sqlsrv_fetch_array($result);
  $ext=$row[0];
  
  $q = "SELECT  obsah FROM dokumenty WHERE UID=N'".$fullPath."'";
  $doc='';
  $result = sqlsrv_query($conn,$q);
  $stream= sqlsrv_get_field( $result, 0, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
  while(!feof($stream)){
    $doc.= fread($stream, 10240);
  }
  $docLen = strlen($doc);
      
  header("Pragma: public"); //vypnutí cache pro proxy servery atp. pro HTTPverze 1.0
  header("Expires: 0"); //datum expirace - nastavení na ihned
  header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); //opět vypnutí cache; pro HTTP verze 1.1
  header('Content-Description: File Transfer');
  header("Content-type: application/force-download");
  header('Content-Length: ' . $docLen);
  header('Content-Disposition: attachment; filename='.$fullPath.$ext);
  echo $doc;
Keeehi
Profil
tom.rossi:
Je velikost souboru správná?
Proč soubory vůbec cpete do databáze a nenecháte je normálně v nějaké složce?
tom.rossi
Profil *
Keeehi:
Správná otázka, kterou jsem zadavateli položil samozřejmě také a několikrát jsem se ho snažil bezúspěšně přesvědčit o výhodách alternativního řešení. Bohužel s tím nic opravdu neudělám a tudíž se rozebíráním důvodů proč to rve do DB nechci zde zdržovat. Jak jsem psal zadání je dané a neměnné a já se snažím najít funkční řešení.

Ano velikost souboru je správná. Obsah se zobrazí, ale je nečitelný. Změť znaků. Pdf fungují bez problémů. Potíže jsou "jen" v případě doc, docx, xls, xlsx, které jsou - jak jinak, že? - v převaze


Po otevření vidí uživatel neco takoveho:
ĐĎࡱá>ţ˙ >ţ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ý˙˙˙A•

 !"#$%&'()*+,-./0123456789:;<=ţ˙˙˙ţ˙˙˙@ţ˙˙˙ţ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙Root Entry˙˙˙˙˙˙˙˙ ŔFŕ÷u÷/Đ?ŔWorkbook˙˙˙˙˙˙˙˙ŞvSummaryInformation(˙˙˙˙äDocumentSummaryInformation8˙˙˙˙˙˙˙˙˙˙˙˙  «Í•Áá°Áâ\pjanikt B°aŔ=śŻĽ=đ-Ě`…/8X@Ť"·Ú1ܐîJ•Calibri1ܐîJ•Calibri1ܐîJ•Calibri1ܐîJ•Calibri1ܐîJ•Calibri1h8ĽîJ•Cambria1,8ĽîJ•Calibri18ĽîJ•Calibri1Ü8ĽîJ•Calibri1ܐîJ•Calibri1ܐîJ•Calibri1Ü<îJ•Calibri1Ü>îJ•Calibri1Ü?ĽîJ•Calibri1Ü4ĽîJ•Calibri1Ü4îJ•Calibri1Ü ĽîJ•Calibri1Ü
Kajman
Profil
tom.rossi:
V proměnné $fullPath mohou být jen ascii znaky (s výjimkou bílých znaků)?

Soubor zobrazujete v prohlížeči nebo ukládáte na disk? Při uložení souhlasí počet bytů s originálem, ale obsah je jiný?

Změní se něco, pokud místo fread použijete fpassthru?
tom.rossi
Profil *
Kajman:
Předně díky za reakce!
K námětům:
ad1) ve $fullPath je například toto {FC55C440-2F20-4BAB-BBEA-CA580C8A402D} (je to UID toho fajlu v DB, k dispozici mám jen 4 sloupce přičemž jako identifikátor je použitelný pouze tento - nejsem autorem, jen nešťastným dědicem), do názvu fajlu v řádku 22 (myšleno řádek v ukázce kódu v mém prvním příspěvku) můžu použít cokoliv třeba 'soubor.xls' a výsledek je stejný.
ad2) soubor otevírám podle hlavičky v default app.
ad3) při použití passthru se to chová stejně


Kajman:
Při uložení souhlasí počet bytů s originálem, ale obsah je jiný?
Obsah bude počítám identický jen se zobrazí jako rozsypaný čaj. Velikost sedí. Zkoušel jsem různé hlavičky, ale nikam to nevedlo. Zaráží mne, že některé doc se zobrazují, pdf zatím všechny, ale u "excelů" je to beznadějně ze 100% špaténka.
Keeehi
Profil
tom.rossi:
Obsah bude počítám identický jen se zobrazí jako rozsypaný čaj.
Počítáš, nebo to stoprocentně víš? Kdyby byl identický, tak se bude zobrazovat správně. Jak to vidím já, tak ty soubory jsou nějak lehce pozměněné (kus jim chybí nebo přebývá) a evidentně pdf formát je více tolerantní k určitým chybám, ale je velmi pravděpodobné, že stejný typ chyby je i v těcho souborech. Jen se s tím prostě pere lépe.
tom.rossi
Profil *
Chlapi je to vyřešené. Kajman mě nakopl správným směrem. Zkusil jsem odstranit hlavičky a řádky 16-23 jsem nahradil tímto:
file_put_contents("$path/$fullPath$pripona",$dokum)
tzn. místo otevírání to ukládám do souboru. Výsledek je potom přesně takový, jaký má být=> takže problém s hlavičkama tipuju, ale nebudu tím zabíjet dál čas. Takže kompromisní řešení. Žádné rozmazlování uživatele a otevírání v default aplikaci na kliknutí, ale pěkně nejdřív vygenerovat soubor z db někam na server a pak si pěkně kliknout na download a pak už jen sociální jistoty a pozitiva. Krkolomné, ale funguje. Díky moc oběma za snahu. Rady nasměrovaly!


Jo a kdyby se tím chtěl někdo náhodou inspirovat, tak jsem zapomněl poznamenat, že $path je absolutní cesta k tomu výslednému souboru (ale myslím, že to stejně každému dojde). Samým nadšením jsem to zapomněl upravit do obecně srozumitelné formy.


Takže pokud by někdo řešil něco podobného, tak celý fungující kód je:
  $q="SELECT pripona FROM documenty WHERE UID='".$fullPath."'";
  $result = sqlsrv_query($conn,$q);
  $row = sqlsrv_fetch_array($result);
  $ext=$row[0];
  
  $q = "SELECT  obsah FROM dokumenty WHERE UID='".$fullPath."'";
  $doc='';
  $result = sqlsrv_query($conn,$q);
  $stream= sqlsrv_get_field( $result, 0, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
  while(!feof($stream)){
    $doc.= fread($stream, 10240);
  }
  file_put_contents("$fullPath$ext",$doc); // predpoklada se, ze stejne jako u mne je $ext vc. tecky

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: