Hur man programmerar med Yii2 Överför filer

Vad du ska skapa

Om du frågar, "Vad är Yii?" kolla in min tidigare handledning: Introduktion till Yii Framework, som granskar fördelarna med Yii och innehåller en översikt över vad som är nytt i Yii 2.0, släppt i oktober 2014.

I det här Hur man programmerar med Yii2-serien, guidar jag läsare som använder Yii2 Framework for PHP. I denna handledning guidar jag dig igenom grunderna för att ladda upp filer och bilder i Yii2. 

För dessa exempel fortsätter vi att föreställa oss att vi bygger ett ramverk för att skicka enkla statusuppdateringar, t.ex. vår egen mini-Twitter. Bilden ovan visar att du skriver en kort uppdatering när du laddar upp en bild som jag tog av Taj Mahal.

Bara en påminnelse, jag deltar i kommentera trådarna nedan. Jag är särskilt intresserad om du har olika tillvägagångssätt, ytterligare idéer eller vill föreslå ämnen för framtida handledning. Om du har en fråga eller ett ämne förslag, vänligen posta nedan. Du kan också nå mig på Twitter @ reifman direkt.

Filuppladdningsprogram

Det finns två filuppladdningsprogram för Yii2 som verkar vara mest robusta:

  1. FileInput Widget av Kartik Visweswaran (visas ovan)
  2. 2Amigos BlueImp File Uploader (ett omslag för BlueImp JQuery File Uploader) 

För denna handledning bestämde jag mig för att fortsätta med Kartiks plugin. Jag fann det lättare att använda och bättre dokumenterade än 2Amigos-plugin. Dock har BlueImp File Uploader några intressanta användarupplevelsefunktioner som du kanske vill utforska (visas nedan):

Arbeta med FileInput-plugin

Låt oss börja installera och använda filuppladdaren och integrera den i vår Twitter-liknande statusskapande applet. Återigen använder vi Yii2 Hello applikationsträdet som du kan ladda ner med GitHub-knapplänken bredvid eller nedanför.

Installera plugin

Först kan vi använda kompositören att lägga till Kartik-v / yii2-widget-fileinput till vår ansökan:

$ composer kräver kartik-v / yii2-widget-filinput "*" ./composer.json har uppdaterats Laddar kompositregister med paketinformation Uppdatering av beroenden (inklusive krav-dev) - Uppdatering av kartik-v / yii2-widget-filinput (dev -master 36f9f49 => v1.0.4) Utcheckning 36f9f493c2d814529f2a195422a8af2e020fc80c Skriva låsfil Generera autoload-filer 

Expandera status tabellen

Därefter måste vi lägga till fält för filen vi ska ladda upp till vår Status-tabell. I det här exemplet låter vi användaren ladda upp en bild för att följa med sin statusuppdatering.

Fälten vi lägger till är för de uppladdade filernas ursprungliga filnamn och ett unikt filnamn som kommer att lagras på vår server för visning:

  • image_src_filename
  • image_web_filename

Skapa en ny migrering för att lägga till dessa fält i statustabellen:

$ ./yii migrera / skapa extend_status_table_for_image Yii Migrationsverktyg (baserat på Yii v2.0.6) Skapa ny migrering '/Users/Jeff/Sites/hello/migrations/m160316_201654_extend_status_table_for_image.php'? (ja | nej) [nej]: ja Ny migrering skapades framgångsrikt.

Här är den anpassade migreringen för att lägga till de två fälten som strängar:

db-> drivrutinName === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> addColumn ('% status', 'image_src_filename', Schema :: TYPE_STRING. 'NOT NULL'); $ this-> addColumn ('% status', 'image_web_filename', Schema :: TYPE_STRING. 'NOT NULL');  allmän funktion ner () $ this-> dropColumn ('% status', 'image_src_filename'); $ This-> dropColumn ( '% status', 'image_web_filename'); returnera false; 

Kör sedan migreringen:

$ ./yii migrera / uppåt Yii Migrationsverktyg (baserat på Yii v2.0.6) Totalt 1 ny migration som ska tillämpas: m160316_201654_extend_status_table_for_image Använd ovanstående migrering? (ja | nej) nej: ja *** tillämpning m160316_201654_extend_status_table_for_image> lägg till kolumn image_src_filename sträng INTE NULL till tabell % status ... gjort (tid: 0.044s)> lägg till kolumn image_web_filename sträng INTE NULL till tabell % status ... gjort (tid: 0.011s) *** tillämpas m160316_201654_extend_status_table_for_image (tid: 0.071s) Migrerad framgångsrikt.

Eftersom Yii2 är byggd med en MVC-arkitektur (Model View Controller), finns det tre andra kodningsområden som vi behöver implementera för filuppladdaren:

  1. Statusmodellen
  2. Statusvyn och formuläret
  3. Statuskontrollen

Förbättra modellfunktionaliteten

Nu gör vi ändringar i /models/Status.php fil. I första hand måste vi tillhandahålla attribut och valideringsregler för de nya bildfälten samt den tillfälliga $ image variabel widgeten kommer att använda för att ladda upp filen.

Nedan lägger vi till kommentarer för de två nya $ image_xxx_filename variabler och skapa en offentlig temporär variabel som heter $ image:

/ ** * Det här är modellklassen för tabell "status". * * @property heltal $ id * @property sträng $ meddelande * @property heltal $ behörigheter * @property sträng $ image_src_filnamn * @property sträng $ image_web_filename * @property heltal $ created_at * @property heltal $ updated_at * @property heltal $ created_by * * @property User $ createdBy * / class Status utökar \ yii \ db \ ActiveRecord const PERMISSIONS_PRIVATE = 10; const PERMISSIONS_PUBLIC = 20; offentlig $ bild;

Därefter lägger vi till valideringsregler för vår bild, till exempel filtyp och maximal storlek:

public function rules () return [[['' message '],' required '], [[' message '],' string '], [[' behörigheter ',' created_at ',' updated_at ',' created_by '] , 'integer'], [['bild'], 'säkert'], [['bild'], 'fil', 'extensions' => 'jpg, gif, png'], [['bild'] 'fil', 'maxSize' => '100000'], [['image_src_filename', 'image_web_filename'], 'sträng', 'max' => 255],]; 

Och nya attribut etiketter för visningar:

 public function attributeLabels () return ['id' => Yii :: t ('app', 'ID'), 'message' => Yii :: t ('app', 'Meddelande'), 'behörigheter' > Yii :: t ('app', 'behörigheter'), 'image_src_filename' => Yii :: t ('app', 'Filnamn'), 'image_web_filename' => Yii :: t ('app', 'söknamn 'created_by' => Yii :: t ('app', 'Skapad av'), 'created_at' => Yii :: t ('app', 'Skapad till'), 'updated_at' => Yii: : t ('app', 'uppdaterad vid'),]; 

Nu kan vi gå vidare till Visa ändringar inom ActiveModel-formuläret.

Lägger till vår vy och formfunktionalitet

Integrera bildöverföring till statusskapningsformuläret

För att möjliggöra formintegrationen av bilduppladdning till Statusuppdateringar (visas ovan), måste vi göra ändringar i /views/status/_form.php fil. 

Först inkluderar vi Kartik \ fil \ FileInput widget nära toppen och uppdatera formuläret för att bli multipart, vilket stöder att posta filer:

 
[ 'Enctype' => 'multipart / form-data']]); // viktigt?>

Sedan lägger vi till widgeten FileInput mellan fältet Tillåtelser och Submit.

fält ($ modell, behörigheter) -> dropDownList ($ model-> getPermissions (), ['prompt' => Yii :: t ('app', '- Välj dina behörigheter' ')]) 
fält ($ modell, bild) -> widget (FileInput :: klassnamn (), ['options' => ['accept' => 'bild / *'], 'pluginOptions' => ['allowedFileExtensions' => ['jpg', 'gif', 'png'], 'showUpload' => false,],]); ?>
isNewRecord? Yii :: t ('app', 'Skapa'): Yii :: t ('app', 'Update'), ['class' => $ model-> isNewRecord? 'btn btn-success': 'btn btn-primary'])?>

I pluginOptions linje begränsar vi filtyper till vanliga bildformat som jpg.

När det är klart kommer det att se ut så här och vänta på att användaren lägger till en bild:

Visar bilden

Jag ska också lägga till kod för att visa den uppladdade bilden för senare (när vi har slutfört kontrollenhetstjänsten). 

Först lägger jag till det på statusvynssidan (/views/status/view.php), vilket är väldigt grundläggande. Jag kommer emellertid att visa bilden nedanför detaljinformationen:

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

'; ?>

Det kommer att se ut så här:

Vi lägger också till en liten miniatyrvy till vår Statusindex-sida (/views/status/index.php). Jag har lagt till en anpassad kolumnattribut till Yii2s GridView-widget:

 $ dataProvider, 'filterModel' => $ searchModel, 'kolumner' => [['class' => 'yii \ grid \ SerialColumn'], 'id', 'meddelande: ntext', 'behörigheter', 'created_at' ['attribute' => 'Image', 'format' => 'raw', 'value' => funktion ($ modell) om ($ model-> image_web_filename! = ") returnera ' ', annars returnerar ingen bild;,], [' class '=>' yii \ grid \ ActionColumn ',' template '=>' view update delete ',' buttons '=> [' view '=> funktion ($ url, $ modell) returnera Html :: a',' status /'.$ modell-> slug, ['title' => Yii :: t ('yii', 'View'),]); ],],],]); ?>

I slutändan kommer det att se ut så här:

Bygga Controller Support

För att göra allt ovan möjligt måste vi slutföra kontrollerns integration. 

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

Då måste vi uppdatera actionCreate fungera:

public function actionCreate () $ model = ny status (); om ($ model-> load (Yii :: $ app-> request-> post ())) $ image = UploadedFile :: getInstance ($ modell, 'bild'); om (! is_null ($ image)) $ model-> image_src_filename = $ image-> namn; $ ext = slutet ((explodera (".", $ bild-> namn))); // skapa ett unikt filnamn för att förhindra dubbla filnamn $ model-> image_web_filename = Yii :: $ app-> security-> generateRandomString (). ". $ ext"; // sökvägen för att spara fil kan du ställa in en uploadPath // i Yii :: $ app-> params (som används i exempel nedan) Yii :: $ app-> params ['uploadPath'] = Yii :: $ app -> basPath. '/ Web / uploads / status /'; $ path = Yii :: $ app-> params ['uploadPath']. $ Modell-> image_web_filename; $ Bild-> SaveAs ($ bana);  om ($ modell-> spara ()) returnera $ this-> omdirigera (['visa', 'id' => $ modell-> id]);  annars var_dump ($ model-> getErrors ()); dö();  returnera $ this-> render ('create', ['model' => $ modell,]); 

I huvudsak utför detta följande åtgärder:

  1. Vi tar det ursprungliga filnamnet från den uppladdade filens formulärinformation (image_src_filename).
  2. Vi genererar ett unikt filnamn för vår server (image_web_filename).
  3. Vi sparar filen till vår uppladdningskatalog (/ Webb / uploads / status /).
  4. Vi sparar modellen.
  5. Vi omdirigerar till den förbättrade visningssidan.

Du kan se de slutliga resultaten med bilden ovan, som inkluderar en bild av Taj Mahal.

Kartiks File Input Widget erbjuder också mer avancerade konfigurationer som han dokumenterar ganska bra, till exempel Drag och släpp:

Kolla mer av dessa på följande sidor:

  • FileInput Widget Demo
  • Ladda upp filen i Yii 2 med FileInput-widgeten
  • Avancerad uppladdning med widgeten Yii2 FileInput 

Vad kommer härnäst?

Jag hoppas det hjälper dig med grunderna för filuppladdning i din Yii2-applikation. Om du vill se en annan liknande genomgång av denna typ av funktionalitet, kolla in Bygga din start med PHP: Användarinställningar, Profilbilder och Kontaktuppgifter. Den handledningen erbjuder en något annorlunda integration än denna handledning, med hjälp av flikar, uppdatering av användarprofiler och skalning av bilderna.

Titta på kommande handledningar i mitt Hur man programmerar med Yii2-serien när jag fortsätter att dyka in i olika aspekter av ramen. Du kanske också vill kolla in min Building Your Startup With PHP-serie, som använder Yii2s avancerade mall när jag bygger en verklig applikation.

Om du vill veta när nästa Yii2 handledning kommer, följ mig @ reifman på Twitter eller kolla min instruktörssida. Min instruktörssida kommer att innehålla alla artiklar från denna serie så snart de publiceras. 

relaterade länkar

Här är en mängd länkar som jag brukade undersöka och skriva denna handledning:

  • Yii2 Developer Exchange, min Yii2 resurs webbplats
  • FileInput Widget Demo by - Kartik
  • Ladda upp filen i Yii 2 med FileInput-widgeten - Kartik
  • Kod för kartik-v / yii2-widget-filinmatning (GitHub)
  • BlueImp JQuery File Upload Demo
  • Kod för 2 amigos/yii2-file-upload-widget: BlueImp File Upload Widget (Github)
  • Uppladdning av filer - Den slutgiltiga guiden till Yii 2.0