반응형

[기능설명]

articles 라는 테이블에 body값과 userId값을 받아 새로운 document 를 생성한다.

 

[1] 순수 PHP

//1. pdo 객체 만들고
$host=config('database.connections.mysql.host');
$dbname=config('database.connections.mysql.database');
$username=config('database.connections.mysql.username');
$password=config('database.connections.mysql.password');
$conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
//2. 쿼리준비
$stmt = $conn->prepare("INSERT INTO articles (body, user_id) VALUES (:body, :userId)");
//3. 쿼리 값을 설정
$user_id=
$stmt -> bindValue(':body', $input['body']);
$stmt->bindValue(':userId', Auth::id());
//4. 실행
$stmt->execute();

 

[2] DB 파사드 사용

먼서 DB 패키지 사용을 위해 import 해준다.

use Illuminate\Support\Facades\DB;

 

// 2) DB 파사드를 이용하는 방법 : Laravel 을 사용해 DB 사용하기
DB::insert ("INSERT INTO articles (body, user_id) VALUES (:body, :userId)", ['body' => $input['body'], 'userId' => Auth::id()]);

 

DB 뒤의 명령어는 상황에 따라 다른데 아래와 같다

- statement : insert, selectl, update, delete가 아닌 경우에 + index를 만든다거나 할때 사용한다
- CRUD : insert, select, update, delete 메소드 사용

 

[3] 쿼리 빌더 사용

1) insert 하기

// 3) 쿼리 빌더를 사용하는 방법
DB::table('articles') ->insert([
    'body' => $input['body'],
    'user_id' => Auth::id()
]);

 

위 방법대로 쿼리 빌더를 사용하면 1번이나 2번과 달리 query 문을 작성하지 않아도 된다는 점이 있다.

 

2) read 하기

> sail tinker
> DB::table('articles')->where('id',9)->first();
------------------------------------------------------
= {#5289
    +"id": 2,
    +"body": "<EB><91><90><EB><B2><88><EC><A7><B8> <EA><B8><80>~~",
    +"user_id": 1,
    +"created_at": "2024-05-02 05:40:39",
    +"updated_at": "2024-05-02 05:40:39",
  }

쿼리빌더를 사용해 데이터를 조회하면 standard class 로 조회되는걸 확인 할 수 있다.

 

3) Data converting : Article class

standard class로 받은 결과를 Article 클래스로 변환할 수 있다.

// 3-1) 쿼리빌더로 데이터 조회 후 Article class로 변환하기
$res = DB::table('articles')->where('id',2)->first();
$article = new Article;
$article->body=$res -> body;
$article->user_id = $res->user_id;

[4] Eloquent ORM 사용하기

Laravel 사용에서 아주아주 많이 이용된다는 Eloquent ORM을 사용해보자!

먼저 이를 사용하기 위해선 model을 생성해 주어야 한다.

1) model Class 생성하기

article collection에 저장할 데이터 클래스를 생성해준다.

이때 기존에 laravel의 blade를 사용하면서 인증 관련 테이블이 자동으로 생성되어 이미 `User` 라는 모델이 있는걸 확인 할 수 있다. 

 

sail artisan make:model Article

위의 명령어로 해당 경로에 Article 이라는 모델 파일이 생성된걸 확인할 수 있다.

이때 주의해야 할 것은 테이블 명의 단수형으로 모델을 생성해야 laravel이 인식할수 있다는것 !!

2) insert 하기

그리고 나서 요청값으로부터 body와 user_id를 가져와서 저장해 주는 로직을 작성한다

//4) Eloquent ORM 사용하기
$article = new Article;
$article->body = $input['body'];
$article->user_id = Auth::id();
$article->save();

 

위의 1~3번과 Eloquent ORM을 사용했을때의 차이점은 여러가지가 있지만 일단 date 값이 자동으로 생성된다는 것이다.

 

 

위의 insert 쿼리를 리팩토링 하여 class생성과 query문 작성을 동시에 할 수 있다.

 

3) read 하기

sail tinker 를 통해 shell 에서 조회하고 있었는데 오류가 발생했다.

Article class 를 찾지 못한다는것... 그래서 경로 전체를 입력해 주었다.

> App\Models\Article::find(2);
= App\Models\Article {#5621
    id: 2,
    body: "<EB><91><90><EB><B2><88><EC><A7><B8> <EA><B8><80>~~",
    user_id: 1,
    created_at: "2024-05-02 05:40:39",
    updated_at: "2024-05-02 05:40:39",
  }

Article 클래스를 입력했을때 자동으로 App\Models 경로로부터 import 할수 있으면 편할거같다...

standard class로 조회되던 쿼리빌더 방식과 달리 Eloquent ORM을 사용하면 Article 클래스로 조회되는걸 확인 할 수 있다.

 

4) create 리팩토링 하기 + 에러 발생 🔥

쿼리 빌더를 사용해 create 구문을 리팩토링 한 것처럼 Eloquent ORM으로 데이터를 조회할때 class 주입과 query 문 작성을 한번에 할 수 있다.

> 리팩토링 쿼리문

// 4-2) Eloquent ORM 사용 2번째 : class 생성과 query 문 작성 동시에 진행하기
Article::create([
    'body' => $input['body'],
    'user_id' => Auth::id()
]);

 

이때 `create`에 어떤 모듈을 import 해줄껀지 뜨는데 이부분 관련해서는 강의에서 언급이 없어서 일단 `@method` 어노테이션을 넣는걸로 하였다.

 

> @method

해당 어노테이션을 추가하니 App\Models\Article 의 class 위에 다음과 같은 코드가 추가되었다.

<?php

namespace App\Models;

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

/**
 * @method static create(array $array)
 */
class Article extends Model
{
    use HasFactory;
}

 

그러고 나서 데이서 생성을 확인해 보았는데 에러가 발생했다.

> fillable property  : 대량 할당 오류

 

`fillable property` 가 눈에 들어온다. 구글링을 해보니 Article 클래스에 담을 필드들을 무언가 처리해 주어야 한다는것 같았다.

 답변 : https://stackoverflow.com/questions/53793841/add-title-to-fillable-property-to-allow-mass-assignment-on-app-post

 

Add [title] to fillable property to allow mass assignment on [App\Post]

While inserting data in Mysql I have encountered the following error: "Add [title] to the fillable property to allow mass assignment on [App\Post]." Here is my code: $post = Post::create([ '

stackoverflow.com

 

해당 답변들을 참고하여 App/Models/Atricle 에 한줄을 추가해 주었다.

/**
 * @method static create(array $array)
 */
class Article extends Model
{
    use HasFactory;
    protected $fillable = ['body','user_id'];
}

 

그랬더니 정상적으로 데이터가 insert 된걸 확인할 수 있었다!

 

--------------------------------------------------------

[에러해결1] fillable porptery : 대량 할당 취약점

해당 개념에 대해서는 laravel 공식문서에도 설명되어 있다.

https://laravel.com/docs/11.x/eloquent#mass-assignment

 

Laravel - The PHP Framework For Web Artisans

Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things.

laravel.com

 

요약하자면 의도치 않은 필드 수정을 막기 위한 조치라고 할수 있는데, 우리가 의도한 필드의 수정을 허용하기 위해서 Atricle 모델에 별도의 처리가 필요하다.

1) fillable : white list

해당 설정으로 사용을 허용하는 필드를 정의할 수 있다. 위 해결법에서 사용한 방법이다

protected $fillable = ['body','user_id'];

 

2) guarded : black list

해당 설정으로 선언된 필드 외의 모든 필드를 허용하는 방법이다.

protected $guarded = ['id'];

 

둘다 작성해줄 필요는 없고 둘중 하나만 설정해 주면된다.

반응형

+ Recent posts