Όταν έχετε μεγάλα έργα, τότε η διαχείριση του δομή κώδικακαι αρχεία μέσα στο έργο γίνεται μια κουραστική δουλειά. Μερικές φορές, λόγω ενός μη οργανωμένου τρόπου, ο κώδικας γίνεται πλέγμα και περίπλοκος. Για να ξεπεράσουμε αυτού του είδους τα προβλήματα μπορούμε να ακολουθήσουμε ένα σχέδιο σχεδίασης. Ένα σχέδιο σχεδίασης είναι μια προηγμένη προσέγγιση για την οργάνωση της δομής του κώδικα. Μας επιτρέπει να χρησιμοποιήσουμε το αρχή της αντιστροφής της εξάρτησης. Σημαίνει διαχωρισμό της επιχειρηματικής λογικής και διατήρησή της σε ένα μέρος χωρίς να εμφανίζεται στο κύριο αρχείο. Αυτό κάνει τον κώδικά μας πιο ισχυρό, καθαρό και ασφαλή. Υπάρχουν διάφορα σχεδιαστικά πρότυπα διαθέσιμα για να το πετύχετε αυτό στη Laravel. Σε αυτήν την ανάρτηση, θα μιλήσω για το Μοτίβο σχεδίασης αποθετηρίου. Είναι ένα από τα δημοφιλή σχέδια σχεδίασης και είναι πολύ ωφέλιμο για μεγάλα έργα. Λοιπόν, ας ξεκινήσουμε με την εφαρμογή του Μοτίβο αποθήκης στο Laravel 9.
Θα επιτύχουμε τα παρακάτω αποτελέσματα χρησιμοποιώντας το Μοτίβο σχεδίασης αποθετηρίου στο Laravel 9.
Προαπαιτούμενα
Δεν συνιστάται η χρήση του Laravel 9 (Η πιο πρόσφατη έκδοση τώρα) για την υλοποίηση του Μοτίβο σχεδίασης αποθετηρίου. Μπορείτε να το χρησιμοποιήσετε και στις προηγούμενες εκδόσεις του Laravel.
Θα έχω μια νέα εγκατάσταση έργου στο Laravel 9. Για να το κάνετε αυτό, θα χρειαστεί να έχετε τις ακόλουθες διαμορφώσεις και εργαλεία.
- PHP >=8.0.2
- Συνθέτης
- Διακομιστής Apache/Nginx
- VS Code Editor (Προαιρετικό)
- MySQL (έκδοση > 5)
Τώρα, ας μεταβούμε στο πρώτο βήμα της ρύθμισης του έργου.
Δημιουργήστε ένα έργο Laravel για την υλοποίηση του μοτίβου σχεδίασης αποθετηρίου
Για τη δημιουργία ενός έργου, θα χρησιμοποιήσω τον συνθέτη. Μπορείτε να ανοίξετε το τερματικό και να δημιουργήσετε ένα έργο χρησιμοποιώντας την παρακάτω εντολή.
composer create-project --prefer-dist laravel/laravel repository-app
Θα δημιουργήσω μια βασική εφαρμογή CRUD εφαρμόζοντας το Μοτίβο σχεδίασης αποθετηρίου.
Μόλις δημιουργηθεί το έργο, ας διαμορφώσουμε μια βάση δεδομένων για αυτό.
Πώς να δημιουργήσετε ένα αρχείο Zip με οποιοδήποτε αρχείο και να το κατεβάσετε στο Laravel 9
Δημιουργήστε και διαμορφώστε μια βάση δεδομένων για το έργο Laravel
Για τη βάση δεδομένων, θα χρησιμοποιώ MySQL και για τη διαχείριση, χρησιμοποιώ phpMyAdmin. Εδώ, έχω δημιουργήσει μια βάση δεδομένων.
CREATE DATABASE laravel_db;
Αφού δημιουργήσετε τη βάση δεδομένων, ήρθε η ώρα να τη συνδέσετε με το έργο. Ως εκ τούτου, πλοηγηθείτε στο .env αρχείο του έργου και ρυθμίστε το DB.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME={{ DB_USERNAME }}
DB_PASSWORD={{ DB_PASSWORD }}
Τώρα, η ώρα είναι να δημιουργήσετε μια εφαρμογή CRUD χρησιμοποιώντας το μοτίβο του Αποθετηρίου.
Δημιουργία μοντέλου, μετεγκατάστασης και ελεγκτή
Θα δημιουργήσω μια απλή εφαρμογή ιστολογίου στην οποία θα έχουμε το περιεχόμενο της ανάρτησης. Άρα, θα κάνουμε αίτηση CRUD λειτουργίες για την ανάρτηση ιστολογίου χρησιμοποιώντας το Μοτίβο σχεδίασης αποθετηρίου.
Επομένως, πατήστε την παρακάτω εντολή για να δημιουργήσετε ένα μοντέλο, μια μετεγκατάσταση και έναν ελεγκτή.
php artisan make:model Post -mc
Η εντολή θα δημιουργήσει αυτά τα τρία αρχεία μαζί.
Τώρα, στο επόμενο βήμα, πρέπει να δημιουργήσετε ένα σχήμα πίνακα για τον πίνακα αναρτήσεων. Ας το κάνουμε αυτό όπως φαίνεται παρακάτω.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title')->nullable();
$table->text('content')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
};
Ομοίως, πρέπει να προσθέσετε μια ιδιότητα με δυνατότητα συμπλήρωσης στο αντίστοιχο μοντέλο.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'content'
];
}
Τώρα, το σχήμα πίνακα είναι έτοιμο για μετεγκατάσταση στη βάση δεδομένων. Ας μεταφέρουμε τον πίνακα.
Συνιστάται: Πώς να ανεβάσετε εικόνα χρησιμοποιώντας τον Ajax στο Laravel 9 με επικύρωση
Για τη μετεγκατάσταση του(των) πίνακα(ων) πρέπει να πατήσετε την παρακάτω εντολή artisan.
php artisan migrate
Στο επόμενο βήμα, ας κάνουμε μια ρύθμιση για το Μοτίβο σχεδίασης αποθετηρίου για αυτό το έργο.
Πώς να χρησιμοποιήσετε ομαδικές διαδρομές για τον ίδιο ελεγκτή στο Laravel 9
Ρύθμιση μοτίβου σχεδίασης αποθετηρίου στο Laravel
Στο ίδιο βήμα, πρέπει να δημιουργήσετε έναν φάκελο με το όνομα Διεπαφές μέσα στο φάκελο της εφαρμογής. Τώρα, μέσα σε αυτόν τον φάκελο δημιουργήστε ένα νέο αρχείο διεπαφής με το όνομα PostInterface.php.
Έτσι, η δομή του φακέλου θα είναι έτσι –
app
|___ Interfaces
| |______ PostInterface.php
|
|
Μετά από αυτό, πρέπει να δηλώσετε τις πιθανές λειτουργίες όπως απαιτείται. Εδώ, θα δημιουργήσουμε ένα CRUD εφαρμογή. Ως εκ τούτου, δηλώνουμε τις παρακάτω συναρτήσεις.
<?php
namespace App\Interfaces;
interface PostInterface
{
public function getAllPosts();
public function createPost($request);
public function getPostById($postId);
public function updatePost($request, $postId);
public function deletePost($postId);
}
Αφού ορίσουμε τις λειτουργίες στο Interface, θα δημιουργήσουμε το Repository όπου θα υλοποιηθεί αυτή η διεπαφή.
Πώς να εκκαθαρίσετε την προσωρινή μνήμη εφαρμογών χωρίς γραμμή εντολών στο Laravel
Δημιουργώ ένα Αποθετήριο στο Laravel
Παρόμοια με το Διεπαφέςδημιουργήστε έναν άλλο φάκελο με το όνομα Αποθετήρια μεσα στην εφαρμογή ντοσιέ. Τώρα, μέσα σε αυτόν τον φάκελο δημιουργήστε μια κλάση με το όνομα PostRepository.php. Έτσι, η δομή του φακέλου θα φαίνεται όπως φαίνεται παρακάτω.
app
|___ Interfaces
| |______ PostInterface.php
|
|___ Repositories
| |______ PostRepository.php
|
|
Μόλις τελειώσετε με PostRepository class, ας προσθέσουμε την υλοποίηση των μεθόδων διεπαφής.
<?php
namespace App\Repositories;
use App\Interfaces\PostInterface;
use App\Models\Post;
class PostRepository implements PostInterface
{
/**
* Function : Get All Posts
* @param NA
* @return posts
*/
public function getAllPosts()
{
return Post::all();
}
/**
* Function : Create Post
*
* @param [type] $request
* @return post
*/
public function createPost($request)
{
return Post::create([
'title' => $request->title,
'content' => $request->content,
]);
}
/**
* Function : Get Post By Id
* @param [type] $id
* @return post
*/
public function getPostById($id)
{
return Post::find($id);
}
/**
* Function : Update Post
*
* @param [type] $request
* @param [type] $id
* @return post
*/
public function updatePost($request, $id)
{
$post = Post::find($id);
if ($post) {
$post['title'] = $request->title;
$post['content'] = $request->content;
$post->save();
return $post;
}
}
/**
* Function : Delete Post
* @param [type] $id
* @return void
*/
public function deletePost($id)
{
$post = Post::find($id);
if ($post) {
return $post->delete();
}
}
}
Εδώ, σε αυτό αποθήκη class, έχουμε εφαρμόσει τις μεθόδους του διεπαφή. Τώρα, έχουμε σχεδόν τελειώσει με το κομμάτι της λειτουργικότητας.
Απομένει όμως το πιο σημαντικό βήμα που είναι η δέσμευση Διεπαφή και Αποθήκη μαζί. Μετά από αυτό το βήμα, θα μπορούμε να καλούμε μεθόδους κλάσης Repository μέσω της διεπαφής. Λοιπόν, ας το κάνουμε αυτό.
Αποσυνδεθείτε από πολλαπλές περιόδους ελέγχου ταυτότητας από άλλες συσκευές στο Laravel 9
Συνδέστε τη διεπαφή και το αποθετήριο μαζί
Για να συνδέσουμε την κλάση αποθετηρίου και τη διεπαφή, θα χρειαστούμε έναν πάροχο υπηρεσιών. Επομένως, επιστρέψτε στο τερματικό και δημιουργήστε μια κλάση παρόχου όπως φαίνεται παρακάτω.
php artisan make:provider RepositoryServiceProvider
Αφού δημιουργήσουμε αυτόν τον πάροχο, θα συνδέσουμε την κλάση Interface και Repository μεταξύ τους.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Interfaces\PostInterface;
use App\Repositories\PostRepository;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
// Bind Interface and Repository class together
$this->app->bind(PostInterface::class, PostRepository::class);
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
//
}
}
Τώρα, στο επόμενο βήμα, πρέπει να καταχωρήσουμε αυτήν την κλάση ServiceProvider στη διαμόρφωση.
Συνιστάται: Πώς να δημιουργήσετε μια εφαρμογή CRUD χρησιμοποιώντας τον Ajax στο Laravel 9
Εγγραφή παρόχου υπηρεσιών στη Laravel
Για να εγγράψετε τον πάροχο υπηρεσιών, πρέπει να πλοηγηθείτε στο config->app.php αρχείο στο έργο. Τώρα, μέσα στον πίνακα παρόχων, προσθέστε τον παροχέα υπηρεσιών που δημιουργήθηκε όπως φαίνεται παρακάτω.
'providers' => [
......
......
......
App\Providers\RepositoryServiceProvider::class,
],
Έτσι, ο πάροχος υπηρεσιών είναι εγγεγραμμένος. Τώρα, στο επόμενο βήμα, θα γράψουμε τη λογική του ελεγκτή μας μέσα στο PostController.php αρχείο.
Δημιουργία λειτουργικότητας CRUD στον ελεγκτή
Έχουμε ήδη δημιουργήσει το PostController.php αρχείο. Εδώ, στο πρώτο βήμα, θα χρειαστεί να δημιουργήσετε έναν κατασκευαστή και να καλέσετε τη διεπαφή ώστε να καλέσουμε τις μεθόδους.
<?php
namespace App\Http\Controllers;
use App\Interfaces\PostInterface;
use Illuminate\Http\Request;
class PostController extends Controller
{
private $postInterface;
public function __construct(PostInterface $postInterface)
{
$this->postInterface = $postInterface;
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$posts = $this->postInterface->getAllPosts();
return view('posts.index', compact('posts'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('posts.create');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
try {
$post = $this->postInterface->createPost($request);
if ($post) {
return redirect()->route('posts.index')->with('success', 'Success! post is created');
} else {
return back()->with('failed', 'Failed! unable to create post');
}
} catch (Exception $e) {
return back()->with('failed', $e->getMessage());
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
try {
$post = $this->postInterface->getPostById($id);
if ($post) {
$isView = true;
return view('posts.create', compact('post', 'isView'));
} else {
return redirect('posts.index')->with('failed', 'Failed! no post found');
}
} catch (Exception $e) {
return redirect('posts.index')->with('failed', $e->getMessage());
}
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
try {
$post = $this->postInterface->getPostById($id);
if ($post) {
$isEdit = true;
return view('posts.create', compact('post', 'isEdit'));
} else {
return redirect('posts.index')->with('failed', 'Failed! no post found');
}
} catch (Exception $e) {
return redirect('posts.index')->with('failed', $e->getMessage());
}
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
try {
$post = $this->postInterface->updatePost($request, $id);
if ($post) {
return redirect()->route('posts.index')->with('success', 'Success! post is updated');
} else {
return back()->with('failed', 'Failed! unable to update post');
}
} catch (Exception $e) {
return back()->with('failed', $e->getMessage());
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
try {
$post = $this->postInterface->deletePost($id);
if ($post) {
return redirect()->route('posts.index')->with('success', 'Success! post is deleted');
} else {
return back()->with('failed', 'Failed! unable to delete post');
}
} catch (Exception $e) {
return back()->with('failed', $e->getMessage());
}
}
}
Στη συνέχεια, σύμφωνα με την απαίτηση, πρέπει να δημιουργήσετε μερικά αρχεία blade για την απόδοση του περιεχομένου.
Ενσωμάτωση Mailgun Laravel για αποστολή email στο Laravel 9
Δημιουργήστε προβολές για την υλοποίηση του CRUD χρησιμοποιώντας το μοτίβο σχεδίασης αποθετηρίου
Κυρίως, χρειαζόμασταν τρία αρχεία blade όπως φαίνεται παρακάτω. Όμως, έχω κρατήσει αυτά τα αρχεία blade μέσα στο φάκελο ανάρτησης.
- master.blade.php
- create.blade.php
- index.blade.php
Επομένως, η δομή φακέλων των προβολών θα πρέπει να είναι αυτή.
resources
|_____ Views
| |_____ master.blade.php
| |_____ posts
| | |_____ create.blade.php
| | |_____ index.blade.php
| |
Αφού δημιουργήσουμε αυτές τις λεπίδες, ας ξεκινήσουμε με την κύρια λεπίδα. Αυτό θα περιέχει το bootstrap και το κύριο τμήμα που θα επεκταθεί περαιτέρω στις παιδικές λεπίδες.
<!doctype html>
<html lang="en">
<head>
<title>Laravel Repository Design Pattern | Programming Fields</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
</head>
<body>
<section class="py-4">
<h3 class="text-center fw-bold">Repository Design Pattern | Programming Fields</h3>
@yield('content')
</section>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"
integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous">
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
integrity="sha384-7VPbUDkoPSGFnVtYi0QogXtr74QeVeeIs99Qfg5YCF+TidwNdjvaKZX19NZ/e6oz" crossorigin="anonymous">
</script>
</body>
</html>
Στη συνέχεια, προσθέστε το παρακάτω απόσπασμα στο index.blade.php αρχείο. Αυτό θα περιέχει τη λίστα των αναρτήσεων με μια επιλογή δημιουργίας.
@extends('master')
@section('content')
<div class="container my-5">
<div class="row">
<div class="col-xl-6">
@if (Session::has('success'))
<div class="alert alert-success d-flex align-items-center alert-dismissible fade show" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:">
<use xlink:href="#check-circle-fill" />
</svg>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
<div>
{{ Session::get('success') }}
</div>
</div>
@elseif (Session::has('failed'))
<div class="alert alert-danger d-flex align-items-center alert-dismissible fade show" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img"
aria-label="Danger:">
<use xlink:href="#exclamation-triangle-fill" />
</svg>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
<div>
{{ Session::get('failed') }}
</div>
</div>
@endif
</div>
<div class="col-xl-6 text-end">
<a href="{{ route('posts.create') }}" class="btn btn-primary"> Create Post </a>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped table-light">
<thead>
<tr>
<th scope="col" width="10%">#</th>
<th scope="col">Title</th>
<th scope="col">Content</th>
<th scope="col" width="20%">Action</th>
</tr>
</thead>
<tbody>
@forelse ($posts as $post)
<tr>
<td>{{ $post->id }}</td>
<td scope="row">{{ $post->title ?? '-' }}</td>
<td>{{ $post->content ?? '-' }}</td>
<td>
<form action="{{ route('posts.destroy', $post->id) }}" method="POST">
@csrf
@method('DELETE')
<a href="{{ route('posts.show', $post->id) }}" class="btn btn-sm btn-info">View</a>
<a href="{{ route('posts.edit', $post->id) }}" class="btn btn-sm btn-success">Edit</a>
<button type="submit" class="btn btn-sm btn-danger">Delete</button>
</form>
</td>
</tr>
@empty
<tr>
<td scope="row" colspan="4">
<p class="text-danger text-center">No post found!</p>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
@endsection
Το τελευταίο, έχουμε τη λεπίδα δημιουργίας. Επομένως, προσθέστε το παρακάτω απόσπασμα σε αυτό το blade αρχείο.
@extends('master')
@section('content')
@php $view = $isView ?? false;
$edit = $isEdit ?? false;
@endphp
<div class="container my-5">
<div class="row">
<div class="col-xl-6 col-12 m-auto">
<form action="{{ $edit ? route('posts.update', $post->id) : route('posts.store') }}" method="POST" class="w-100">
@csrf
@if ($edit)
@method('PUT')
@endif
<div class="card shadow">
<div class="card-header">
<h4 class="card-title"> {{ $view ? 'View' : ($edit ? 'Update' : 'Create')}} Post</h4>
</div>
<div class="card-body">
<div class="form-group my-2">
<label for="title" class="form-label">Title <span class="text-danger">*</span></label>
<input type="text" name="title" @if ($view) disabled @endif class="form-control" id="title" required value="{{ old('title') ?? ($post->title ?? '') }}">
</div>
<div class="form-group my-2">
<label for="content" class="form-label">Content <span class="text-danger">*</span></label>
<textarea name="content" @if ($view) disabled @endif class="form-control" id="content" required>{{ old('content') ?? ($post->content ?? '') }}</textarea>
</div>
</div>
<div class="card-footer">
<a href="{{route('posts.index')}}" class="btn btn-secondary">Back</a>
@if (!$view)
<button type="submit" class="btn btn-primary">Save</button>
@endif
</div>
</div>
</form>
</div>
</div>
</div>
@endsection
Τέλος, πρέπει να προσθέσετε τη διαδρομή για τον ελεγκτή θέσης.
Συνιστάται: Πώς να χρησιμοποιήσετε ομαδικές διαδρομές για τον ίδιο ελεγκτή στο Laravel 9
Προσθήκη δρομολογίων για τον ελεγκτή θέσης
Για να προσθέσετε τη διαδρομή, μεταβείτε στο web.php αρχείο και προσθέστε τη διαδρομή όπως φαίνεται παρακάτω.
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
Route::resource('posts', PostController::class);
Αυτό είναι για το Μοτίβο σχεδίασης αποθετηρίου στη Laravel. Τώρα, μπορείτε να εκτελέσετε την εφαρμογή για να ελέγξετε τα αποτελέσματα.
Κατώτατες γραμμές
Τέλος, εφαρμόσαμε το Μοτίβο σχεδίασης αποθετηρίου στο Laravel με ένα παράδειγμα εφαρμογής CRUD. Αυτή ήταν απλώς μια βασική επίδειξη χρήσης του μοτίβο σχεδίασης σε έργα Laravel. Μπορείτε να το επεκτείνετε σε ένα πιο προηγμένο επίπεδο σύμφωνα με την απαίτηση του έργου. Ελπίζω ότι αυτή η ανάρτηση θα σας φανεί χρήσιμη.
Σε περίπτωση οποιουδήποτε ζητήματος ή βοήθειας σχετικά με αυτήν την ανάρτηση ή οποιοδήποτε ερώτημα, μπορείτε να επικοινωνήσετε μαζί μου γράφοντας στην παρακάτω ενότητα σχολίων. Θα προσπαθήσω να λύσω τα προβλήματά σας το συντομότερο.