22
Tags:
php
Skrevet af
Bruger #8223
@ 29.09.2009
Øvelse: BlogsystemNu har vi gennemgået de basale begreber indenfor CodeIgniter's MVC, og har lært hvordan vi redigerer models, controllers og views, og får dem til at kommunikere sammen. Vi har sprunget lidt let hen over nogle af forklaringerne – det har indtil nu været tilstrækkeligt at det virkede. Nu skal vi til at lære lidt om hvordan det virker, så vi kan bruge det til noget fornuftigt. Derfor vil artiklen nu guide dig igennem udviklingen af en simpel weblog, der kan oprette, liste, læse, redigere og slette posts, og på vejen vil vi kigge nærmere på de forskellige libraries og metoder der bliver taget i brug.
BEMÆRK: undervejs i denne øvelse vil urlen http://dinServerUrl/ blive brugt istedet for din egen url. Sørg for at skifte denne url ud inden du kører eksemplerne!Øvelse: Blogsystem - DatabasenFør at have en weblog kørende skal vi have en eller anden form for database op at stå. Artiklen tager udgangspunkt i en MySQL-database, men CodeIgniter kan indstilles til at bruge både PostgresSQL, Sqlite, Oracle, MSSQL m.v i konfigurationen. Derudover tilbyder CodeIgniter en databaseabstraktion der gør det let at skrive database-uafhængige queries. Det vil vi alt sammen se nærmere på senere – vi fokuserer på det der ligger umiddelbart foran os, og det er at få lavet databasen. Resten ser vi på senere - agil udvikling.
Udfør følgende SQL-sætning i din database (skal eventuelt rettes lidt til for at passe, hvis du bruger noget andet end MySQL). Hvis du bruger PHPMyAdmin kan du gøre det via SQL-funktionen i interfacet:
- CREATE TABLE `codeigniter_blog` (
- `id` BIGINT UNSIGNED AUTO_INCREMENT NOT NULL,
- `title` VARCHAR(255) NOT NULL,
- `body` TEXT NOT NULL,
- PRIMARY KEY (`id`)
- );
Nu har vi tabellen, så skal vi fortælle CodeIgniter at den findes. Det gør vi ved at gå ind i system/application/config/database.php og ændre lidt på konfigurationsvariablerne. Som du kan se er MySQL valgt som default, og det er jo fint. Variablerne burde være selvforklarende, så ret dem til så de passer til dine specifikationer, og gem filen igen. Nu er databasen sat op, og vi kan komme igang med at producere kode!
Øvelse: Blogsystem – OprettelsesformVi skal igang med vores blog, og førend vi kan læse eller liste data, er vi nødt til at have noget data at arbejde med. Derfor kan vi ligeså godt starte med oprettelsesdelen – det er agilt, det er smart, og det er nemt.
Lad os analysere situationen engang: For at kunne oprette blogindlæg skal vi bruge en database, den har vi lavet, en funktion der sætter dataene ind, og et sted at skrive dem. Intet af dette kan lade sig gøre uden adgangslaget, så lad os starte med at oprette en controller:
- <?php
-
- class Weblog extends Controller {
-
- function Weblog()
- {
- parent::Controller();
- $this->load->database();
- $this->load->model('weblog_model');
- }
-
- function index()
- {
-
- }
-
- function create()
- {
- $data['message'] = $this->weblog_model->opret();
- $this->load->view('weblog_create', $data);
- }
- }
-
- /* End of file weblog.php */
- /* Location: ./system/application/controllers/weblog.php */
Filen er umiddelbart ganske simpel, men for en god ordens skyld løber vi den igennem. Den starter med en konstruktør, der loader database-delen af CodeIgniter, og weblog-modellen – den har vi endnu ikke lavet, den kommer bagefter. Derefter defineres to metoder, index() og create(). index() skal vi ikke bruge til noget endnu, så den efterlader vi bare tom. I create() har vi to linier kode. Den første putter resultatet af $this->weblog_model->create() ind i en data-variabel, og den anden åbner weblog-oprettelsesformuleren og pusher resultatet ind. Dette betyder at når både vores model og view er lavet, vil formularen fra viewet blive postet til controlleren, der sender dataene videre til modellen, der igen sender resultatet tilbage til controlleren der til sidst sparker det ind i viewet. På den måde kan brugeren få sine data lagt ind, og derefter få at vide hvorvidt det lykkedes. Ligenu vil koden dog ikke fungere, da både modellen og formularen mangler.
Lad os starte med at oprette modellen. Den skal til at starte med bare kunne oprette, så vi laver den ganske simpel for nu:
- <?php
-
- class Weblog_model extends Model {
-
- function Weblog_model()
- {
- parent::Model();
- }
-
- function create()
- {
- if(!$this->input->post('title') &&
- !$this->input->post('body'))
- {
- return '';
- }
-
- if(empty($this->input->post('title')))
- {
- return 'Titel er ikke angivet!';
- }
-
- if(empty($this->input->post('body')))
- {
- return 'Der er ingen tekst!';
- }
-
- $data = array(
- 'title' => $this->input->post('title'),
- 'body' => $this->input->post('body')
- );
- $this->db->insert('codeigniter_blog', $data);
-
- return 'Dit indlæg fik ID: ' .$this->db->insert_id();
- }
- }
-
- /* End of file weblog_model.php */
- /* Location: ./system/application/models/weblog_model.php */
For atter at gennemgå vores kode kan vi starte med at konkludere, at konstruktøren ikke gør andet end at ligge der, til hvis vi får brug for den. Det interessante her er create() metoden, der gør nogle ting med vores data. Som du kan se ligger post-data i en metode i CodeIgniter's input-klasse, der hedder post(). Denne metode sørger for at filtrere XSS-forsøg og lignende fra inputtet, uden at du behøves tænke over det. Metoden returnerer FALSE hvis den ikke er sat.
Det allerførste der sker er at tjekke hvorvidt titel og brødtekst overhovedet er forsøgt postet. Hvis det ikke er tilfældet for nogen af dem, konkluderes det at man ikke forsøger at poste endnu, og der returneres derfor en tom meddelelse. Ellers fortsættes der til at tjekke hvorvidt titelfeltet er tomt eller ej. Hvis det er tomt stopper metoden med meddelelsen om at der skal indtastes en titel. Ellers fortsættes der til at tjekke hvorvidt der er indtastet en brødtekst.
Hvis det hele går glat bliver dataene indsat i databasen via CodeIgniters ActiveRecord klasse, der giver en nydelig databaseabstraktion. Det fungerer ved at vi først angiver et array der indeholder de data vi vil ind – hvor index-nøglerne repræsenterer tabel-feltet – og skubber det ind som argument til insert() metoden, lige efter vi har fortalt den hvilken tabel vi vil snakke med. Bemærk at når vi indsætter data på denne måde, bliver input automatisk filtreret og escapet så vi ikke behøves bekymre os om SQL-injections.
Det kan også lade sig gøre at køre almindelige queries med $this->db->query('INSERT ....') men de anbefales at bruge ActiveRecord istedet, da dette både er mere sikkert og gør det nemmere at skifte database senere.
Til sidst bliver det indsatte ID sendt tilbage til brugeren i en besked, så vedkommende ved hvilken post han nu skal kigge på for at se det endelige resultat.
Så langt, så godt. Det eneste vi reelt mangler nu for at kunne poste til vores blog er en formular i html. Vi har allerede sagt til vores controller at den ligger under navnet weblog_create, så nu laver vi en fil i system/application/views/ og kalder den weblog_create.php med følgende indhold:
- <html>
- <head>
- <title>Vores oprettelsesformular</title>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- </head>
- <body>
- <p><?php echo $message; ?></p>
- <form method='post' action=''>
- <p><label for='title'>Titel</label><br/>
- <input type='text' name='title'/></p>
-
- <p><label for='body'>Brødtekst</label><br/>
- <textarea name='body'></textarea></p>
-
- <p><input type='submit' value='Opret indlæg'/></p>
- </form>
- <a href='http://dinServerUrl/MinApp/index.php/weblog/overview/'>
- Tilbage til oversigten
- </a>
- </body>
- </html>
Nu er du færdig, og kan tilgå siden med urlen
http://dinServerUrl/MinApp/index.php/weblog/create og oprette blogs – lav et par stykker med forskellige titler og forskelligt indhold. Du kan ikke se dem endnu, medmindre du går ind og kigger direkte i databasen, men det kommer vi til i næste afsnit.
Øvelse: Blogsystem – Liste af indlæg
Nu har vi lavet nogle blogs, og nu skal vi have en måde at se dem på. Den bedste måde at gøre det på er at lave en liste som vi kan vælge ud fra. For at opnå dette mål skal vi have lavet et adgangslag til det i controlleren, få vores weblog_model til at kunne returnere en liste af indlæg, og lave et view til det.
Vi starter med controlleren, og tilføjer følgende metode:
- function overview()
- {
- $data['blogs'] = $this->weblog_model->overview();
- $this->load->view('weblog_overview', $data);
- }
Nu har vi sagt at der findes en model-metode der hedder overview(), såvel som et view der hedder weblog_overview. Nu går vi videre til at oprette metoden i weblog_model, så vi kan få fat i noget data:
- function overview()
- {
- $blogs = $this->db->get('codeigniter_blog');
- return $blogs->result_array();
- }
Igen benytter vi os af ActiveRecord til at få hevet data ud, istedet for at skulle skrive en lang SELECT FROM .... sætning selv. Resultatet bliver et objekt indeholdende nogle metoder til at hente de selectede data med. Vi bruger result_array() for at få resultatet tilbage som et array med arrays i. Hvis vi brugte result() ville vi få det som et array med objekter, hvilket kan være en fordel i nogle situationer, men her er vi interesseret i en så simpel løsning som muligt.
Sidst men ikke mindst skal vi have oprettet et view der hedder weblog_overview.php. Denne fil skal have noget html der kan liste et ubekendt antal blog posts, så vi skal have fat i en lille løkke. Dataene vi får fra modellen er i form af et numerisk array der hver indeholder associative arrays med blogindholdet, så vi skal ganske enkelt lave en PHP foreach og udskrive de forskellige data således:
- <html>
- <head>
- <title>Liste over indlæg</title>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <body>
- <?php foreach($blogs as $blog_entry) { ?>
- <h1>
- <a href='http://dinServerUrl/MinApp/index.php/weblog/display/<?php echo $blog_entry['id']; ?>'>
- <?php echo $blog_entry['title']; ?>
- </a>
- </h1>
- <p>
- <?php echo nl2br($blog_entry['body']); ?>
- </p>
- <?php } ?>
- <a href='http://dinServerUrl/MinApp/index.php/weblog/create'>
- Opret nyt indlæg
- </a>
- </body>
- </html>
Når du har gemt filen kan du gå ind på
http://dinServerUrl/MinApp/index.php/weblog/overview og se alle de indlæg vi oprettede med oprettelsesformularen. Som du kan se har vi lagt et link ind til display-logikken med et id til blogindlægget. Linket duer ikke endnu, men det er det næste vi skal lave.
Vedhæftede filer:
Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.
Del også gerne artiklen med dine Facebook venner:
Kommentarer (10)
Struktureret artikel med gode formulering. Jeg føler selv at jeg har fået noget ud af at læse den.
Kanon god artikel. Jeg har selv længe holdt mig fra frameworks, da jeg ikke har kunne se det smarte i at benytte det frem for mine egne klasser. Men den store fordel er gået op for mig at jeg kan stadig bruge mine egne klasser, nu kan de komme nemmere over i MVC plus Codeigniter tilbyder noget security jeg har ikke selv har haft nogle smarte løsninger på. Thumbs up og en femmer herfra.
Jeg takker mange gange for de rosende ord og den pæne rating
Vil da lige give lidt feedback efter et par meget lærrige timers læsning :-)
Side 4, afsnit 2 -
Du skriver: "Den ovenstående fil er meget, meget basisk" <--- så vidt jeg ved kan filer ikke være basiske ;-) basisk er noget man snakker om i kemi. Basal er det rette danske ord for det engelske 'basic'.
Side 6, første PHP kode -
du bruger $this->weblog_model->opret(); i koden, men betegner den $this->weblog_model->create() i teksten
Side 6, anden PHP kode -
jeg har problemer med empty(), da den ikke accepterer et function return som argument. Jeg valgte at bruge == "" i stedet.
Ellers vil jeg sige tak for en super guide :-) en 5'er fra mig.
Tak for dine indspark Randi!
Basisk og opret/create havde jeg ikke lige set, tak for det.
Den med empty havde jeg godt spottet et stykke tid efter jeg uploadede den, men udvikleren.dk har ikke rigtigt nogen mulighed for at man kan redigere i sine artikler efter de er godkendt. Men det er iøvrigt slet ikke nødvendigt med det tjek. Funktionen returnerer nemlig boolean false hvis den er empty såvel som !isset, har jeg sidenhen erfaret.
Oh, ja det var jo rart at vide ;-) det havde jeg ikke lige fået tjekket efter... Så er det jo ikke det store problem.
Så, for at forklare for andre der ser det her, og ikke forstår hvad vi snakker om:
I artiklen står der nogle steder if(empty($this->input->post('noget')) - der kan I nøjes med if(!$this->input->post('noget'))
Hej alle, ved godt det er over et år siden der sidst er skrevet kommentarer til denne artikel
jeg faldt bare over den og læste den igennem, fandt så det CodeIgniter spændende og ville prøve det.
Kunne så bare overhovedet ikke få det til at virke, og da jeg så selv kigger de filer igennem jeg har hentet fra Codeigniter kan jeg se at bla. Controlleren den kalder i starten: #
# class Welcome extends Controller {
hedder nu CI_Controller, det er bare en lidt træls fejl hvis folk ikke har prøvet rode med det før da den bare viser blank side, om der er andet der er galt har jeg ikke lige undersøgt
Synes os bare jeg lige ville give heads up til andre der kaster sig ud i det.
Anyways super god artikel, godt skrevet og godt formuleret
For lige at følge op på min tidligere post, har jeg efter at ha rodet en del rundt med det fundet ud af at den version jeg har hentet 2.0.0 Er ret så meget anderledes end den sidste tidligere 1.7.3.. Stortset alle guides osv. på nettet understøtter ikke rigtigt 2.0.0 så tror indtilvidere for nybegyndere at det ville være en fordel at hente den tidligere udgave, ihvertfald indtil der er mere hjælp at hente på den nye
Ja, det er korrekt. Efter 2.0(en *længe* sukket efter udgivelse i miljøet) blev udgivet er der sket en del store omvæltninger.
For at få artiklen til at virke skulle det dog være nok at lave et lille hack:
En fil i application/core kaldet MY_Controller.php (extended core-controller) der indeholder følgende
<?php
class Controller extends CI_Controller {}
class Model extends CI_Model {}
class MY_Controller {
// hvad end du vil have i din egen MY_Controller
}
// EOF
Du skal være
logget ind for at skrive en kommentar.