Autor | Zpráva | ||
---|---|---|---|
maycza Profil |
#1 · Zasláno: 23. 3. 2015, 08:21:00
Zdravím,
chtěl bych se zeptat, máte někdo zkušenosti s nahráváním souborů do ms sql databáze? Data ukládám do sloupce typu varbinary(max) . Mám kód:
$content=file_get_contents($_FILES["soubor"]["tmp_name"]); $content=base64_encode($content); $q="INSERT INTO files (name,size,type,content,znak)VALUES('".htmlspecialchars($soubor_name)."','$soubor_size','$soubor_typ',CONVERT(varbinary(MAX), '$content'),'c')"; $d=odbc_exec($db, $q); Data se bez problémů uloží. Problém nastává při výpisu dat, pro který používám následující kód: $db = odbc_connect('Driver=TDS;Server=nejakyServer;', 'jmeno', 'heslo'); if($db === false) {echo "Chyba připojení k databázi";} $q=odbc_exec($db,"SELECT name, type, size, CONVERT(varbinary(MAX),content) AS content FROM files WHERE id=".$_GET["id"]); while($r=odbc_fetch_array($q)){ $name=$r["name"]; $size=$r["size"]; $velikost=$r["content"]; $type=$r["type"]; $content=base64_decode($r["content"]); } header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified header("Content-length: " . $size); header("Content-type: " . $type); header("Content-Disposition: attachment; filename={$name}"); header("Content-Transfer-Encoding: binary"); print($content); Dalo by se říct, že všechno funguje, ale... pokud jsou data < 8kB vše je ok, pokud jsou větší, vypíše se jen část (do 8kB) a tím pádem se data stávají nečitelnými. Když si nechám vypsat jen surová data ze sloupce content , vypíše se vždy jen jejich část, vždy se to utne na stejném místě (omezení 46000). Pokud v databázi spustím dotaz SELECT LEN(content) FROM tabulka zjistím, že soubor má mnohem víc znaků než 46000.
Zjistil jsem, že MS SQL managenet studio má záměrně omezení pro výpis dat 8kB / 46000 znaků, čemuž rozumím, proč ale nemůžu z databáze dostat celý obsah sloupce content pomocí php?
|
||
Časová prodleva: 3 dny
|
|||
maycza Profil |
#2 · Zasláno: 26. 3. 2015, 12:47:07
Kdyby to náhodou někdy někdo řešil, tak doporučuju tento odkaz. Je sice starší, ale mě to pomohlo. Jen jsem musel změnit typ sloupce
content z varbinary(max) na image .
Nahrávání souborů zůstalo jak je, pro stažení souboru jsem si upravil kód z článku (komentáře jsou původní): if (isset($_GET["file"])){$id_priloha=$_GET["file"];} $dbconnect = odbc_connect('Driver=TDS;Server=servername;', 'user', 'password'); if($dbconnect === false) {echo "Chyba připojení k databázi";} $data=""; $blok_dat=512; //data budeme z databáze číst po 512 b if (isset($id_priloha) and is_numeric($id_priloha)){ $query="SELECT size, name, type FROM table_name.files WHERE id=".$id_priloha; $soubory=ODBC_exec($dbconnect,$query); while ($r=odbc_fetch_array($soubory)){ $velikost=$r["size"]; $jmeno=$r["name"]; $mime_type=$r["type"]; } $p=0; //$p označuje pozici, odkud se začneme binárně soubor z databáze číst (pokud 0, tak od začátku) //zjištění ukazatele a dalších pomocných proměnných $sql="SELECT TEXTPTR(content) as textptr, DATALENGTH(content) as blobsize, $p as chunkindex, CASE WHEN $blok_dat< DATALENGTH(content) THEN 512 ELSE DATALENGTH(content) END as chunksize FROM table_name.files WHERE id=".$id_priloha; $rs=ODBC_exec($dbconnect,$sql); while ($r=odbc_fetch_array($rs)){ //načtení výsledků z dtb do proměnných $textptr=bin2hex($r["textptr"]); //ukazatel (musí být binární) na pozici souboru $blobsize=$r["blobsize"]; //definuje celou velikost souboru $chunksize=$r["chunksize"]; //definuje po kolika bitech se bude načítat soubor //Soubor je nutné načítat po blocích! Nelze najednou… chunksize je velkost bloku $chunkindex=$r["chunkindex"]; //def. pozici, odkud se začíná číst blok dat (jehož velikost def. $chunksize } //================= if ($textptr<>""){ //jestliže je nalezen ukazatel while (($chunkindex<$blobsize)){ //tento cyklus postupně načte všechna data if (($chunkindex+$chunksize)>$blobsize){ /* kdybychom chtěli načíst větší blok, než jaký můžeme => pak je nutné vzít jako blok přesnou velikost toto typicky nastane tehdy, je-li max. možná délka načítaných dat menší, než udává proměnná $blok_dat */ $chunksize=$blobsize-$chunkindex; } //celý princip je o tom, že SQL server není schopen vrátit víc jak 2048bitů. //Proto tedy /po námi stanoveném kroku v proměnné proměnná $blok_dat (512b)/ //čteme celý soubor část po části a následně tyto bloky spojujeme do celku $sql2="set textsize 512 READTEXT table_name.files.content 0x".$textptr." $chunkindex ".($chunksize-$p).""; //nezapomeňme, že proměnná $p označuje počáteční pozici čtení dat; $rs2=ODBC_exec($dbconnect,$sql2); //přilepení bloku dat ke stávajícím while ($r=odbc_fetch_array($rs2)){ $data.=$r["content"]; } //navýšení indexu =>abychom četli následující blok dat $chunkindex=$chunkindex+$chunksize; } } //a máme načtená data //odešleme HTTP hlavičku 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: $mime_type"); header("Content-Length: " . $velikost); header("Content-Disposition: attachment; filename=" . $jmeno); // a nyní odešleme data prohlížeči echo base64_decode($data); exit(); } |
||
Časová prodleva: 10 let
|
0