21
Tags:
php
mysql
Skrevet af
Bruger #5620
@ 09.06.2011
3. Brugseksempler
Den sektion vil vise eksempler på brugen af tagsystemet. Tagsystemet har på ingen måde et indbygger brugergrænseflade, som for eksempel HTML. Dette er et bevidst valg ud fra anskuelsen, at det er lettere at bygge en grænseflade om et system, end det er at ændre i et systems indbyggede grænseflade.
Systemet kræver et ekstern objekt af databasetilgangsklasse. Grunden til dette er at det dermed bliver muligt at ændre databasetilgangslaget i stedet for at systemet til et bestemt databasetilgangslag som for eksemple MySQL.
Der vil i denne sektion blive givet eksempler på, hvordan en HTML grænseflade bygges om systemet og på implementeringen af en databasetilgangsklasse, der implementere en grænseflade til PHP's
mysql-funktioner.
3.1. Bilentiternes database tabelDe tre biler(entiteter) er gemt i en databasetabel, se kodeblok 3.1, med et
id og en sti til billedet på serveren.
biler:
id integer
url varchar(20)
id | url
-----------------
1 | ferrari.jpg
2 | porche.jpg
3 | vw.jpg
Kodeblok 3.1: Biltabellen.
3.2. HTML grænsefladenDen sektion beskriver HTML grænsefladen til tagsystemet. Denne grænseflade er opdelt i fire dele visning, administration, installering, associering.
I alle grænsefladerne antages det at tagsystemet er i filen "tags.php" og databasetilgangsklassen
MySQL er i "mysql.php".
3.2.1. VisningDenne sektion viser et forslag til hvordan tagsystemet kan integreres i visualisering af bilentiterne. Figur 3.1 viser skærmbilleder koden producerer.
Figur 3.1: Visualisering.
- <?php
- session_start();
- require_once('tags.php');
- require_once('mysql.php');
-
-
- $db = new MySQL();
- if(!$db->connect("localhost", "root", "", "test")){
- die("DB Failed");
- }
-
- $tagsystem = new TagSystem();
- $tagsystem->setTableNamePrefix('bil_');
- $tagsystem->setEntityId('bilid');
- $tagsystem->db= $db;
-
- if(!$tagsystem->load()){
- die(mysql_error());
- }
-
- $filter = $tagsystem->makeFilter();
- $filter->sessionField('tagfilter');
-
- if(isset($_GET['ic'])){
- $tag = $tagsystem->getTagById($_GET['ic']);
- $filter->includeTag($tag);
- }
-
- if(isset($_GET['ec'])){
- $tag = $tagsystem->getTagById($_GET['ec']);
- $filter->excludeTag($tag);
- }
-
- if(isset($_GET['cc'])){
- $tag = $tagsystem->getTagById($_GET['cc']);
- $filter->couldcludeTag($tag);
- }
-
- if(isset($_GET['free'])){
- $tag = $tagsystem->getTagById($_GET['free']);
- $filter->freeTag($tag);
- }
-
- function tagHTML($filter, $tag){
- print '<li style="font-size:'.(1+3*($tag->weight-1)/10).'em">'. $tag->name;
- $include = '<a href="?ic='.$tag->id.'">+</a>';
- $exclude = '<a href="?ec='.$tag->id.'">-</a>';
- $couldclude = '<a href="?cc='.$tag->id.'">?</a>';
- $free = '<a href="?free='.$tag->id.'">x</a>';
-
- if($filter->isIncluded($tag)){
- print $exclude.$couldclude.$free;
- }else if($filter->isExcluded($tag)){
- print $include.$couldclude.$free;
- }else if($filter->isCouldcluded($tag)){
- print $include.$exclude.$free;
- }else{
- print $include.$exclude.$couldclude;
- }
- print '</li>';
- }
-
- print '<div style="float:left">Free tags:';
- print '<ul>';
- foreach($tagsystem->getFreeTagsInResult($filter, 'biler','id') as $tag){
- tagHTML($filter, $tag);
- }
-
- print '</ul>';
- print 'Filter tags:'.count($filter);
- print '<ul>';
- foreach($filter as $id => $state){
- $tag = $tagsystem->getTagById($id);
- tagHTML($filter, $tag);
- }
-
- print '</ul>';
- print 'All tags:';
- print '<ul>';
- foreach($tagsystem as $tag){
- tagHTML($filter, $tag);
- }
-
- print '</ul>';
- print '</div>';
-
- foreach($tagsystem->applyFilter($filter, 'biler','id','url, id','url') as $bil){
- print '<div style="float:left"><img src="../'.$bil['url'].'"><div>Tags:';
- print '<ul>';
- foreach($tagsystem->getEntityTags($bil['id']) as $tag){
- tagHTML($filter, $tag);
- }
- print '</ul>';
- print '</div>';
-
- print '<div>Related:';
- print '<ul>';
- foreach($tagsystem->getRelatedEntities('biler', $bil['id'], 'id','url') as $ent){
- print '<img src="../'.$ent['url'].'">';
- }
- print '</ul>';
- print '</div>';
-
- print '</div>';
- }
- ?>
Kodeblok 3.2: Visualiseringkoden.
Når der efterfølgende i denne sektion refereres til linjenumre er det i kodeeksempel 3.2.
Linjerne 1-10 er blot inkludering og initialisering af databasetilgangslaget. Og har dermed i realiteten intet med tagsystemet at gøre. Det er dog vigtigt notere sig at der foretages et
connect i linje 8. Tagsystemet forventer at databasetilgangskladsen enten er connectet eller selv foretager et connect når der foretages en
sql-forespørgsel.
Linjerne 12-19 initialisering af tagsystemet, hvor der oprettes et objekt af systemet, objektets tabel præfix sættes, navnet på entiternes id kolonne i tag brugs tabellen gives, databasetilgangsobjektet gives og sidst kaldes load metoden på objektet, dette henter alle tags i databasen ind i tabellen.
Linjerne 1 – 19 er ens for alle grænseflader tilsystemet når grænsefladerne deler det samme emne. Grunden til at det er muligt at sætte entitetkolonnens navn i brugstabellen er at det dermed er muligt navngive kolonnen så den har samme navn som i entitetstabellen. Grunden til at det er muligt at give systemets tabeller et præfiks er at det dermed bliver muligt både at have flere tagsystemer i samme database og give dem et navn der passer til entiteterne.
Linjerne 21 – 22 opretter et tomt filter og forbinder dette til session feltet
tagfilter, hvis session feltet er sat forventes det implicit at være et array på filtrets form.
Linjerne 24 – 42 tester om der er sat et tagid i _GET og hvis der er tilføjes fjernes dette id fra filtret afhængigt af nøglen i _GET.
Linjerne 44 – 61 er en funktion der tager filtret og et tag og udskriver HTML. Filtret bruges til at udskrive HTML'en så den er baseret på taggets tilstand i filtret. Mens en funktion ikke er strengt nødvendigt kan det stærkt anbefales at bruge en, da det medføre at det er lettere at visualisere tags ens flere steder.
Linjerne 65 – 67 udskriver alle frie tags i entiteterne, der er i resultatet af at bruge et filter systemet. Metoden
getFreeTagsInResult kaldes med filtret entitet tabellen og navnet på id kolonnen i denne tabel.
Linjerne 72 – 75 udskriver tags i filtret.
Linje 87 kalder metoden
applyFilter der returnerer et resultatet med de entiteterne der kommer igennem filtret. Metoden kaldes med filtret entitet tabellen, navnet på id kolonnen i denne tabel, navnene på de kolonner der skal hentes for hver entitet og navnet på den kolonne, der skal sorteres efter.
Linje 87 - 105 udskriver alle entiteter der kommer igennem filtret.
Linje 90 - 92 udskriver alle tag en entitet har. Metoden
getEntityTags kaldes med entitetens id.
Linje 98 - 100 udskriver alle entiteter, der er relaterede til en entitet. Metoden
getRelatedEntities kaldes navnet på entitet tabellen, id'et på entiteten, navnet på id kolonnen i entitet tabellen og navnene på de kolonner der skal returneres for hver entitet.
3.2.2. AdministrationDenne sektion vil vise den mindst mulige administration. Det er i systemet muligt at få vist og slettet alle tags, der ikke har nogen brug i brugs tabellen og alle relationer i tagbrugs tabellen der ikke har nogen entitet i en entitets tabel.
- <?php
-
- require_once('tags.php');
- require_once('mysql.php');
-
-
- $db = new MySQL();
- if(!$db->connect("localhost", "root", "", "test")){
- die("DB Failed");
- }
-
- $tagsystem = new TagSystem();
- $tagsystem->setTableNamePrefix('bil_');
- $tagsystem->setEntityId('bilid');
- $tagsystem->db= $db;
-
-
-
- if(isset($_POST['submit'])&&$_POST['submit']){
- $tagsystem->deleteOrphans('biler','id');
- }
-
- if(!$tagsystem->load()){
- die(mysql_error());
- }
-
-
- $orphans=$tagsystem->orphanCheck('biler','id');
- ?>
- <div>
- <form method="post">
- <table>
- <?php
- print '<tr><th>Id</th><th>Name</th><th>Appearances</th><th>Weight</th><th>Orphans</th></tr>';
- foreach($tagsystem as $tag){
- $color=($tag->appearances==0)?'#ff0000;':'#ffffff';
- if(array_key_exists($tag->id,$orphans)){
- $color='#ff0000;';
- }
- print '<tr style="background-color:'.$color.'"><td>'.$tag->id.'</td><td>'.$tag->name.'</td><td>'.$tag->appearances.'</td><td>'.$tag->weight.'</td>';
- print '<td>'.((array_key_exists($tag->id,$orphans))?$orphans[$tag->id]:0).'</td>';
- print '</tr>';
- }
- ?>
- </table>
- <input type="submit" value="Delete Orphans" name="submit"/>
- </form>
- </div>
Kodeblok 3.3: Administration.
Når der efterfølgende i denne sektion refereres til linjenumre er det i kodeeksempel 3.3.
Linjerne 19 – 21, tester om submit knappen er blev klikket og kalder metoden
deleteOrphans med entitet tabellens navn og navnet på id kolonnen i den. Denne metode vil slette alle tagrelationer der ikke har en entitet i entitetstabellen og derefter alle tags der ikke har en tagrelation i tagbrugs tabellen. Det er vigtigt at denne metode kaldes før metoden
load i linje 23.
Linje 28 kalder metoden
orphanCheck med entitet tabellens navn og navnet på id kolonnen i den. Denne metode returnerer et array med alle de orphans der er i tagbrugstabellen.
Linje 29 – 48 udskriver en form, der lister alle de tags tagsystemet har med deres vægt i systemet antallet af gange de er brugt og antallet af gange de er påstået at være brugt (orphans).
Det er muligt i tagsystemet at slette alle tagbrugstilfælde der er afhængige af en bestemt entitet via metoden
deleteEntityTags. Kald til denne metode bør implementeres der, hvor tagsne til en entitet kan ændre og, hvor hele entiteten kan slettes. Brugen af orphan sletning som beskrevet er implementeret i tilfælde af at der opstår fejl de andre steder (For eksempel at det lykkes at slette en entitet efterfulgt af en fejl så entitetens tags ikke bliver slettet.).
3.2.3. AssocieringDen sektion beskriver koden for at associere tags med en entitet (oprette rækker i tagsbrugs tabellen).
- <?php
-
- require_once('tags.php');
- require_once('mysql.php');
-
-
- $db = new MySQL();
- if(!$db->connect("localhost", "root", "", "test")){
- die("DB Failed");
- }
-
- $tagsystem = new TagSystem();
- $tagsystem->setTableNamePrefix('bil_');
- $tagsystem->setEntityId('bilid');
- $tagsystem->db= $db;
-
- if(!$tagsystem->load()){
- die(mysql_error());
- }
-
- $tagsystem->associateTagsWith(1, array('mærke.ferrari','farve.rød','type.sportsvogn','sæder.to'));
- $tagsystem->associateTagsWith(2, array('mærke.porche','farve.grøn','type.sportsvogn','sæder.to'));
- $tagsystem->associateTagsWith(3, array('mærke.vw','farve.grå','type.familiebil','sæder.fire'));
- ?>
Kodeblok 3.4: Associeringskoden.
Det eneste specielle i kodeeksempel 3.4 er linjerne 21 - 23, hver af disse linjer kalder metoden
associateTagsWith. Denne metode kaldes med id'et på en entitet (id'erne der gives passer til dem i tabellen i kodeeksempel 3.1) og et array af navnene på de tags entiteten skal associeres med. Findes et tag med et givet navn ikke i systemet oprettes det. Kald til denne metode bør indbygges, der hvor entiteter oprettes og ændres.
3.2.4. InstalleringDen sektion beskriver koden for at installere tagsystemet (oprette tabellerne i databasen). Dette har ikke et egentlig visuelt komponent, men er ren PHP kode.
- <?php
-
- require_once('tags.php');
- require_once('mysql.php');
-
-
- $db = new MySQL();
- if(!$db->connect("localhost", "root", "", "test")){
- die("DB Failed");
- }
-
- $tagsystem = new TagSystem();
- $tagsystem->setTableNamePrefix('bil_');
- $tagsystem->setEntityId('bilid');
- $tagsystem->db= $db;
- if($tagsystem->install()){
- die(mysql_error());
- }
- ?>
Kodeblok 3.5: Installeringskoden.
Det eneste specielle i kodeeksempel 3.5 er linje 16, der kalder metoden
install. Denne metode vil oprette to tabeller "bil_tags" og "bil_tagsuse" ("bil_" præfikset skyldes linje 13). Disse to tabeller er henholdsvis for de individuelle tags og for samhængen mellem bilerne og tagsne.
3.3. DatabasetilgangsklasserneDenne sektion beskriver de databasetilgangsklasser, der er nødvendige for tagsystemet. Dette består af to klasser (grænseflader). En klasse til at foretage en forespørgsel og en klasse til at gennemløbe resultatet af denne forespørgelse.
Eftersom dette er en ekstern klasse vil blive beskrevet eksterne. Dermed vil kun metoderne tagsystemet faktisk bruger blive vist og beskrevet. Et eksempel på en implementering af databasetilgangslaget er vist i 1.2.
Figur 3.2: UML-diagrammet for MySQL-klassen.
Figur 3.3: UML-diagrammet for MySQLResult-klassen.
Databasetilgangsklassen klassen (
MySQL) skal implementere de tre metoder
query,
make_safe og
make_tuple.
Metoden
query skal accepterer en sql tekst og fortage den forespørgelse indkodet i denne tekst. Er forespørgelsen en
select skal metoden returnerer et iterabeltobjekt (
MySQLResult), der ved hver iteration returnerer at associativ array over en række i resultatet. Er forespørgelsen ikke en
select eller hvis
select forespørgelsen fejler skal metoden returnerer sandt eller falsk.
Metoden
make_safe skal accepterer en værdi og returnere en repræsentation af denne værdi, der er sikker for indsættelse i en sql streng.
Metoden
make_tuple skal accepterer et variabelt antal værdier og returnere en streng, hvor hver værdi er en sikker SQL repræsentation af værdien. Værdierne adskilles af kommaer og hele strengen omkranses af parenteser.
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 (1)
Som at give slik til små børn... Well done
Du skal være
logget ind for at skrive en kommentar.