NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Uložení souboru na disk s informací do databáze

V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
petr.jouza
Člen
Avatar
petr.jouza:5.10.2016 18:55

Ahoj,
hledám nějakou radu.

Řeším v PHP ukládání souboru na disk s tím, že informaci o souboru (cesta k souboru, typ, velikost) uložím do databáze a potřebuji vyřešit následující:
Soubory uložím na disk, kam uživatel nebude mít přístup načítat soubory bude jen prohlížeč (uživatel si samozřejmě bude moci soubor stáhnout a oprávněný uživatel ho bude moci i smazat), ale potřebuji, aby k němu nebyl klasický přístup.

Otázky tedy zní
Jak nastavit práva?
Jak řešit přístup PHP aplikace?
Jak ověřovat nahrávaný soubor (velikost, typ, název)?
Jsou na to nějaké PHP funkce?

S informacemi do databáze si už asi nějak poradím, ale nikde nemohu najít nějaký rozumný článek (kterému porozumím). Zde na IT network jsem našel jen nějaký hotový kód, ale bez vysvětlení.

Nakopne mě prosím někdo? Na jaké funkce se zaměřit? Jak nastavit filesystem? Nějaké odkazy na články které pomůžou? Nebo mi to někdo rovnou vysvětlí?

Ještě asi doplním, že používám XAMPP na Windows.

Jinak nejsem moc velký angličtin, tak pokud budou informace v češtině, tak to bude jedině veliké +

Předem moc díky.

 
Odpovědět
5.10.2016 18:55
Avatar
Eda Stehlík
Člen
Avatar
Eda Stehlík:5.10.2016 21:29

Bude tě citovat

nikde nemohu najít nějaký rozumný článek

Já mám spíš pocit, že ty jsi ani nehledal!
Rovnou na této stránce je spousta návodů a článků například:

A dále...

Zde na IT network jsem našel jen nějaký hotový kód, ale bez vysvětlení.

Popřípadě...

Nakopne mě prosím někdo? Na jaké funkce se zaměřit? Jak nastavit filesystem? Nějaké odkazy na články které pomůžou? Nebo mi to někdo rovnou vysvětlí?

Nikdo za tebe práci zdarma neudělá! Tak to bylo, je a bude!

 
Nahoru Odpovědět
5.10.2016 21:29
Avatar
petr.jouza
Člen
Avatar
petr.jouza:6.10.2016 7:02

Dovol mi ke tvému komentáři pár poznámek.

Jistě na této stránce http://www.itnetwork.cz/php/zaklady je spousta návodů a článků, ale ani jeden se nevěnuje problematice nahrávání souborů přes PHP na server a zabezpečení uložiště. Věci jako jsou proměnné, pole, cykly a pod... fakt řešit nepotřebuji.

Následující http://www.itnetwork.cz/php/databaze také nepotřebuji, s tím si poradím.

A poslední už vůbec nepotřebuji: http://www.itnetwork.cz/php/oop do objektového programování jsem se zatím nepustil a "projekt", který mám není na tolik složitý, abych se bez toho neobešel.

Teď budu citovat já tebe

Nikdo za tebe práci zdarma neudělá! Tak to bylo, je a bude!

Chce to snad někdo po někom?

Ze tvé reakce mi akorát přijde, že sis ani pořádně nepřečetl co jsem psal a o co žádám.

Snažím se najít radu typu: Tento problém řeší článek takový a makový nebo zaměř se na funkci/e XY...
Nechci tu dlouze konzultovat co a jak a vyřešte to někdo.

Něco málo už jsem našel, ale moc moudrý z toho nejsem. Asi jediný rozumný článek je tento: https://php.vrana.cz/…zivatele.php, ale není tam mnoho vysvětlení. (podobně jako ve zdejších tutoriálech).

 
Nahoru Odpovědět
6.10.2016 7:02
Avatar
Odpovídá na petr.jouza
Neaktivní uživatel:6.10.2016 9:04

Já bych to vzal podle těch otázek:

Jak nastavit práva?

Na jakém systému? Bude to složka na webhostingu nebo samostatný adresář na vlastním serveru?
Všeobecně potřebuješ mít k umístěný přístup pouze pro vlastníka (uživatel pod kterým běží webserver).

Jak řešit přístup PHP aplikace?

PHP interpreter běží většinou pod stejným uživatelem jako webserver takže viz výše.
V php.ini je nutné povolit nahrávání souboru a také tam jsou nastaveny limity pro maximální velikost nahrávaného souboru, ty je potřeba patřičně upravit nebo omezit povolenou velikost v odesílacím formuláři.

Jak ověřovat nahrávaný soubor (velikost, typ, název)?

Z proměnné $_FILES a kontrolou typu souboru.

Jsou na to nějaké PHP funkce?

Ano, php má funkce, proměnné a metody pro práci se soubory, které se ti hodí.
Odesílat soubor můžeš pomocí metody POST, kontrolovat můžeš podle dat v globální proměnné $_FILES a funkce mime_content_type a přesouvat do úložiště pomocí funkce move_uploaded_file.
Data pro db máš opět v proměnné $_FILES.

Ten článek od Jakuba je celkem dost vysvětlující, jaké informace ti tam chybí nebo co by jsi k tomu ještě potřeboval vědět?

Nahoru Odpovědět
6.10.2016 9:04
Neaktivní uživatelský účet
Avatar
petr.jouza
Člen
Avatar
Odpovídá na Neaktivní uživatel
petr.jouza:6.10.2016 16:32

Díky za informace...

Nyní to řeším na vlastním serveru s Windows. Mám nainstalovaný XAMPP, kde tedy běží APACHE. Řešil bych to asi v adresářové struktuře DocumentRoot (tedy výchozí adresář htdocs), kde bych vytvořil složku třeba soubory a tam bych při uploadu souboru vytvořil složku s ID položky a v té by byl soubor. Apache mi běží pod účtem Local Systém (automaticky spuštěná služba Windows.

V php.ini je v defaultu nastaveno:
post_max_size=8M
file_uploads=On
upload_tmp_dir="­C:\xampp\tmp"
upload_max_fi­lesize=2M
max_file_uploads=20

Zarazilo mě teď to post_max_size a upload_max_fi­lesize. Když nastavím upload_max_filesize třeba na 10M, tak musím zvětšit i post_max_size na 10M?

Tu proměnou $_FILES a podmínky pro ni asi dám nějak dohromady, ale spíše mě trápí ten přístup k souborům.
Napadlo mě, (ale nevím jestli to jde) ošetřit to pomocí .htacces a .htpasswd. Jestli jsem pochopil dobře, tak proměnná $_SERVER['REMO­TE_USER'] vrací uživatele, ale nevím jakou proměnnou bych použil pro heslo. Možná to je blbý nápad...

Potřeboval bych tedy, aby když jakýkoliv uživatel (ať přihlášený, tak nepřihlášený) zadá do prohlížeče adresu http://server.cz/…y/soubor.pdf se k souboru nedostal, ale pokud má oprávnění přistoupit ke stránce třeba http://server.cz/…ozadavku.php, kde se mu nabídne soubor ke stažení, tak aby soubor mohl stáhnout. Stránka detail-pozadavku.php by měla udělen přístup do složky soubory.
Když to tak vezmu, tak soubory nebudou nijak tajné a bude je moci zobrazit jakýkoliv uživatel, ale mazat je bude moci akorát ten, komu patří zadaná položka (to si ale ověřím).

Jinak asi ještě pro info: uživatele mám ve vlastní databázi... nepoužívám připojení na Active Directory. (i když to bych se chtěl také naučit) :-)

Ještě jednou díky za rady a nakopnutí.

 
Nahoru Odpovědět
6.10.2016 16:32
Avatar
Odpovídá na petr.jouza
Neaktivní uživatel:6.10.2016 23:26

V případě xampp na Windows a ukládání souborů do složky htdocs většinou není potřeba řešit práva, to přichází na řadu až v případě, kdy máš xampp nainstalovaný třeba v Program Files nebo jiné složce chráněné UAC.

K php.ini:
file_uploads=On - povolí nahrávání souborů
upload_tmp_dir="­C:\xampp\tmp" - určuje cestu pro dočasné uložení nahrávaného souboru
max_file_uplo­ads=20 - maximální počet souběžných uploadů
upload_max_fi­lesize=2M - maximální velikost nahrávaného souboru
post_max_size=8M - maximální objem všech dat odesílaných formulářem
memory_limit=128M - maximální velikost paměti využitelné jedním skriptem
max_input_time - maximální čas po který může skript parsovat data

Teď prakticky, pokud nastavíš upload_max_filesize na 10M, musíš nastavit post_max_size na víc než 10M, protože se do toho limitu počítá velikost odesílaného souboru + velikost dalších odesílaných dat z daného formuláře (třeba id uživatele, antispam a podobně). Samozřejmě je potřeba přizpůsobit podle potřeby i velikost memory_limit, protože do paměti se samozřejmě ta odesílaná data parsují a následně se pracuje třeba s nahraným souborem a dalšími daty. Nahrávání větších souborů samozřejmě trvá déle, proto je potřeba zkontrolovat i nastavení max_input_time (defaultní hodnota je -1 což znamená neomezeně, ale ne každý webhosting to tak má).

U proměnné $_FILES si dej hlavně pozor na $_FILES['user­file']['type'], protože je to nespolehlivé a dá se podvhrnout, protože je to závislé na tom, co php skriptu tvrdí uživatelův prohlížeč.

Pomocí .htaccess můžeš přesměrovat požadavek na jakýkoli soubor v určité složce na nějaký konkrétní php soubor se skriptem, kde budeš kontrolovat jestli je uživatel přihlášen a zda má potřebná práva pro stahování nebo mazání souboru. Ověření prováděj třeba pomocí dat v $_SESSION.

Nahoru Odpovědět
6.10.2016 23:26
Neaktivní uživatelský účet
Avatar
petr.jouza
Člen
Avatar
Odpovídá na Neaktivní uživatel
petr.jouza:7.10.2016 19:03

Díky za upřesnění. Zkusil jsem si s tím trochu pohrát a docela to chápu. Našel jsem ještě zajímavý článek zde: http://www.w3schools.com/…e_upload.asp

Jestli tedy chápu správně, tak stačí následující?
v cestě http://www.neco.cz/soubory (kde budou umístěny jen soubory) vytvořím .htaccess, kde budu mít:

RewriteEngine on
RewriteRule (.*) ../stranka.php [R]

stranka.php bude obsahovat něco, kde bude kontrola přihlášení a oprávnění, ale jak pak vytvořit odkaz ke stažení? klasické <a href="odkaz na soubor v soubory">Soubor</a> udělá přesměrování opět do stranka.php a uživatel je bez souboru.

Spíše mi nějak toto nejde do hlavy. Jak tedy udělat, aby nepřihlášený uživatel se k souboru nedostal přes přímý odkaz, ale aby měl po přihlášení možnost soubor stáhnout?

Je to vůbec nějak reálné?

Díky

 
Nahoru Odpovědět
7.10.2016 19:03
Avatar
Odpovídá na petr.jouza
Neaktivní uživatel:7.10.2016 23:25

.htaccess ve složce soubory by mohl být třeba nějak takhle

# zakáže vypsání obsahu složky do prohlížeče
Options -Indexes

RewriteEngine On

# pokud je požadován soubor
RewriteCond %{REQUEST_FILENAME} -f

# soubor s libovolným názvem a libovolnou koncovkou přesměruje na download.php
RewriteRule (.*)\.(.*)$ download.php [L]

V souboru download.php by pak bylo ověření uživatele, případně přesměrování na přihlášení a výběr souboru ke stažení. Soubor se pak dá uživateli odeslat nikoli přímým odkazem, ale třeba pomocí funkce readfile(), která je přímo v php.

<?php
$file = 'nazev_stahovaneho_souboru';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

Uvedené jsou jen příklady (příklad s readfile() je přímo z dokumentace php), ale principielně by to tak mohlo fungovat.

Nahoru Odpovědět
7.10.2016 23:25
Neaktivní uživatelský účet
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.