Slik programmerer du med Yii2 Laster opp filer

Hva du skal skape

Hvis du spør, "Hva er Yii?" sjekk ut min tidligere opplæring: Introduksjon til Yii Framework, som vurderer fordelene med Yii og inneholder en oversikt over hva som er nytt i Yii 2.0, utgitt i oktober 2014.

I denne Slik programmerer du med Yii2-serien, veileder jeg lesere i bruk av Yii2 Framework for PHP. I denne veiledningen vil jeg veilede deg gjennom det grunnleggende om å laste opp filer og bilder i Yii2. 

For disse eksemplene fortsetter vi å forestille oss at vi bygger et rammeverk for å legge ut enkle statusoppdateringer, f.eks. vår egen mini-Twitter. Bildet over viser at du skriver en kort oppdatering mens du laster opp et bilde jeg tok av Taj Mahal.

Bare en påminnelse, jeg deltar i kommentar tråder nedenfor. Jeg er spesielt interessert hvis du har forskjellige tilnærminger, flere ideer eller ønsker å foreslå emner for fremtidige opplæringsprogrammer. Hvis du har et spørsmål eller et emneforslag, vennligst legg inn under. Du kan også nå meg på Twitter @ reifman direkte.

Filopplastingsprogrammer

Det er to filopplastingsplugger for Yii2 som synes mest robuste:

  1. FileInput Widget av Kartik Visweswaran (vist over)
  2. 2Amigos BlueImp File Uploader (en wrapper for BlueImp JQuery File Uploader) 

For denne opplæringen bestemte jeg meg for å fortsette med Kartiks plugin. Jeg fant det enklere å bruke og bedre dokumentert enn 2Amigos-plugin. BlueImp File Uploader har imidlertid noen spennende brukeropplevelsesfunksjoner som du kanskje vil utforske (vist nedenfor):

Arbeider med FileInput-plugin

La oss begynne å installere og gjøre bruk av filopplasteren og integrere den i vår Twitter-lignende statusopprettingsapplet. Igjen, vi bruker Yii2 Hello-applikasjonstreet som du kan laste ned med GitHub-knappen ved siden av eller under.

Installere plugin

Først kan vi bruke komponist til å legge til Kartik-v / yii2-widget-fileinput til vår søknad:

$ komponent krever kartik-v / yii2-widget-fileinput "*" ./composer.json har blitt oppdatert Laster kompositorbeholdninger med pakkedata Oppdatere avhengigheter (inkludert krav-dev) - Oppdaterer kartik-v / yii2-widget-filinput (dev -master 36f9f49 => v1.0.4) Sjekk ut 36f9f493c2d814529f2a195422a8af2e020fc80c Skrive låsfil Generere autoload-filer 

Utvider statustabellen

Deretter må vi legge til felt for filen vi skal laste opp til vårt Status-tabell. I dette eksemplet lar brukeren laste opp et bilde for å fortsette med statusoppdateringen.

Feltene vi legger til, er for de opplastede filenees originale filnavn, samt et unikt filnavn som vil bli lagret på vår server for visning:

  • image_src_filename
  • image_web_filename

Opprett en ny migrasjon for å legge til disse feltene i statustabellen:

$ ./yii migrere / opprett extend_status_table_for_image Yii Migreringsverktøy (basert på Yii v2.0.6) Opprett ny migrasjon '/Users/Jeff/Sites/hello/migrations/m160316_201654_extend_status_table_for_image.php'? (ja | nei) [nei]: ja Ny migrasjon ble opprettet.

Her er den tilpassede overføringen for å legge til de to feltene som strenger:

db-> drivernavn === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> addColumn ('% status', 'image_src_filename', Skjema :: TYPE_STRING. 'NOT NULL'); $ this-> addColumn ('% status', 'image_web_filename', Skjema :: TYPE_STRING. 'NOT NULL');  offentlig funksjon ned () $ this-> dropColumn ('% status', 'image_src_filnavn'); $ Dette-> dropColumn ( '% status', 'image_web_filename'); returner falsk; 

Kjør deretter overføringen:

$ ./yii migrere / opp Yii Migreringsverktøy (basert på Yii v2.0.6) Totalt 1 ny migrasjon som skal brukes: m160316_201654_extend_status_table_for_image Bruk overføringen ovenfor? (ja | nei) nei: ja *** bruker m160316_201654_extend_status_table_for_image> legg til kolonne image_src_filename streng IKKE NULL til tabell % status ... ferdig (tid: 0.044s)> legg til kolonne image_web_filename streng IKKE NULL til tabell % status ... ferdig (tid: 0.011s) *** brukt m160316_201654_extend_status_table_for_image (tid: 0.071s) Migrert opp med hell.

Siden Yii2 er bygget med en MVC-arkitektur (Model View Controller), er det tre andre kodingsområder som vi må implementere for filopplasteren:

  1. Statusmodellen
  2. Statusvisningen og skjemaet
  3. Statuskontrolleren

Forbedre modellfunksjonaliteten

Nå skal vi gjøre endringer i /models/Status.php fil. Først og fremst må vi gi attributter og valideringsregler for de nye bildefeltene, samt de midlertidige $ bilde Variabel widgeten vil bruke til å laste opp filen.

Nedenfor legger vi til kommentarer til de to nye $ image_xxx_filename variabler og opprett en offentlig midlertidig variabel som heter $ bilde:

/ ** * Dette er modellklassen for tabell "status". * * @property heltall $ id * @property streng $ melding * @property heltall $ tillatelser * @property streng $ image_src_filnavn * @property streng $ image_web_filename * @property heltall $ created_at * @property heltall $ updated_at * @property heltall $ created_by * * @property Bruker $ createdBy * / class Status utvider \ yii \ db \ ActiveRecord const PERMISSIONS_PRIVATE = 10; const PERMISSIONS_PUBLIC = 20; offentlig $ image;

Deretter legger vi til valideringsregler for bildet vårt, for eksempel filtype og maksimal størrelse:

offentlige funksjon regler () return [[['message'], 'required'], [['message'], 'string'], [['permissions', 'created_at', 'updated_at', 'created_by'] , 'integer'], [['bilde'], 'sikkert'], [['bilde'], 'fil', 'utvidelser' => 'jpg, gif, png'], [['bilde'] 'fil', 'maxSize' => '100000'], [['image_src_filename', 'image_web_filename'], 'streng', 'max' => 255],]; 

Og nye attributtetiketter for visninger:

 offentlig funksjon attributtLabels () return ['id' => Yii :: t ('app', 'ID'), 'message' => Yii :: t ('app', 'Message'), 'permissions' Yii :: t ('app', 'Filnavn'), 'image_web_filename' => Yii :: t ('app', 'Pathname' '),' created_by '=> Yii :: t (' app ',' Opprettet av '),' created_at '=> Yii :: t (' app ',' Created At '),' updated_at '=> Yii: : t ('app', 'Oppdatert på'),]; 

Nå kan vi gå videre til Vis endringer i ActiveModel-skjemaet.

Legge til vår visning og formfunksjonalitet

Integrering av bildeopplasting til statusopprettingsskjemaet

For å aktivere formintegrasjonen av bildeopplasting til Statusoppdateringer (vist ovenfor), må vi gjøre endringer i /views/status/_form.php fil. 

Først inkluderer vi Kartik \ fil \ FileInput widget nær toppen og oppdater skjemaet for å bli flerart, som støtter å legge inn filer:

 
[ 'Enctype' => 'multipart / skjema-data']]); // viktig?>

Deretter legger du til FileInput-widgeten mellom Tillatelser-feltet og Send-knapper:

feltet ($ modell, 'tillatelser') -> dropDownList ($ model-> getPermissions (), ['prompt' => Yii :: t ('app', '- Velg dine tillatelser -')]) 
felt ($ modell, bilde) -> widget (FileInput :: klassenavn (), ['options' => ['accept' => 'image / *'], 'pluginOptions' => ['allowedFileExtensions' => ['jpg', 'gif', 'png'], 'showUpload' => false,],]); ?>
erNewRecord? Yii :: t ('app', 'Create'): Yii :: t ('app', 'Update'), ['class' => $ model-> erNewRecord? 'btn btn-suksess': 'btn btn-primary'])?>

I pluginOptions linje, begrenser vi filtyper til vanlige bildeformater som jpg.

Når det er fullført, ser det ut som dette, og venter på at brukeren skal legge til et bilde:

Viser bildet

Jeg skal også legge til kode for å vise det opplastede bildet for senere (når vi har fullført kontrollerstøtten). 

Først legger jeg det til på statusvisningssiden (/views/status/view.php), som er veldig grunnleggende. Imidlertid vil jeg vise bildet under elementets detaljer:

 $ model, 'attributes' => ['id', 'createdBy.email', 'message: ntext', 'permissions', 'image_web_filename', 'image_src_filename', 'created_at', 'updated_at',],])? > image_web_filename! = ") echo '

'; ?>

Det vil se slik ut:

Vi legger også til en liten miniatyrvisning på vår Statusindeks-side (/views/status/index.php). Jeg har lagt til en tilpasset kolonneattributt til Yii2s GridView-widget:

 $ dataProvider, 'filterModel' => $ searchModel, 'columns' => [['class' => 'yii \ grid \ SerialColumn'], 'id', 'melding: ntext', 'tillatelser', 'created_at' ['attribute' => 'Image', 'format' => 'raw', 'value' => funksjon ($ modell) if ($ model-> image_web_filename! = ") returnere ' '; ellers returner ingen bilde;,], [' class '=>' yii \ grid \ ActionColumn ',' template '=>' view update delete ',' buttons '=> [' view '=> funksjon ($ url, $ modell) return Html :: a ('',' status /'.$ modell-> slug, ['title' => Yii :: t ('yii', 'View'),]); ],],],]); ?>

Til syvende og sist vil det se slik ut:

Å bygge kontrollerstøtten

For å gjøre alt ovenfor mulig, må vi fullføre kontrollerintegrasjonen. 

På toppen av /controllers/StatusController.php, vi må inkludere Yii \ web \ UploadedFile:

Da må vi oppdatere actionCreate funksjon:

offentlig funksjon actionCreate () $ model = new Status (); if ($ model-> load (Yii :: $ app-> request-> post ())) $ image = UploadedFile :: getInstance ($ modell, 'bilde'); hvis (! er_null ($ bilde)) $ model-> image_src_filename = $ image-> navn; $ ext = end ((eksplodere (".", $ bilde-> navn))); // generere et unikt filnavn for å hindre dupliserte filnavn $ model-> image_web_filename = Yii :: $ app-> security-> generateRandomString (). ". $ ext"; // banen for å lagre filen, kan du sette en opplastingPath // i Yii :: $ app-> params (som brukt i eksempel nedenfor) Yii :: $ app-> params ['uploadPath'] = Yii :: $ app -> basePath. '/ Web / opplasting / status /'; $ path = Yii :: $ app-> params ['uploadPath']. $ Modell> image_web_filename; $ Bilde-> saveas ($ bane);  hvis ($ model-> save ()) return $ this-> omdirigere (['view', 'id' => $ model-> id]);  ellers var_dump ($ model-> getErrors ()); dø();  returnere $ this-> render ('create', ['model' => $ modell,]); 

I hovedsak utfører dette følgende operasjoner:

  1. Vi tar opp det opprinnelige filnavnet fra den opplastede filens skjemainformasjon (image_src_filename).
  2. Vi genererer et unikt filnavn for vår server (image_web_filename).
  3. Vi lagrer filen til vår opplastings katalog (/ Web / uploads / status /).
  4. Vi lagrer modellen.
  5. Vi omdirigerer til den forbedrede visningssiden.

Du kan se de endelige resultatene med bildet ovenfor, som inkluderer et bilde av Taj Mahal.

Kartiks filinndatamodul tilbyr også mer avanserte konfigurasjoner som han dokumenterer ganske bra, for eksempel Drag og Drop:

Sjekk flere av disse på følgende sider:

  • FileInput Widget Demo
  • Last opp fil i Yii 2 ved hjelp av FileInput-widgeten
  • Avansert opplasting med Yii2 FileInput-widget 

Hva blir det neste?

Jeg håper dette hjelper deg med grunnleggende om filopplasting i Yii2-programmet. Hvis du vil se en annen lignende gjennomgang av denne typen funksjonalitet, kan du sjekke ut Bygg opp oppstarten med PHP: Brukerinnstillinger, Profilbilder og Kontaktdetaljer. Denne opplæringen gir en litt annen integrering enn denne opplæringen, ved hjelp av faner, oppdatering av brukerprofiler og skalering av bildene.

Se etter kommende opplæringsprogrammer i hvordan jeg programmerer med Yii2-serien når jeg fortsetter å dykke inn i ulike aspekter av rammen. Du vil kanskje også sjekke ut Bygg opp din oppstart med PHP-serien, som bruker Yii2s avanserte mal, da jeg bygger en applikasjon i virkeligheten.

Hvis du vil vite når neste Yii2 opplæring kommer, følg meg @ reifman på Twitter eller sjekk min instruktørside. Min instruktørside vil inkludere alle artiklene fra denne serien så snart de er publisert. 

Relaterte linker

Her er en rekke lenker som jeg pleide å undersøke og skrive denne opplæringen:

  • Yii2 Developer Exchange, min Yii2 ressurs side
  • FileInput Widget Demo by - Kartik
  • Last opp fil i Yii 2 ved hjelp av FileInput-widgeten - Kartik
  • Kode for kartik-v / yii2-widget-filinngang (GitHub)
  • BlueImp JQuery Fil Last opp demo
  • Kode for 2 amigos /yii2-file-upload-widget: BlueImp File Upload Widget (Github)
  • Laster opp filer - Den Definitive Guide to Yii 2.0