๐Ÿ’ป์ปดํ“จํ„ฐ ๊ธฐ๋ก์žฅ/PHP

Laravel ์‹ค์Šต : ํ•  ์ผ ๋ชฉ๋ก(To-Do List)

dd_blog 2024. 11. 8. 17:22
728x90

์‹ค์Šต ๊ฐœ์š”

  1. ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™” ๋ฐ ์„ค์ •
  2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ •
  3. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ƒ์„ฑ ๋ฐ ์‹คํ–‰ (ํ•  ์ผ ๋ชฉ๋ก ํ…Œ์ด๋ธ” ๋งŒ๋“ค๊ธฐ)
  4. ๋ชจ๋ธ๊ณผ ์ปจํŠธ๋กค๋Ÿฌ ์ƒ์„ฑ
  5. ๋ผ์šฐํŒ… ๋ฐ ๋ทฐ ํŒŒ์ผ ์ƒ์„ฑ
  6. CRUD ๊ธฐ๋Šฅ ์ถ”๊ฐ€ (ํ•  ์ผ ์ถ”๊ฐ€, ์กฐํšŒ, ์ˆ˜์ •, ์‚ญ์ œ)

 

1. Laravel ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

ํ„ฐ๋ฏธ๋„์—์„œ Laravel ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 
composer create-project --prefer-dist laravel/laravel="8.*" todo-app

 

 

 

2. MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ •

MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์‚ฌ์šฉ์ž ๊ณ„์ •์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ํ„ฐ๋ฏธ๋„์ด๋‚˜ MySQL ํด๋ผ์ด์–ธํŠธ์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

CREATE DATABASE todo_app;
CREATE USER 'todo_user'@'localhost' IDENTIFIED BY 'password123';
GRANT ALL PRIVILEGES ON todo_app.* TO 'todo_user'@'localhost';
FLUSH PRIVILEGES;

 

์ด ๋ช…๋ น์–ด๋กœ todo_app๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ todo_user๋ผ๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ password123์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

 

3. Laravel .env ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์„ค์ •

Laravel ํ”„๋กœ์ ํŠธ ํด๋”์— ์žˆ๋Š” .env ํŒŒ์ผ์„ ์—ด๊ณ , ๋‹ค์Œ ์„ค์ •์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=todo_app
DB_USERNAME=todo_user
DB_PASSWORD=password123

 

((MySQL ์ •๋ณด์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜์„ธ์š”.))

 

4. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ƒ์„ฑ: ํ•  ์ผ ๋ชฉ๋ก ํ…Œ์ด๋ธ” ๋งŒ๋“ค๊ธฐ

ํ•  ์ผ ๋ชฉ๋ก์„ ์ €์žฅํ•  ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

php artisan make:migration create_tasks_table --create=tasks

 

์ด ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด database/migrations ํด๋”์— ์ƒˆ๋กœ์šด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

 

ํŒŒ์ผ์„ ์—ด์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ…Œ์ด๋ธ” ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

// database/migrations/xxxx_xx_xx_xxxxxx_create_tasks_table.php

public function up()
{
    Schema::create('tasks', function (Blueprint $table) {
        $table->id();
        $table->string('title');       // ํ•  ์ผ ์ œ๋ชฉ
        $table->text('description');   // ํ•  ์ผ ์„ค๋ช…
        $table->boolean('completed')->default(false); // ์™„๋ฃŒ ์—ฌ๋ถ€
        $table->timestamps();          // ์ƒ์„ฑ ๋ฐ ์ˆ˜์ • ์‹œ๊ฐ„
    });
}โ€‹

 

์ด์ œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์‹คํ–‰ํ•˜์—ฌ tasks ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

php artisan migrate

 

5. ๋ชจ๋ธ ์ƒ์„ฑ: Task ๋ชจ๋ธ ๋งŒ๋“ค๊ธฐ

Eloquent ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด tasks ํ…Œ์ด๋ธ”์„ ์กฐ์ž‘ํ•ฉ๋‹ˆ๋‹ค. Task ๋ชจ๋ธ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

php artisan make:model Task

 

app/Models/Task.php ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ๋ชจ๋ธ์ด ์–ด๋–ค ํ•„๋“œ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

 

// app/Models/Task.php

protected $fillable = ['title', 'description', 'completed'];

 

 

6. ์ปจํŠธ๋กค๋Ÿฌ ์ƒ์„ฑ ๋ฐ ๋กœ์ง ์ถ”๊ฐ€

ํ•  ์ผ ๋ชฉ๋ก์˜ CRUD ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•  ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

php artisan make:controller TaskController

 

TaskController.php ํŒŒ์ผ์„ ์—ด๊ณ , ํ•  ์ผ ๋ชฉ๋ก์˜ ๊ฐ ๊ธฐ๋Šฅ (๋ชฉ๋ก ์กฐํšŒ, ์ถ”๊ฐ€, ์ˆ˜์ •, ์‚ญ์ œ)์„ ์œ„ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

// app/Http/Controllers/TaskController.php

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

class TaskController extends Controller
{
    // ํ•  ์ผ ๋ชฉ๋ก ์กฐํšŒ
    public function index()
    {
        $tasks = Task::all();
        return view('tasks.index', compact('tasks'));
    }

    // ํ•  ์ผ ์ถ”๊ฐ€ ํผ ํ‘œ์‹œ
    public function create()
    {
        return view('tasks.create');
    }

    // ํ•  ์ผ ์ €์žฅ
    public function store(Request $request)
    {
        Task::create($request->all());
        return redirect()->route('tasks.index');
    }

    // ํ•  ์ผ ์ˆ˜์ • ํผ ํ‘œ์‹œ
    public function edit(Task $task)
    {
        return view('tasks.edit', compact('task'));
    }

    // ํ•  ์ผ ์—…๋ฐ์ดํŠธ
    public function update(Request $request, Task $task)
    {
        $task->update($request->all());
        return redirect()->route('tasks.index');
    }

    // ํ•  ์ผ ์‚ญ์ œ
    public function destroy(Task $task)
    {
        $task->delete();
        return redirect()->route('tasks.index');
    }
}

 

7. ๋ผ์šฐํŒ… ์„ค์ •

routes/web.php ํŒŒ์ผ์—์„œ ๋ผ์šฐํŒ…์„ ์„ค์ •ํ•˜์—ฌ ๊ฐ URL์— ๋Œ€์‘ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

use App\Http\Controllers\TaskController;

Route::resource('tasks', TaskController::class);

 

Route::resource๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด index, create, store, edit, update, destroy์™€ ๊ฐ™์€ ๊ธฐ๋ณธ CRUD ๊ฒฝ๋กœ๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

 

8. ๋ทฐ ํŒŒ์ผ ์ƒ์„ฑ

ํ•  ์ผ ๋ชฉ๋ก ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ทฐ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. resources/views/tasks ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

ํ•  ์ผ ๋ชฉ๋ก ํŽ˜์ด์ง€ (index.blade.php)

<!-- resources/views/tasks/index.blade.php -->

<h1>ํ•  ์ผ ๋ชฉ๋ก</h1>
<a href="{{ route('tasks.create') }}">์ƒˆ ํ•  ์ผ ์ถ”๊ฐ€</a>

<ul>
    @foreach ($tasks as $task)
        <li>
            {{ $task->title }}
            <a href="{{ route('tasks.edit', $task) }}">์ˆ˜์ •</a>
            <form action="{{ route('tasks.destroy', $task) }}" method="POST" style="display:inline;">
                @csrf
                @method('DELETE')
                <button type="submit">์‚ญ์ œ</button>
            </form>
        </li>
    @endforeach
</ul>

 

 

์ƒˆ ํ•  ์ผ ์ถ”๊ฐ€ ํŽ˜์ด์ง€ (create.blade.php)

<!-- resources/views/tasks/create.blade.php -->

<h1>์ƒˆ ํ•  ์ผ ์ถ”๊ฐ€</h1>
<form action="{{ route('tasks.store') }}" method="POST">
    @csrf
    <label>์ œ๋ชฉ:</label>
    <input type="text" name="title">
    <label>์„ค๋ช…:</label>
    <textarea name="description"></textarea>
    <button type="submit">์ถ”๊ฐ€</button>
</form>

 

 

ํ•  ์ผ ์ˆ˜์ • ํŽ˜์ด์ง€ (edit.blade.php)

<!-- resources/views/tasks/edit.blade.php -->

<h1>ํ•  ์ผ ์ˆ˜์ •</h1>
<form action="{{ route('tasks.update', $task) }}" method="POST">
    @csrf
    @method('PUT')
    <label>์ œ๋ชฉ:</label>
    <input type="text" name="title" value="{{ $task->title }}">
    <label>์„ค๋ช…:</label>
    <textarea name="description">{{ $task->description }}</textarea>
    <button type="submit">์—…๋ฐ์ดํŠธ</button>
</form>

 

 

9. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰

์ด์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜์—ฌ ํ•  ์ผ ๋ชฉ๋ก ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”.

 

php artisan serve

 

 

๋ธŒ๋ผ์šฐ์ €์—์„œ http://127.0.0.1:8000/tasks๋กœ ์ ‘์†ํ•˜๋ฉด ํ•  ์ผ ๋ชฉ๋ก ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.