[PHP]Hjälp med uppladdning och och returnering av textfil

Permalänk
Medlem

[PHP]Hjälp med uppladdning och och returnering av textfil

Jag funderar på hur jag ska göra ett säkert uppladdningsscript för textfiler.
Jag vill ju till exempel inte att någon ska kunna ladda upp någon PHP-fil exempelvis. Räcker det verkligen med att bara kolla filändelsen då? Vad finns det för mer sätt man kan kolla den den uppladdade filen innan den sparas på servern?
Man kanske kan spara filen under www-rooten och sedan hämta innehållet med file_get_contents() för att öka säkerheten?

Sedan skulle jag vilja kunna returnera filen med ett annat filnamn än det namnet som den har. Jag vill ha lite struktur på filerna och kommer därför att döpa dem enligt följande: id.attribut.filändelse
Men sedan när de ska laddas ner så ska den hämta ett filnamn från databasen och sedan ska det se ut som filen heter så när den skickas till användaren. Hur gör man detta?

Visa signatur

Bloggar om Hemautomation på HomeAutomateIt.com

Permalänk
Medlem

Så länge du skickar filen till användaren med filtypen text/plain till användaren spelar det ingen roll om vad den innehåller. Därför behöver du heller inte kolla något innan du sparar den på servern. Däremot bör du inte spara filen med dess rätta filändelse utan lägga till .txt så att uppladdade filer inte kan köras på servern.

Alltså; låt användarna ladda upp en fil till din server, vilken som helst. Filens ursprungliga namn sparar du i en databas, tillsammans med ett unikt ID (och eventuellt attribut, men det låter onödigt). Själva filen sparar du som id[.attribut].txt

När någon sedan hämtar hem filen levererar du den som mimetyp text/plain med filnamnet som sparades i databasen. Om du vill tvinga .txt på slutet är det ju bara att göra det.

Permalänk
Medlem

Semi-pseudo-kod för att skicka filen så som azoapes beskrev det:

// Hämta först originalfilnamnet ur databasen, beroende på ett ID från t.ex. $_GET['id'] (kör mysql_real_escape först)... // Skicka användaren till en annan sida med en Location-header om ID är ogiltigt. (T.ex. filen finns inte i databasen) header('Content-type: text/plain'); header('Content-Disposition: attachment; filename="'.$originalfilnamn.'"'); readfile('sökväg/till/upplagda/filer/'.$originalfilnamn.'.txt');

Permalänk
Medlem

Okej, tack!

Skulle behöva lite hjälp med ett reg exp också.
Skulle vilja matcha strängen /<id>/<filnamn>.<filändelse>

I id ska endast vara siffor
I filnamnet ska väll de flesta tecken vara tillåtna
I filändelsen ska jag kunna välja vilka som ska tillåtas, t.ex. .txt, .log m.m.
Jag vill även kunna plocka ut alla dessa värden och använda de i scriptet

Mitt försök:
^/[0-9]/[a-zA-Z0-9._-]+(\.srt|\.sub|\.rar)$

Visa signatur

Bloggar om Hemautomation på HomeAutomateIt.com

Permalänk
Medlem

Angående regexp-uttrycket; det finns bra verktyg som testar dina regexp-uttryck. Kolla på dessa två;
http://www.radsoftware.com.au/regexdesigner/
http://www.weitz.de/regex-coach/

Permalänk
Medlem

Hum..

Laddade ner Rad software regex designer.
I programmet verkade regexen funka prima men inte i php-koden :S

if (!preg_match('^/([0-9])/([a-zA-Z0-9._-])+(\.txt)$', '/1/textfil.txt', $matches)) exit('error! ');

Jag får upp massa varningar. I exemplet ovan får jag:
Warning: preg_match() [function.preg-match]: No ending delimiter '^' found in /home/swepiracy_nu/www/sub.php on line 17

Visa signatur

Bloggar om Hemautomation på HomeAutomateIt.com

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av pekz0r
...

Det är skillnad på syntax i ereg_* och preg_* tror jag... testa med den andra, programmet du använder kanske kör på den syntaxen istället.

(preg_* = PERL Regexp, ereg_* = POSIX Extended Regexp)

Permalänk
Hedersmedlem

Du har missat / på slutet av regexet.
if (!preg_match('^/([0-9])/([a-zA-Z0-9._-])+(\.txt)$'/, '/1/textfil.txt', $matches))
exit('error! ');

Edit: Före också.

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem

Njae det funkade inte heller.

Men jag lyckades lösa det till sist genom att läga till ":" före och efter:
if (!preg_match(':^/([0-9])/([a-zA-Z0-9._-])+(\.txt)$:', '/1/textfil.txt', $matches))
exit('error! ');

Tack så mycket för era svar!
Även om ni inte löser problemet helt så får man sig en tankeställare som gör att man kan lösa det på egenhand vilket nästan är bättre

Edit:
Det funkade visst inte riktigt som hag har tänkt ändå...
$matches[2] blir bara sista tecknet i filnamnet. Hur gör jag för att få ut hela?

if (preg_match(':^/([0-9])/([a-zA-Z0-9._-])+(\.txt|\.rar)$:', '/1/textfile.txt', $matches))

Visa signatur

Bloggar om Hemautomation på HomeAutomateIt.com

Permalänk
Hedersmedlem

Plusset måste ligga innanför parentesen. Alltså
([a-zA-Z0-9._-])+ blir
([a-zA-Z0-9._-]+)

Att / inte funkade beror på att du inte escapade de övriga (de inuti regexet), men det går ju som sagt lika bra med flera andra delimiters

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem

Aha
Det funkar ju alldeles utmärkt!
Tack så mycket!

Börjar få lite grepp på det här nu

Visa signatur

Bloggar om Hemautomation på HomeAutomateIt.com