jins coding sample blog
게시판 만들기 5. 회원가입 본문
회원가입부터 조금 복잡하다.
이미 MVC 모델이나 migrate 에 대해서 자세히 알고 계신분께는 괜찮겠지만, 나는 정말 맨땅에 헤딩한꼴이라 내가 몰랐던 부분들이나 헤맸던 오류들까지 적어볼까한다.
해당 내용은 '라라벨로 배우는 실전 PHP 웹 프로그래밍'+'Laracast 의 강좌들' 과 함께 보면 더 좋을 것 같다!
M(모델)
MVC라는 순서에 맞춰서 M부터 해볼까한다.
모델은 데이터베이스에 관련한 가장 큰 과정으로 생각해주면 좋다.
1. migration (데이터베이스를 만들고, 지우는 것만 함. 입력은 안함)
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateJoinTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
//생성할 테이블 이름
$table->text('name');
$table->string('id')->uniqid();
$table->string('password')->bcrypt();
$table->string('email')->uniqid();
$table->timestamps();
//timestamps는 폼 전송시 자동으로 입력되니, 폼에서는 적지 않는다.
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
해당 과정에서 파일이름과 class 의 이름을 같게 하지 않으면
'SQLSTATE[42S02]: Base table or view not found' 라는 오류 문구를 포함한 웁스창이 뜬다. 그럴 땐 파일이름과 class 이름을 갖게 해주면 된다.
아래 일어났던 오류들에서 정리해서 넣을 것이다.
2. Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Join extends Model
{
public function save(array $request=[])
{
if(parent::save($request))
{
$this->input('name','id','password','email');
//$user->name=$request->input('name');
//$user->id=$request->input('id');
//$user->password=$request->input('password');
//$user->email=$request->input('email');
}
}
protected $table='users'; //입력될 테이블이름 한번더 언급
protected $fillable=['name','id','password','email']; //대량할당 가능하게 한 부분
protected $hidden=[
'password','remember_token',
]; //password 는 혹시몰라서 hidden 으로 한번더 가려줌
private function input(string $string, string $string1, string $string2, string $string3)
{
//꼭 입력해야함. 입력안하면 input 자체가 안먹어서
//Call to undefined method App\Join::input()
//위의 에러 일어남
}
}
해당 코드의 다른 내용들도 중요하지만, 아래 내용을 더 주의깊게 봐줬으면 좋겠다.
public function save(array $request=[])
만약 맨 위에서 언급했던 책과 함께 보고 있다면 아래와 비슷하게 입력했다가 오류가 났을 것이다.
//코드
public function save($request)
//나한테 일어났던 에러
Call to a member function save() on null error
확인해보니, laravel 6 부터는 괄호안에 변수명만 적는 것이 아니라, 배열로 받는 것으로 바뀌었다고 한다.
배열로 받으면 문제없다!
V(뷰)
두번째 순서인 V이다.
<html>
<head>
<title>회원가입 화면</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" charset="utf-8">
</head>
<body>
<form name="login" method="POST" action="{{route('Join.store')}}">
{{ csrf_field() }}
<input type="text" name="name" value="{{old('name')}}" placeholder="name">이름<br>
<span class="text-danger">{{ $errors->first('name') }}</span> //오류 일어난 곳 알려줌
<input type="text" name="id" value="{{old('id')}}" placeholder="id">아이디<br>
<span class="text-danger">{{ $errors->first('id') }}</span>
<input type="password" name="password" placeholder="비밀번호는 최소 4자리">비밀번호<br>
<span class="text-danger">{{ $errors->first('password') }}</span>
<input type="email" name="email" value="{{old('email')}}" placeholder="email">이메일<br>
<span class="text-danger">{{ $errors->first('email') }}</span>
<input type="submit" name="submit">제출하기
<span class="text-danger">{{ $errors->first('submit') }}</span>
</form>
</body>
</html>
폼의 중간중간에 밑의 문장이 들어가 있는데, 오류가 일어난 곳을 알기 위해 일일이 넣은 것이다.
단 first() 괄호안의 이름은 에러를 보고 싶은 input name 으로 적어야한다.
<span class="text-danger">{{ $errors->first('name') }}</span>
그리고! main에 추가 된 부분이 있는데, main.blade.php의 <body></body> 사이에
@include('sweetalert::alert') 를 넣어줬다.
해당 라이브러리는 알림창을 더 이쁘게 표현하고 싶어서 넣은 것이다 (^^ 이쁜거 최고~~~)
설치는 밑의 주소 확인
https://packagist.org/packages/uxweb/sweet-alert
uxweb/sweet-alert - Packagist
README Installation Require the package using Composer. composer require uxweb/sweet-alert If using laravel < 5.5 include the service provider and alias within config/app.php. 'providers' => [ UxWeb\SweetAlert\SweetAlertServiceProvider::class, ]; 'aliases'
packagist.org
C(컨트롤러)
가장 마지막과정인 C이다.
MVC 라는 이름에 맞춰 가장 밑으로 왔지만, 개인적으로는 VCM 으로 진행하는 것을 추천한다.
나같은 경우에는 과정에 맞춰 순서대로 하는걸 좋아하는데 V에서 틀을 잡고, C에서 중간정리를 하고 M에서 만든곳으로 전송한다는 느낌을 가지고 있기 때문이다.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use App\Join;
use Dotenv\Regex\Success;
use RealRashid\SweetAlert\Facades\Alert;
use Illuminate\Support\Facades\DB;
class JoinController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function create()
{
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request)
{
$this->validate($request,[
'name'=>'required',
'id'=>'required|max:20|unique:users',
'password'=>'required|min:4',
'email'=>'required|unique:users',
]);
$user=\App\Join::create([
'name'=>$request->input('name'),
'id'=>$request->input('id'),
'password'=>$request->input('password'),
'email'=>$request->input('email'),
]);
$user->save;
Alert::success('회원가입완료','해당 아이디로 로그인해주세요');
return redirect('/');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
컨트롤러는 java와 비슷한 부분이 많다보니 java의 기초틀을 알고 계신 분이라면 알기 쉬울 것 같다.
public 으로 묶여있는 틀들은 내가 일일이 친게 아니고 리소스 컨트롤러를 사용한 것이다.
라라벨 6.x - API Resources
라라벨 한글 메뉴얼 6.x - API Resources
laravel.kr
위의 resource 컨트롤러를 쓰면 이러한 틀이 있다고 말하고 싶어서 전체 코드를 올렸지만, 앞으로는 각각 잘라서 쓰려고한다.
나는 store 에 저장에 관한 것을 입력했지만 솔직히 web.php 에쓴 Route 에 맞는 행동만 하면 update 에 적어도 상관이 없다. 단, 일반적으로 store 에 쓰기 때문에 쓴것이다.
아직까지는 저장(insert)만 한거라서 store 를 아래에!
public function store(Request $request)
{
$this->validate($request,[
//최소한 입력해야하는 것들, 입력하는 문자의 길이, 중복된 컬럼을 방지 위한 unique 설정
'name'=>'required',
'id'=>'required|max:20|unique:users',
'password'=>'required|min:4',
'email'=>'required|unique:users',
]);
$user=\App\Join::create([
//'join.blade.php의 form name=''에 설정된 이름=>$요청보내기->insert한다('user 테이블의 각 칼럼이름'),
'name'=>$request->input('name'),
'id'=>$request->input('id'),
'password'=>$request->input('password'),
'email'=>$request->input('email'),
]);
$user->save;
//해당 기능하면 Model로 save 요청을 보낸다.
Alert::success('회원가입완료','해당 아이디로 로그인해주세요');
//성공시 위의 문구가 뜬다.
//실패시엔 바로 밑이 실행이 안되고 입력안된다는 알람이 뜨고 그자리에 있는 관계로 설정안함
//실패시는 추후 수정 예정
return redirect('/');
//입력 모두 완료시 메인으로 가고, 바로 위의 alret 가 뜬다.
}
web.php
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('main');
});
Route::get('/join',function(){
return view('join');
});
Route::post('/main','JoinController@store')->name('Join.store');
위의 내용들은 Route 설정을 해준 것으로, 아직까지 Route 가 많이 적히진 않았다.
아래의 내용을 봐보자! 이걸 잘 해결하면 post에 고생하는 일이 없을 것이다!
Route::post('/main','JoinController@store')->name('Join.store');
해당 route는 post 요청을 받으면 /main 으로 간다는 뜻이다.
어자피 '/' 로 설정해도 main 으로 가겠지만, 내가 조금 더 확실하게 알고 싶어서 설정했다.
'JoinController@store' 는 JoinController 의 store 펑션을 사용한다는 것이다.
내가 post 를 누르는 잠깐 사이 store 에 있던 기능들이 실행되고, 그 정보를 model로 넘겨서 저장한다.
name('Join.store') <- 이거 진짜 별 100만개 해줘야한다고 본다.
만약 하지 않으면, form 에서 전송을 누르면 밑의 웁스페이지가 뜬다.
이건 내가 V에서
action="{{route('Join.store')}}
해당 문구를 넣어서 인데, route의 Join.store 라는 걸 사용한다는 거다.
때문에 해당 문구를 한번더 언급해줄 필요가 있는 것이다.
저 post 를 해결하는 방법도 다양하게 있지만, 나는 내가 사용한 방법이 제일 편했다.
실제 적용 화면
이제 다음포스팅 부터는 로그인 화면을 만들어본다:)
정말 마지막으로 오류 정리
발생한 오류 | 상황 | 해결방법 |
SQLSTATE[42S02]: Base table or view not found | migrate 를 했지만, 해당 문구가 뜨고 되지 않았다. |
파일 이름과 class 이름이 같지 않았음 같게 해주면 해결 |
Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR).Call to a member function save() on null. | 폼 전송을 했지만, 되지 않았다. |
라라벨 버전 문제. save() 괄호 안의 내용을 배열로 설정하면 됨. 자세한건 위의 1번 M 참고 |
419 Error 혹은 Route 에서 post 문제가 있다고 뜬다. | 폼 전송을 했지만, 되지 않았다. | wep.php에서 '
->name('Join.store');' 등의 수정을 했다. 자세한 건 위의 2번 V와 3번 C를 참고 |
'웹 응용 > laravel' 카테고리의 다른 글
구현된 기능 정리 (1) | 2020.03.23 |
---|---|
Auth::login() 메소드 (0) | 2020.03.11 |
게시판 만들기 - 4. 메인 화면 (0) | 2020.03.01 |
게시판 만들기 3. 설치할 것 (0) | 2020.03.01 |
게시판 만들기 - 2. 기본 설정 (0) | 2020.03.01 |