1. Home
  2. Laravel
  3. Basic
  4. 1.3 Crud tutorial

1.3 Crud tutorial

ধাপ ১: Laravel ইন্সটলেশন ও প্রজেক্ট সেটআপ

১.১ Laravel ইন্সটলেশন

প্রথমে আপনার কম্পিউটারে নিশ্চিত করুন যে নিচের সফটওয়্যারগুলো ইন্সটল করা আছে:

  • PHP (8.0 বা তার উপরে)
  • Composer
  • MySQL বা অন্য কোনো ডাটাবেস

কমান্ড দিয়ে Laravel ইন্সটল করুন:

composer create-project laravel/laravel student-crud
cd student-crud

১.২ প্রজেক্ট স্ট্রাকচার বোঝা

Laravel ইন্সটল করলে নিচের ফোল্ডার স্ট্রাকচার তৈরি হবে:

  • app/ – এপ্লিকেশনের মূল লজিক (মডেল, কন্ট্রোলার ইত্যাদি)
  • database/ – মাইগ্রেশন, সিডার, ফ্যাক্টরি
  • public/ – পাবলিক অ্যাক্সেসযোগ্য ফাইল (CSS, JS, images)
  • resources/ – ভিউ ফাইল এবং ফ্রন্টএন্ড অ্যাসেট
  • routes/ – সব রাউট ডেফিনিশন
  • vendor/ – কম্পোজার ডিপেন্ডেন্সি

ধাপ ২: ডাটাবেস কনফিগারেশন

২.১ .env ফাইল এডিট করুন

.env ফাইলটি আপনার প্রজেক্টের রুট ডিরেক্টরিতে আছে। এখানে ডাটাবেস কনফিগারেশন সেট করুন:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=student_crud
DB_USERNAME=root
DB_PASSWORD=

২.২ ডাটাবেস তৈরি করুন

MySQL কমান্ড লাইন বা PHPMyAdmin ব্যবহার করে ডাটাবেস তৈরি করুন:

CREATE DATABASE student_crud;

ধাপ ৩: মডেল ও মাইগ্রেশন তৈরি

৩.১ মডেল কি?

মডেল হলো ডাটাবেস টেবিলের PHP রিপ্রেজেন্টেশন। এটি এলোকুয়েন্ট ORM ব্যবহার করে ডাটাবেসের সাথে ইন্টারঅ্যাক্ট করে।

৩.২ মডেল ও মাইগ্রেশন তৈরি

php artisan make:model Student -m

এই কমান্ডে:

  • -m ফ্লাগ মডেলের সাথে একটি মাইগ্রেশন ফাইলও তৈরি করবে

৩.৩ মাইগ্রেশন কি?

মাইগ্রেশন হলো ডাটাবেস টেবিল তৈরি/পরিবর্তনের জন্য ভার্সন কন্ট্রোল সিস্টেম। এটি PHP কোডে ডাটাবেস স্কিমা ডিফাইন করে।

৩.৪ মাইগ্রেশন ফাইল এডিট করুন

database/migrations/xxxx_create_students_table.php ফাইলটি নিম্নরূপ করুন:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up()
    {
        Schema::create('students', function (Blueprint $table) {
            $table->id(); // অটো-ইনক্রিমেন্ট প্রাইমারি কি
            $table->string('name'); // স্টুডেন্ট নাম
            $table->string('email')->unique(); // ইউনিক ইমেইল
            $table->string('phone'); // ফোন নাম্বার
            $table->string('course'); // কোর্স নাম
            $table->string('image')->nullable(); // ইমেজ পাথ (নাল হতে পারে)
            $table->timestamps(); // created_at  updated_at টাইমস্ট্যাম্প
        });
    }

    public function down()
    {
        Schema::dropIfExists('students');
    }
};

৩.৫ মাইগ্রেশন রান করুন

php artisan migrate

ধাপ ৪: মডেল সেটআপ

৪.১ Mass Assignment

app/Models/Student.php ফাইলটি নিম্নরূপ করুন:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Student extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'email',
        'phone',
        'course',
        'image'
    ];
}

protected $fillable এর ব্যাখ্যা:

  • এটি একটি সিকিউরিটি ফিচার
  • শুধুমাত্র এই ফিল্ডগুলোই mass assignment এর জন্য allowed
  • Mass assignment মানে হলো Student::create($request->all()) এর মতো এক লাইনে অনেক ডাটা ইনসার্ট করা

ধাপ ৫: কন্ট্রোলার তৈরি

৫.১ কন্ট্রোলার কি?

কন্ট্রোলার রিকুয়েস্ট হ্যান্ডল করে এবং রেস্পন্স রিটার্ন করে। এটি মডেল ও ভিউ এর মধ্যে মধ্যস্থতাকারী।

৫.২ Resource কন্ট্রোলার তৈরি

php artisan make:controller StudentController --resource

এই কমান্ডে --resource ফ্লাগ CRUD অপারেশনের জন্য প্রি-ডিফাইন্ড মেথড তৈরি করে।

৫.৩ কন্ট্রোলার মেথডগুলোর কাজ

app/Http/Controllers/StudentController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Student;
use Illuminate\Http\Request;

class StudentController extends Controller
{
    // সব স্টুডেন্ট দেখাবে
    public function index()
    {
        $students = Student::all(); // সব স্টুডেন্ট নেয়া
        return view('students.index', compact('students')); // ভিউতে ডাটা পাস করা
    }

    // নতুন স্টুডেন্ট ফর্ম দেখাবে
    public function create()
    {
        return view('students.create'); // ক্রিয়েট ফর্ম ভিউ
    }

    // নতুন স্টুডেন্ট স্টোর করবে
    public function store(Request $request)
    {
        // ভ্যালিডেশন
        $request->validate([
            'name' => 'required',
            'email' => 'required|email|unique:students',
            'phone' => 'required',
            'course' => 'required',
            'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
        ]);

        // ইমেজ আপলোড
        $imageName = time().'.'.$request->image->extension();  
        $request->image->move(public_path('images'), $imageName);

        // ডাটাবেসে সেভ
        Student::create([
            'name' => $request->name,
            'email' => $request->email,
            'phone' => $request->phone,
            'course' => $request->course,
            'image' => $imageName,
        ]);

        return redirect()->route('students.index')->with('success', 'Student created successfully.');
    }

    // একটি স্টুডেন্ট দেখাবে
    public function show(Student $student)
    {
        return view('students.show', compact('student'));
    }

    // স্টুডেন্ট এডিট ফর্ম দেখাবে
    public function edit(Student $student)
    {
        return view('students.edit', compact('student'));
    }

    // স্টুডেন্ট আপডেট করবে
    public function update(Request $request, Student $student)
    {
        $request->validate([
            'name' => 'required',
            'email' => 'required|email|unique:students,email,'.$student->id,
            'phone' => 'required',
            'course' => 'required',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
        ]);

        // নতুন ইমেজ আপলোড হলে
        if($request->hasFile('image')){
            // পুরাতন ইমেজ ডিলিট
            if($student->image && file_exists(public_path('images/'.$student->image))){
                unlink(public_path('images/'.$student->image));
            }

            // নতুন ইমেজ সেভ
            $imageName = time().'.'.$request->image->extension();  
            $request->image->move(public_path('images'), $imageName);
            $student->image = $imageName;
        }

        // ডাটা আপডেট
        $student->name = $request->name;
        $student->email = $request->email;
        $student->phone = $request->phone;
        $student->course = $request->course;
        $student->save();

        return redirect()->route('students.index')->with('success', 'Student updated successfully.');
    }

    // স্টুডেন্ট ডিলিট করবে
    public function destroy(Student $student)
    {
        // ইমেজ ডিলিট
        if($student->image && file_exists(public_path('images/'.$student->image))){
            unlink(public_path('images/'.$student->image));
        }

        // ডাটাবেস থেকে ডিলিট
        $student->delete();
        return redirect()->route('students.index')->with('success', 'Student deleted successfully.');
    }
}

ধাপ ৬: রাউট সেটআপ

৬.১ রাউট কি?

রাউট নির্ধারণ করে কোন URL এ কোন কন্ট্রোলার মেথড কল হবে।

৬.২ রাউট ফাইল এডিট

routes/web.php:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\StudentController;

// রিসোর্স রাউট সব CRUD রাউট একসাথে তৈরি করে
Route::resource('students', StudentController::class);

৬.৩ Resource রাউট দ্বারা তৈরি রাউটগুলো:

HTTP MethodURIActionRoute Name
GET/studentsindexstudents.index
GET/students/createcreatestudents.create
POST/studentsstorestudents.store
GET/students/{student}showstudents.show
GET/students/{student}/editeditstudents.edit
PUT/PATCH/students/{student}updatestudents.update
DELETE/students/{student}destroystudents.destroy

ধাপ ৭: ভিউ তৈরি

৭.১ লেআউট ফাইল

resources/views/layouts/app.blade.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Student CRUD</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        @yield('content')
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

৭.২ ইনডেক্স ভিউ

resources/views/students/index.blade.php:

@extends('layouts.app')

@section('content')
<div class="container mt-5">
    <h2 class="mb-4">Students List</h2>
    <a href="{{ route('students.create') }}" class="btn btn-success mb-3">Add New Student</a>

    @if(session('success'))
        <div class="alert alert-success">
            {{ session('success') }}
        </div>
    @endif

    <table class="table table-bordered">
        <thead>
            <tr>
                <th>ID</th>
                <th>Image</th>
                <th>Name</th>
                <th>Email</th>
                <th>Phone</th>
                <th>Course</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            @foreach($students as $student)
            <tr>
                <td>{{ $student->id }}</td>
                <td>
                    @if($student->image)
                        <img src="{{ asset('images/'.$student->image) }}" width="50" height="50" class="rounded-circle">
                    @else
                        No Image
                    @endif
                </td>
                <td>{{ $student->name }}</td>
                <td>{{ $student->email }}</td>
                <td>{{ $student->phone }}</td>
                <td>{{ $student->course }}</td>
                <td>
                    <a href="{{ route('students.show', $student->id) }}" class="btn btn-info btn-sm">View</a>
                    <a href="{{ route('students.edit', $student->id) }}" class="btn btn-primary btn-sm">Edit</a>
                    <form action="{{ route('students.destroy', $student->id) }}" method="POST" class="d-inline">
                        @csrf
                        @method('DELETE')
                        <button type="submit" class="btn btn-danger btn-sm">Delete</button>
                    </form>
                </td>
            </tr>
            @endforeach
        </tbody>
    </table>
</div>
@endsection

৭.৩ ক্রিয়েট ফর্ম

resources/views/students/create.blade.php:

@extends('layouts.app')

@section('content')
<div class="container mt-5">
    <h2>Create New Student</h2>

    <form method="POST" action="{{ route('students.store') }}" enctype="multipart/form-data">
        @csrf

        <div class="mb-3">
            <label for="name" class="form-label">Name</label>
            <input type="text" class="form-control" id="name" name="name" required>
        </div>

        <div class="mb-3">
            <label for="email" class="form-label">Email</label>
            <input type="email" class="form-control" id="email" name="email" required>
        </div>

        <div class="mb-3">
            <label for="phone" class="form-label">Phone</label>
            <input type="text" class="form-control" id="phone" name="phone" required>
        </div>

        <div class="mb-3">
            <label for="course" class="form-label">Course</label>
            <input type="text" class="form-control" id="course" name="course" required>
        </div>

        <div class="mb-3">
            <label for="image" class="form-label">Image</label>
            <input type="file" class="form-control" id="image" name="image" required>
        </div>

        <button type="submit" class="btn btn-primary">Submit</button>
        <a href="{{ route('students.index') }}" class="btn btn-secondary">Cancel</a>
    </form>
</div>
@endsection

ধাপ ৮: ইমেজ আপলোড সেটআপ

৮.১ পাবলিক ইমেজ ফোল্ডার তৈরি

mkdir public/images
chmod -R 755 public/images

৮.২ ইমেজ আপলোড লজিক

কন্ট্রোলারে ইমেজ আপলোড করার কোড:

$imageName = time().'.'.$request->image->extension();  
$request->image->move(public_path('images'), $imageName);

এখানে:

  • time() ব্যবহার করে ইউনিক ফাইলনেম তৈরি করা হচ্ছে
  • extension() দিয়ে ফাইল এক্সটেনশন নেয়া হচ্ছে
  • move() দিয়ে ফাইল পাবলিক/ইমেজ ফোল্ডারে সেভ করা হচ্ছে

ধাপ ৯: অ্যাপ্লিকেশন টেস্টিং

সার্ভার চালু করুন:

php artisan serve

এখন ব্রাউজারে ভিজিট করুন: http://localhost:8000/students

সমস্যা সমাধান

১. ইমেজ আপলোড না হলে:

  • ফোল্ডার পারমিশন চেক করুন (public/images)
  • php artisan storage:link কমান্ড রান করুন

২. ডাটাবেস কানেকশন এরর:

  • .env ফাইলের ডাটাবেস ক্রেডেনশিয়াল চেক করুন
  • MySQL সার্ভার চালু আছে কিনা দেখুন

৩. রাউট কাজ না করলে:

  • php artisan route:list কমান্ড দিয়ে রাউট লিস্ট চেক করুন

How can we help?