Online bestandsopslag met PHP

In deze zelfstudie laat ik je zien hoe eenvoudig het is om een ​​online bestandsopslagsysteem met PHP te maken. Je leert hoe je bestanden kunt uploaden met PHP en ze kunt opsommen door de map "uploads" te scannen.

Invoering

Heb je ooit gewenst dat je een plaats had om bestanden te uploaden terwijl je onderweg was? Wat als u een openbare terminal of de computer van iemand anders gebruikt en geen software van derden voor bestandsoverdracht kunt installeren?
Zou het niet netjes zijn om gewoon een pagina in een browser te openen en uw bestand met één klik op de knop te uploaden?

Er zijn al veel sites voor het hosten van bestanden, maar in deze zelfstudie laat ik je zien hoe je je eigen kunt maken. Dit is wat we gaan creëren:

Stap 1 - Eenvoudige HTML

Laten we beginnen. Het eerste dat we nodig hebben, is een leeg HTML-document. Ik gebruik XHTML 1.0 Transitional met ISO-8859-1 tekenset. Als u wilt en geen speciale tekens nodig heeft, kunt u dit vervangen door de UTF-8-tekenset.

     Online bestandsopslag    

Stap 2 - Het bestandsuploadformulier toevoegen

Oké, nu we een eenvoudig HTML-bestand hebben, hebben we eigenlijk niets :) Dus laten we wat inhoud toevoegen. Ik pak alle inhoud in een DIV-element in om de pagina te verfraaien met CSS. De tags Fieldset en Legend zijn misschien wat zeldzaam, maar ze zijn wel de duidelijke markup voor het organiseren van content in groepen.

Ik heb een wachtwoordveld toegevoegd dat we zullen gebruiken om ongewenste uploaders weg te jagen, omdat we niet willen dat vreemden onze bestandsquota opvullen met willekeurige rommel.

Merk op dat in tegenstelling tot het standaard dagelijkse formulierelement, deze het enype heeft ingesteld op multipart / form-data.
Dit is nodig voor het POSTEN van bestanden en moet hier zijn. Ik heb de actiemodificator zodanig ingesteld dat deze naar hetzelfde bestand verwijst.
Wat dat betekent is dat zodra het formulier is ingediend, de formuliergegevens worden teruggezet naar dezelfde pagina.

Het verborgen veld MAX_FILE_SIZE is voor PHP en definieert de maximale grootte (in bytes) die we kunnen verzenden. Dit overschrijft echter niet de instelling MAX_FILE_SIZE in het bestand php.ini, dus dat is altijd degene die de maximale grootte bepaalt..

 

Online bestandsopslag

Voeg een nieuw bestand toe aan de opslag



Als we het bestand openen in een browser, hebben we nu een saaie en eenvoudige HTML-vorm. Het stuurt inhoud naar zichzelf maar weet niet wat ermee te doen.

We hebben een plaats nodig om de bestanden weer te geven die we al hebben geüpload; dus voeg de volgende html in de container-div toe onder de eerste veldset.

 
Eerder geüploade bestanden

Merk op dat de ongeordende lijst met de ID "bestanden" leeg is. Maak je daar nu geen zorgen over, want we vullen die sectie in met de bestanden op de server.

Stap 3 - CSS en JS toevoegen

Ik heb jQuery gebruikt om de mogelijkheid te creëren om de zichtbaarheid van bepaalde bestandstypen te wijzigen zonder de pagina te hoeven vernieuwen.
Dit is puur optioneel en het verwijderen van de JS zal het laden van de pagina iets versnellen. Dus laten we de volgende regels toevoegen aan de HEAD van het HTML-bestand.

  

Ik laad de jQuery tijdens runtime van een externe bron. Nogmaals, als u wilt, kunt u dit wijzigen zodat het bestand met deze lijn uit een lokale bron wordt geladen.

 

Het rechtstreeks laden van code.jquery.com zorgt ervoor dat we de nieuwste versie gebruiken en onze bandbreedte bij elke pagina wordt opgeslagen, maar als de code.jquery.com-server overvol of overvol zou zijn, krijgen we mogelijk niet het bestand wanneer we het nodig hebben.

Maak een nieuwe map met de naam style en maak er een nieuw CSS-bestand van met de naam style.css. Dit is het bestand dat de browser vertelt hoe we willen dat de pagina eruitziet. Er is nogal wat CSS hier, maar het is eenvoudig genoeg voor iedereen om te volgen.

Nu zou de pagina er ongeveer zo uit moeten zien te zien.

 @CHARSET "ISO-8859-1"; body achtergrondkleur: #cddcec; lettertype-familie: "Arial"; font-size: 11px;  div # container width: 600px; marge: 0px auto; rand: 1px vast # e6eef6; achtergrondkleur: #ffffff;  div # container h1 background-colour: # 4b75b3; marge: 0px; opvulling: 8px; lettertype-familie: "Arial"; font-gewicht: normaal; rand: 1px vast # 3564a9;  div # container-veldset margin: 20px; rand: 1px vast # 98b9d0;  ul # menu list-style-type: none; marge: 4px; opvulling: 0px;  ul # menu li float: links; marge: 4px;  ul # menu li.active background-color: # 98b9d0; border-left: 1px solid # 3564a9; border-top: 1px solid # 3564a9; border-bottom: 1px solid # e6eef6; border-right: 1px solid # e6eef6;  ul # menu li a text-decoration: none; lettergrootte: 10px; opvulling: 2px; kleur: # 3564a9;  ul # bestanden list-style-type: none; marge: 40px 0px 0px 0px; opvulling: 0px;  ul # bestanden li background-color: # fff7c0; border-bottom: 1px solid #efefef; opvulling: 2px; margin-bottom: 1px; 

Wat we nu zouden moeten hebben, wordt geïllustreerd in de volgende afbeelding.

Stap 4 - Behandeling van bestandsinvoerinzendingen met PHP

Laten we de PHP-kant van de zelfstudie starten door een klasse Settings te maken. In deze klasse kunnen we zowel het uploadwachtwoord als het bestandspad voor de uploadmap opslaan.
We kunnen de klas vervolgens opnemen in onze pagina en de waarden gebruiken wanneer dat nodig is.
Je kunt PHP-bestanden schrijven met vrijwel dezelfde gereedschappen die je gebruikt om HTML en CSS te schrijven, vergeet niet om het bestand met het achtervoegsel .php op te slaan.

 

Zonder dieper te gaan in Object Oriented Programming (OOP), wat de code doet, is dat het een nieuwe klasse creëert met het soort waarden waartoe toegang kan worden verkregen zonder de klasse te beïnvloeden.
We hebben nu toegang tot de waarden door simpelweg Instellingen :: $ wachtwoord aan te roepen; en Instellingen :: $ uploadFolder; Dit is ook de plaats waar u het wachtwoord kunt wijzigen wanneer u maar wilt.
De markeer het begin en het einde van een PHP codesegment. Deze segmenten kunnen in normale html-pagina's worden geschreven en de server zal ze interpreteren wanneer om de pagina wordt gevraagd.

Oké, nu komen we aan het werk. In het html-bestand waarmee we hebben gewerkt, voegen we het volgende toe helemaal bovenaan het bestand. Ja, voor de label.

  

Eerst vertellen we de PHP-interpreter om ons instellingenbestand op te nemen. Ik heb ook een nieuw variabele $ -bericht ingesteld. Later zal ik procesinformatie in deze variabele schrijven en deze aan de gebruiker tonen.

 // Heeft de gebruiker iets geüpload? if (isset ($ _ FILES ['file'])) 

Als het formulier is ingediend met een bestand, moet de array $ _FILE een waarde hebben met de sleutel die we hebben gebruikt als de naam van het bestandsinvoerveld..

 $ target_path = Instellingen :: $ uploadFolder; $ target_path = $ target_path. tijd (). '_'. basename ($ _FILES ['file'] ['name']);

Hier krijgen we het pad naar de uploadmap die we hebben opgegeven in de instellingen. Op regel 2 voegen we (aaneengeschakeld) de naam van het geüploade bestand toe aan het doelpad.
Merk ook op dat ik de huidige tijdstempel van de server heb toegevoegd aan het begin van de bestandsnaam. Er zijn twee redenen waarom ik dit doe.
Eerst wordt het gebruikt om de datum op te slaan en ten tweede zorgt het ervoor dat alle bestanden van verschillende namen zijn.
Als we een database achter deze toepassing gebruiken, zou de tijd van toevoegen er zijn en zouden we de bestandsnamen kunnen serialiseren en de originele naam alleen in de databasetabel kunnen opslaan,
maar omdat er geen database is, kunnen we deze tijdelijke oplossing gewoon gebruiken.

 // Controleer het wachtwoord om de legale upload te controleren als ($ _ POST ['wachtwoord']! = Instellingen :: $ wachtwoord) $ message = "Invalid Password!";  else 

Als de inzending is gedaan zonder een wachtwoord in te voeren of als het opgegeven wachtwoord iets anders was dan het wachtwoord dat in de instellingen is gedefinieerd, zullen we het bestand niet verwerken en alleen een bericht retourneren dat een vals wachtwoord aangeeft.

 // Probeer het geüploade bestand naar de opgegeven map te verplaatsen als (move_uploaded_file ($ _ FILES ['bestand'] ['tmp_name'], $ target_path)) $ message = "Het bestand". basename ($ _FILES ['file'] ['name']). "is geüpload";  else $ message = "Er is een fout opgetreden bij het uploaden van het bestand, probeer het opnieuw!"; 

Ok, dus het wachtwoord was goed, wat nu? Nu "opslaan" we het bestand. Ik zeg sparen tussen haakjes omdat het bestand eigenlijk al op de server staat; het zit gewoon in de tijdelijke map.
Dus om het bestand toegankelijk te maken en ervoor te zorgen dat de server het niet verwijdert wanneer de temp is gewist, moeten we het naar een veilige locatie verplaatsen. Ik heb de functie move_uploaded_file gebruikt.
De functie heeft twee argumenten nodig. Ten eerste is de tijdelijke naam van het bestand automatisch toegewezen door de server, en de andere is het doelpad dat we eerder hebben toegewezen.
De functie retourneert een Booleaanse waarde die een succesvolle bewerking aangeeft. We stellen opnieuw de berichtwaarde in om de gebruiker te informeren wat er is gebeurd.

 if (strlen ($ message)> 0) $ message = '

'. $ bericht. '

';

En zo eenvoudig is het om met PHP bestanden naar de server te uploaden! Hier heb ik net gecontroleerd of er iets is geschreven in de berichtvariabele (lengte meer dan 0) en formatteer het zodat we het kunnen stijlen met CSS.

Stap 5 - Maak een lijst van de geüploade bestanden

 / ** LIST UPLOADED FILES ** / $ uploaded_files = ""; // Open de map voor het lezen van $ dh = opendir (Instellingen :: $ uploadFolder);

Het eerste dat u moet doen, is een maphandvat maken. Het enige dat je hoeft te doen is één commando. De variabele uploaded_files is waar we de bestandsnamen van de mappen in HTML-formaat gaan schrijven.

 // LOOP door de bestanden terwijl (($ file = readdir ($ dh))! == false) 

Hier doorlopen we de bestanden in de map. Zolang we het volgende bestand in de map in de bestandsvariabele kunnen lezen, doen we dat en gaan we verder. Zodra we alle bestanden hebben doorlopen, retourneert de functie false en eindigt de lus.

 if ($ file! = '.' && $ file! = '...') 

De '.' en '...' worden ook geretourneerd door deze functie, dus we moeten ervoor zorgen dat we niets proberen te doen met die functie.

 $ filename = Instellingen :: $ uploadFolder. $ File; $ parts = explode ("_", $ bestand);

We voegen de naam van het bestand toe aan het pad van de map uploads en slaan het op als bestandsnaamvariabele. Vervolgens ontploffen we de naam van het bestand bij het teken '_'.
Deze functie retourneert een reeks tekenreeksen die de oorspronkelijke reeks splitsen telkens wanneer er een '_' is.
Omdat er een van die tekens is, ontvangen we een array met het tijdstempeldeel als cel 1 en de oorspronkelijke bestandsnaam als cel 2.

 $ size = formatBytes (bestandsgrootte ($ bestandsnaam)); $ added = date ("m / d / Y", $ parts [0]); $ origName = $ parts [1];

Nu we de tijdstempelwaarde hebben als een eigen string, kunnen we deze in een datum formatteren en de originele bestandsnaam opslaan als zijn eigen variabele.
De bestandsgrootte-functie van PHP retourneert de grootte van het bestand alleen in bytes, dus we zullen het in een beter leesbare vorm formatteren met de functie formatBytes, die een beetje is bedekt.

 $ filetype = getFileType (substr ($ file, strlen ($ file) - 3)); $ uploaded_files. = "
  • $ origName $ size - $ added
  • \ N ";

    Bij het uploaden van een bestand naar de server geeft PHP ons de informatie over het bestandstype, maar omdat we geen plaats hebben om die informatie op te slaan, moeten we proberen het bestandstype te krijgen met een aangepaste functie.
    Ik geef de drie laatste tekens van de bestandsnaam als een parameter voor de functie getFileType (wordt later weergegeven). Ik gebruik de variabele filetype om de verschillende bestanden met CSS te stijlen.
    Het enige dat nu overblijft, is een HTML-tekenreeks genereren en deze toevoegen aan de variabele uploaded_files en de map-handle sluiten.

      closedir ($ dh);
     if (strlen ($ uploaded_files) == 0) $ uploaded_files = "
  • Geen bestanden gevonden
  • ";

    Als er geen bestanden zijn gevonden, stelt u de geüploade_bestanden var in om een ​​bericht weer te geven.

    We moeten ook de tekenreeks geüploade bestanden ergens laten zien; dus voeg deze regel toe binnen de

      met de id 'bestanden'.

       

      Stap 6 - Hulpfunctie

      De functie getFileType probeert te raden welk type het bestand is door de laatste tekens van de naam te lezen. Dit werkt niet met extensies zoals .jpeg en .tiff.
      Om het universeler te maken, moeten we een subtekenreeks lezen die begint in de periode en aan het einde van de bestandsnaam.
      Maar als de naam zoiets als mijn.new.car.pic is, krijgen we new.car.pic als extensies.
      Dus om dit echt te laten werken, zouden we het moeten vinden laatste periode in de naam en neem een ​​subtekenreeks vanaf daar.
      Maar voor de reikwijdte van deze tutorial is dit voldoende dichtbij.

       functie getFileType ($ extensie) $ images = array ('jpg', 'gif', 'png', 'bmp'); $ docs = array ('txt', 'rtf', 'doc'); $ apps = array ('zip', 'rar', 'exe'); if (in_array ($ extensie, $ afbeeldingen)) geeft "Afbeeldingen" terug; if (in_array ($ extension, $ docs)) geeft "Documenten" terug; als (in_array ($ extensie, $ apps)) 'Toepassingen' wordt geretourneerd; terug ""; 

      Deze volgende functie formatteert de bytes in een beter leesbaar formaat. Gewoon elementaire wiskunde - niets meer. De functie zelf komt uit de opmerkingen van de PHP.net-functie.

       functie formatBytes ($ bytes, $ precision = 2) $ units = array ('B', 'KB', 'MB', 'GB', 'TB'); $ bytes = max ($ bytes, 0); $ pow = floor (($ bytes? log ($ bytes): 0) / log (1024)); $ pow = min ($ pow, count ($ units) - 1); $ bytes / = pow (1024, $ pow); return round ($ bytes, $ precision). ". $ units [$ pow];?>

      En dat is het voor het PHP-gedeelte. Nog wat meer JS en CSS en we zijn allemaal klaar.

      Stap 7 - Een vleugje CSS voor meer leesbaarheid

      Wat we tot nu toe hebben gezien, zou er als volgt uit moeten zien:

      Maar om goed gebruik te maken van de functie getFileType en de klassenaam die het retourneert, heb ik de volgende CSS-regels toegevoegd aan het bestand style.css.

       ul # bestanden li a text-decoration: none; kleur: # 3564a9; opvulling: 2px 25px; achtergrond-positie: links; achtergrondherhaling: geen herhaling;  ul # bestanden li.Documents a background-image: url ('... /images/text.jpg');  ul # bestanden li.Images a background-image: url ('... /images/picture.jpg');  ul # bestanden li.Applications a background-image: url ('... /images/zip.jpg');  p.error background-color: # fff7c0; border-bottom: 1px solid #efefef; lettertype: vet; kleur: # ff0000; opvulling: 6px; 

      Ik wijs een pictogram toe aan elk type bestand. De icoon's die ik heb gebruikt zijn van de prachtige collectie die te vinden is op http://www.famfamfam.com.
      Wat we zouden moeten hebben, is zoiets als dit.

      Ah, veel beter.

      Stap 8 - Zichtbaarheid van bestanden wijzigen met jQuery

      Voor een afrondingsbit voegen we wat extra functionaliteit toe met JavaScript. Maak een nieuwe map met de naam "js" en maak in die map een nieuw bestand, filestorage.js.
      Voeg vervolgens de volgende regel toe aan het einde van de HTML-pagina vlak voor de label.