Databasen
Dette er anden del i en serie om, hvordan man opretter en blog med PHP og MySQL. Du kan få den første del her
Vi fortsætter, hvor vi slap i den sidste tutorial. I dette afsnit vil vi arbejde på vores databasedesign og brugergodkendelse (registrering og login). Opret en database med navnet complete-blog-php. I denne database skal du oprette 2 tabeller: indlæg og brugere med følgende felter.
indlæg:
+----+-----------------+----- -+| felt | type | specifikationer |+----+------------+--------------------+| id | INT(11) | || bruger_id | INT(11) | || titel | VARCHAR(255) | || snegl | VARCHAR(255) | UNIK || udsigt | INT(11) | || billede | VARCHAR(255) | || krop | TEKST | || offentliggjort | boolsk | || oprettet_ved | TIDSSTIMPEL | || updated_at | TIDSSTIMPEL | |+----------------+---------------+--------+
brugere:
+----+-----------+------------------------+- -----------+| felt | type | specifikationer |+----+------------+------------------------+----- -------+| id | INT(11) | || brugernavn | VARCHAR(255) | UNIK || e-mail | VARCHAR(255) | UNIK || rolle | ENUM("Admin","Forfatter") | || adgangskode | VARCHAR(255) | || oprettet_ved | TIDSSTIMPEL | || updated_at | TIDSSTIMPEL | |+----------------+---------------+--------+------ ------+
Du kan oprette disse tabeller ved hjælp af disse kommandoer.
brugere:
CREATE TABLE `users` ( `id` int(11) AUTO_INCREMENT PRIMARY KEY NOT NULL, `brugernavn` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `rolle` enum( 'Author','Admin') DEFAULT NULL, `password` varchar(255) NOT NULL, `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NULL DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1;
indlæg:
CREATE TABLE `posts` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `user_id` int(11) DEFAULT NULL, `title` varchar(255) NOT NULL, `slug` varchar( 255) NOT NULL UNIQUE, `views` int(11) NOT NULL DEFAULT '0', `image` varchar(255) NOT NULL, `body` text NOT NULL, `published` tinyint(1) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', FOREIGN KEY (`user_id`) REFERENCES `NO`USES` ON DELETE ON DELETE OPDATERING INGEN HANDLING) ENGINE=InnoDB DEFAULT CHARSET=latin1
Du kan køre disse scripts ved at bruge SQL-kommandoprompten eller PHPMyAdmin. På PHPMyAdmin, klik/vælg den database, du vil have disse tabeller oprettet under (i dette tilfælde complete-blog-php), og klik derefter på SQL-fanen på navigeringslinjen et sted øverst på siden. Hvis du ser et SQL-script i rummet nedenfor, skal du fjerne det og indsætte scriptet ovenfor i det angivne felt og klikke på 'Go' for at oprette tabellerne.
Hvis du i stedet vælger at oprette disse tabeller manuelt, skal du huske at gøre slug-feltet på posttabellen UNIQUE, og husk at indstille user_id-feltet for posts-tabellen som den fremmednøgle, der refererer til id på brugertabellen. Indstil INGEN HANDLING som værdien for indstillingerne ON SLET og ON UPDATE, så når en bruger slettes eller opdateres, forbliver deres indlæg på indlægstabellen og slettes ikke.
Indsæt nu et par brugere i brugertabellen og et par indlæg i posttabellen. Du kan gøre det ved at køre disse SQL-forespørgsler for at indsætte:
brugere:
INSERT INTO `brugere` (`id`, `brugernavn`, `e-mail`, `rolle`, `adgangskode`, `created_at`, `updated_at`) VALUES(1, 'Awa', 'info @codewithawa.com', 'Admin', 'mypassword', '2018-01-08 12:52:58', '2018-01-08 12:52:58')
indlæg:
INSERT INTO `posts` (`id`, `user_id`, `title`, `slug`, `views`, `image`, `body`, `published`, `created_at`, `updated_at `) VALUES(1, 1, '5 vaner, der kan forbedre dit liv', '5-vaner-der-kan-forbedre-dit-liv', 0, 'banner.jpg', 'Læs hver dag', 1, '2018-02-03 07:58:02', '2018-02-01 19:14:31'),(2, 1, 'Andet indlæg på LifeBlog', 'andet-indlæg-på-livsblog', 0 , 'banner.jpg', 'Dette er brødteksten i det andet indlæg på dette websted', 0, '2018-02-02 11:40:14', '2018-02-01 13:04:36')
Lad os oprette forbindelse til databasen, forespørge på disse indlæg og vise dem på websiden.
I config.php, lad os tilføje kode for at forbinde vores applikation til databasen. Efter tilføjelse af koden vil vores config.php-fil se sådan ud:
Dette returnerer et databaseforbindelsesobjekt $conn, som vi kan bruge i hele vores applikation til at forespørge databasen.
Denne applikation er blevet struktureret på en måde, så PHP-kode er så adskilt fra HTML som muligt. Handlinger såsom at forespørge databasen og udføre noget logik på data udføres i PHP-funktioner, og resultaterne sendes til HTML for at blive vist. For at få alle indlæg fra databasen, vil vi derfor gøre det i en funktion og returnere resultaterne som et associativt array, der skal gennemløbes og vises på siden.
Derfor opret en fil med navnet public_functions.php i mappen include. Denne fil kommer til at indeholde alle vores PHP-funktioner til det offentlige område. Alle sider, der bruger nogen af funktionerne i denne fil, skal have denne fil inkluderet i den øverste del af siden.
Lad os skabe vores første funktion i vores nyoprettede public_functions.php. Vi navngiver funktionen getPublishedPosts(), og den vil hente alle indlæg fra posts-tabellen i databasen og returnere dem som en associativ matrix:
public_functions.php:
Øverst i index.php-filen, lige under linjen, der inkluderer config. php , tilføj denne kode for at forespørge databasen:
Vi tilføjede to linjer kode. Den første inkluderer filen public_functions.php (som indeholder funktionerne) til vores index.php-fil. Den anden kodelinje kalder funktionen getPublishedPosts() som forespørger databasen og returnerer indlæg hentet fra databasen i en variabel kaldet $posts. Lad os nu gå igennem og vise disse indlæg på index.php-siden.
Åbn vores berømte index.php-fil igen. I indholdssektionen et sted i midten finder du et
-tag og en kommentar, der angiver, hvor mere indhold skal komme. Tilføj denne kode i rummet lige under
-tagget:
Okay, lad venligst være med at genindlæse siden endnu. Lad os tilføje styling til dette indlæg. Åbn public_styling.css og føj denne kode til den:
/* INDHOLD */.content { margin:5px auto; kant-radius:5px; min-height:400px;}.content:after { content:""; display:blok; clear:both;}.content .content-title { margin:10px 0px; farve:#374447; font-family:'Averia Serif Libre', kursiv;}.content .post { width:335px; margin:9px; min-højde:320px; flyde:venstre; kant-radius:2px; kant:1px fast #b3b3b3; position:relativ;}.indhold .post .category { margin-top:0px; polstring:3px 8px; farve:#374447; baggrund:hvid; display:inline-blok; kant-radius:2px; kant:1px fast #374447; box-shadow:3px 2px 2px; position:absolut; venstre:5px; top:5px; z-index:3;}.content .post .category:hover { box-shadow:3px 2px 2px; farve:hvid; baggrund:#374447; overgang:.4s; opacitet:1;}.indhold .post .post_image { højde:260px; bredde:100%; baggrundsstørrelse:100%;}.content .post .post_image { width:100%; højde:260px;}.indhold .post .post_info { højde:100%; polstring:0px 5px; skrifttypevægt:200; font-family:'Noto Serif', serif;}.content .post .post_info { color:#222;}.content .post .post_info span { color:#A6A6A6; font-style:italic;}.content .post .post_info span.read_more {position:absolut; højre:5px; bund:5px;}
Nu kan du genindlæse siden.
Hvis alt gik godt, vil du se et enkelt indlæg stilet som et miniaturebillede under titlen "Seneste artikler". Husk, at vi havde indsat to poster i databasen, men kun én bliver vist. Dette skyldes, at en af posterne havde sit publicerede felt sat til falsk (det vil sige 0), og da kun offentliggjorte artikler må vises, ser vi kun én, den offentliggjorte.
Men vores indlæg er indtil videre ikke klassificeret under noget emne. Lad os oprette en emnetabel og danne en mange-til-mange-relation mellem indlæggene og emnetabellen. For at gøre dette opretter vi to nye tabeller:emner til at gemme emner og post_topic-tabel til at håndtere forholdet mellem indlæg og emner.
emner:
+----+-----------+------------------------+- -----------+| felt | type | specifikationer |+----+------------+------------------------+----- -------+| id | INT(11) | || navn | VARCHAR(255) | || snegl | VARCHAR(255) | UNIK |+----------------+--------------+--------+------ -------+
post_emne:
+----+-----------+------------------------+- -----------+| felt | type | specifikationer |+----+------------+------------------------+----- -------+| id | INT(11) | || post_id | INT(11) | UNIK || emne_id | INT(11) | |+----------------+---------------+--------+------ ------+
Det, vi virkelig er interesserede i, er post_topic-tabellen. Dette er tabellen, der håndterer forholdet mellem indlæg og emner. Når et indlæg oprettes under et bestemt emne, indsættes id'et for det pågældende indlæg (post_id), samt id'et for emnet (topic_id), som det pågældende indlæg er oprettet under, i post_topic tabellen.
Lad os etablere dette forhold, så når et indlæg slettes, vil deres indtastning i post_topic-tabellen også automatisk blive slettet; du ønsker ikke at beholde oplysninger om et indlægs forhold, når indlægget ikke eksisterer vel?
Klik/vælg post_topic-tabellen, og klik derefter på strukturfanen i PHPMyAdmin-navigationslinjen. Klik derefter på Relationsvisning lige under strukturfanen (den kan findes et andet sted afhængigt af din version af PHPMyAdmin). Udfyld derefter formularen nedenfor som følger:
Tip:Linket +Tilføj begrænsning bruges til at tilføje en ny begrænsning.
ON DELETE og ON UPDATE er alle indstillet til henholdsvis CASCADE og NO ACTION, så når et indlæg eller et emne slettes, slettes dets relationsoplysninger i post_topic-tabellen også automatisk. (På billedet lavede jeg en fejl ved at indstille ON UPDATE til CASCADE i stedet for INGEN HANDLING, undskyld for det).
Klik på Gem og det er det. Tabellerne er nu relaterede. Men for at etablere et forhold mellem indlæg og emner, er vi nødt til at udfylde emnetabellen med emner og til sidst post_topic-tabellen, som er den faktiske relationsinformation.
Lad os nu indsætte nogle få poster i de to tabeller:
emner:
INSERT INTO `topics` (`id`, `name`, `slug`) VALUES(1, 'Inspiration', 'inspiration'),(2, 'Motivation', 'motivation'),( 3, 'Dagbog', 'dagbog')
post_emne:
INSERT INTO `post_topic` (`id`, `post_id`, `topic_id`) VALUES(1, 1, 1),(2, 2, 2)
Relationen defineret i post_topic-tabellen siger, at emnet med id 1 i emnetabellen hører til indlægget med id 1 i posts-tabellen. Det samme gælder for emnet med id 2 og indlæg med id 2.
På hver postliste på index.php-siden vil vi vise det emne, som indlægget er oprettet under.
For at gøre dette skal vi ændre vores getPublishedPosts() vi oprettede inde i public_functions.php for at forespørge på emnet for hvert indlæg fra databasen og returnere indlægget sammen med dets emne.
Rediger public_functions.php-filen til at se sådan ud:
Gå nu til filen index.php. Inde i foreach loop, direkte under billedtagget , tilføj if-sætningen for at vise emnet. Din forreste løkke skulle se sådan ud efter ændring:
Genindlæs nu siden, og du vil se emnet vist i indlægget.
Inde i denne foreach-løkke bemærker du, at der er to links, som når du klikker på dem, fører dig til to sider:filtered_posts.php og single_post.php.
filtered_posts.php er en side, der viser alle indlæg under et bestemt emne, når brugeren klikker på det emne.
single_post.php er en side, der viser hele indlægget i detaljer sammen med kommentarer, når brugeren klikker på indlægs-thumbnailet.
Disse to filer har brug for nogle få funktioner fra vores public_functions.php fil. filtered_posts.php har brug for to funktioner kaldet getPublishedPostsByTopic() og getTopicNameById() mens single_posts.php har brug for getPost() og getAllTopics().
Lad os starte med filtered_posts.php-filen. Åbn public_functions.php og tilføj disse to funktioner til listen over funktioner:
/* * * * * * * * * * * * * * * ** Returnerer alle indlæg under et emne* * * * * * * * * * * * * * * */funktion getPublishedPostsByTopic ($topic_id) { global $conn; $sql ="VÆLG * FRA indlæg ps WHERE ps.id IN (SELECT pt.post_id FROM post_topic pt WHERE pt.topic_id=$topic_id GROUP BY pt.post_id HAVING COUNT(1) =1)"; $result =mysqli_query($conn, $sql); // hent alle indlæg som et associativt array kaldet $posts $posts =mysqli_fetch_all($result, MYSQLI_ASSOC); $final_posts =array(); foreach ($posts as $post) { $post['topic'] =getPostTopic($post['id']); array_push($finale_posts, $post); } return $final_posts;}/* * * * * * * * * * * * * * ** Returnerer emnenavn efter emne-id* * * * * * * * * * * * * * * */funktion getTopicNameById ($id){ global $conn; $sql ="VÆLG navn FRA emner WHERE id=$id"; $result =mysqli_query($conn, $sql); $emne =mysqli_fetch_assoc($result); returner $emne['navn'];}
Lad os først oprette filen filtered_posts.php i rodmappen i vores applikation (det vil sige complete-blog-php/filtered_posts.php). Jeg vil bare gå videre og indsætte hele koden på denne side i filen:
filtered_posts.php:
LifeBlog | Hjem
Opdater nu siden, klik på emnet, og hvis det fører dig til en side, der viser indlæg under dette emne, så gør du det rigtige.
Lad os gøre det samme med single_post.php. Åbn public_functions.php og føj disse 2 funktioner til det:
/* * * * * * * * * * * * * * ** Returnerer et enkelt indlæg* * * * * * * * * * * * * */function getPost($slug){ global $conn; // Get single post slug $post_slug =$_GET['post-slug']; $sql ="VÆLG * FRA indlæg WHERE slug='$post_slug' OG offentliggjort=true"; $result =mysqli_query($conn, $sql); // hent forespørgselsresultater som associativ matrix. $post =mysqli_fetch_assoc($result); if ($post) { // få det emne, som dette indlæg tilhører $post['topic'] =getPostTopic($post['id']); } return $post;}/* * * * * * * * * * * ** Returnerer alle emner* * * * * * * * * * * */function getAllTopics(){ global $conn; $sql ="VÆLG * FRA emner"; $result =mysqli_query($conn, $sql); $topics =mysqli_fetch_all($result, MYSQLI_ASSOC); returner $topics;}
Opret nu filen complete-blog-php/single_post.php og indsæt denne kode i den:
| LifeBlog Beklager... Dette indlæg er ikke blevet offentliggjort
Lad os nu anvende styling til dette. Åbn public_styling.css og føj denne stylingkode til den:
/* * * * * * * * ** ENKEL SIDE * * * * * * * * */.content .post-wrapper { width:70%; flyde:venstre; min-højde:250px;}.full-post-div { min-højde:300px; polstring:20px; kant:1px fast #e4e1e1; border-radius:2px;}.full-post-div h2.post-title { margin:10px auto 20px; text-align:center;}.post-body-div { font-family:'Noto Serif', serif; font-size:1.2em;}.post-body-div p { margin:20px 0px;}.post-sidebar { width:24%; flyde:venstre; margin-venstre:5px; min-højde:400px;}.content .post-comments { margin-top:25px; kant-radius:2px; border-top:1px solid #e4e1e1; polstring:10px;}.post-sidebar .card { width:95%; margin:10px auto; kant:1px fast #e4e1e1; border-radius:10px 10px 0px 0px;}.post-sidebar .card .card-header { padding:10px; tekst-align:center; kant-radius:3px 3px 0px 0px; baggrund:#3E606F;}.post-sidebar .card .card-header h2 { color:white;}.post-sidebar .card .card-content a { display:block; box-sizing:border-box; polstring:8px 10px; border-bottom:1px solid #e4e1e1; farve:#444;}.post-sidebar .card .card-content a:hover { padding-left:20px; baggrund:#F9F9F9; overgang:0.1s;}
Ser godt ud nu ikke?
En sidste ting at gøre, og vi vil være stort set færdige med det offentlige område:Vi vil implementere brugerregistrering og login.
Brugerregistrering og login
Fordi jeg allerede har lavet et et tutorial om brugerregistrering og login, vil jeg være ret til det punkt med denne del og vil ikke forklare meget.
Opret to filer i din rodmappe ved navn register.php og login.php. Åbn hver af dem og indsæt denne kode i dem:
register.php:
LifeBlog | Tilmeld dig
login.php:
LifeBlog | Log ind
I de øverste sektioner af begge filer inkluderede vi en fil med navnet registration_login.php for at håndtere logikken omkring registrering og login. Dette er den fil, som login- og registreringsformularoplysningerne sendes til, og kommunikationen med databasen vil blive udført. Lad os oprette den i mappen inkluderer og spytte denne kode ind i den:
complete-blog-php/includes/registration_login.php:
0) { // få id for oprettet bruger $reg_user_id =mysqli_fetch_assoc($result)['id']; // put logget på bruger i session array $_SESSION['bruger'] =getUserById($reg_user_id); // hvis brugeren er admin, omdiriger til admin området if ( in_array($_SESSION['user']['role'], ["Admin", "Author"])) { $_SESSION['message'] ="Du er nu logget ind"; // redirect to admin area header('location:' . BASE_URL . '/admin/dashboard.php'); exit(0); } else { $_SESSION['message'] ="Du er nu logget ind"; // redirect to public area header('location:index.php'); exit(0); } } else {array_push($errors, 'Forkerte legitimationsoplysninger'); } } } // escape-værdi fra form funktion esc(String $value) { // bring det globale db connect-objekt ind i funktion global $conn; $val =trim($værdi); // fjern det tomme rum omkring strengen $val =mysqli_real_escape_string($conn, $værdi); returnere $val; } // Få brugeroplysninger fra bruger-id-funktionen getUserById($id) { global $conn; $sql ="VÆLG * FRA brugere WHERE id=$id LIMIT 1"; $result =mysqli_query($conn, $sql); $bruger =mysqli_fetch_assoc($result); // returnerer bruger i et array-format:// ['id'=>1 'brugernavn' => 'Awa', 'email'=>'[email protected]', 'adgangskode'=> 'mypass'] returner $bruger; }?>
Gå til http://localhost/complete-blog-php/register.php, og du vil se en fejl, der siger, at filen errors.php ikke blev fundet.
errors.php-filen er filen med kode til at vise formularvalideringsfejl. Opret errors.php inde i complete-blog-php/includes og indsæt denne kode i den:
0) :?>
Åben public_styling.css igen, lad os tilføje dette sidste stykke stylingkode til denne errors.php-fil og et par andre elementer:
/* MEDDELELSESMEDDELELSER */.message { width:100%; margin:0px auto; polstring:10px 0px; farve:#3c763d; baggrund:#dff0d8; kant:1px fast #3c763d; kant-radius:5px; text-align:center;}.error { color:#a94442; baggrund:#f2dede; kant:1px fast #a94442; margin-bottom:20px;}.validation_errors p { text-align:left; margin-left:10px;}.logged_in_info { text-align:right; polstring:10px;}
Og nu er fejlmeddelelsen væk. Klik på tilmeld-knappen uden at udfylde formularen, og du ser flotte fejlmeddelelser gengivet.
Lad os oprette en ny bruger ved at udfylde formularen på register.php-siden og klikke på tilmeld-knappen. Du kan give alle gyldige oplysninger om brugernavn, e-mail og adgangskode; bare sørg for at huske dem, for vi vil bruge dem til at logge ind meget snart på login-siden.
Når en bruger logger ind, skal de helt sikkert være i stand til at logge ud. I programmets rodmapp skal du oprette en fil med navnet logout.php.
complete-blog-php/logout.php:
Når en bruger logger ind, vil vi også vise deres navn og et link eller en knap, som de kan klikke på for at logge ud. For det offentlige område vil vi gøre det i banner.php-filen, vi inkluderede. Åbn banner.php-filen og rediger koden til at se sådan ud:
complete-blog-php/includes/banner.php:
velkommen | log ud
It checks the session to see if a user is available (logged in). If logged in, the username is displayed with the logout link. When there is a logged in user, the banner does not get displayed since it is some sort of a welcome screen to guest users.
You notice that the banner has a login form and this banner is included inside index.php file. Therefore we need to include the code that handles registration and login inside our index.php file also. Open index.php and add this line directly under the include for public_functions.php:
top section of complete-blog-php/index.php:
And that's it with user registration and login. In the next section, we begin work on the admin area.
Thank you so much for sticking around up to this point. I hope you found it helpful. If you have any worries, please leave it in the comments below. Your feedback is always very helpful and if you have any bugs in your code, I will try my best to help you out.
I will be very much encouraged to create more of these tutorials with improved quality if you share, subscribe to my site and recommend my site to your friends.