2019-01-15
최근 laravel을 공부 하면서, 이것 저것 기록해 놓으려고 한다.
해당 글은 
Laravel 5.7
을 기준으로 쓰여졌다 5.7 한글 메뉴얼 https://laravel.kr/docs/5.7 시작하기 - composer가 설치되어 있어야 한다(링크 https://getcomposer.org/ ) - window 환경에서는 git bash를 가지고 하면 cmd창보다는 편하게 사용 가능하다 - Laravel 인스톨러가 없다면,
composer create-project laravel/laravel 프로젝트명 --prefer-dist
- Laravel 인스톨러가 있다면,
laravel new 프로젝트명
- 이미 만들어진 디렉토리에 프로젝트 생성시, 해당 디렉토리에 들어가서 프로젝트명을 제외하고
laravel new
- 특정 버전으로 설치하고 싶다면
composer create-project laravel/laravel="6.*"
식으로 하면 된다. 다만 laravel만 설치된 것이므로 composer install을 해줘야 한다.
b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel $ laravel new test_project1 Crafting application... . . .
composer를 통한 패키지 재설치 - 만들어진 laravel 프로젝트를 보면, .gitignore파일에 vendor디렉토리는 제외 되어 있다 - 보통 다른곳에 git clone을 했을때,
composer install
을 통해서 vendor디렉토리의 패키지를 재설치 하기 때문이다 - 참고로 php.ini파일에 OpenSSL, PDO, MBstring, Tokenizer모듈들이 extension 되어 있지 않으면 오류가 뜬다 - .env파일도 보통 .gitignore파일에 포함되어 있기 때문에, 따로 작성해야 한다.(보통 .env.example파일을 변경해서 활용) - 패키지 업데이트는
composer update
로 가능하다
b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel $ git clone http://b1ix.net:6000/test_project1 Cloning into 'test_project1'... remote: Counting objects: 126, done remote: Finding sources: 100% (126/126) remote: Getting sizes: 100% (113/113) remote: Total 126 (delta 12), reused 126 (delta 12) Receiving objects: 100% (126/126), 249.97 KiB | 10.00 MiB/s, done. Resolving deltas: 100% (12/12), done. b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel $ composer install Composer could not find a composer.json file in C:\D\laravel To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel $ cd test_project1/ b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel/test_project1 (master) $ composer install Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Package operations: 86 installs, 0 updates, 0 removals - Installing doctrine/inflector (v1.3.0): Loading from cache - Installing doctrine/lexer (v1.0.1): Loading from cache . . .
- laravel 프로젝트 디렉토리 안에서 composer install을 하지 않으면, composer.json파일을 찾을수 없다고 뜬다 - 그래서 해당 디렉토리로 들어가서 다시 하는 모습이다. 아티즌 CLI(Artisan CLI) - 아티즌(Artisan)은 라라벨에 포함된 커맨드라인 인터페이스(CLI)의 이름 - 참고 : https://laravel.kr/docs/5.7/artisan Artisan 명령어 -
php artisan list
명령어 모음 보기 -
php artisan serve
자체 내장 서버 동작 -
php artisan serve --port 8001
port옵션이 없으면 기본포트는 8000 -
php artisan serve --help
각종 옵션 출력 -
php artisan down
정검모드로 전환(503페이지가 뜨게 된다:"점검중"페이지로 ) -
php artisan up
서비스 모드로 전환(정상 작동) .env 파일 - .env파일에 포함된 내용은
$_ENV
로 슈퍼전역변수로 자동 로드 된다 - 파일 내용을 직접 바꿨을때는, 서버를 리부트 해야 제대로 적용된다 -
APP_DEBUG=false
true시에는 디버그 모드로, false시에는 500에러페이지 출력 - DB접속 설정, APP_KEY 설정 등의 중요 설정이 포함되어 있다 어플리케이션 키 생성 - composer를 통해서 프로젝트 생성시에는 자동생성 - 없을 경우에는 명령어로 실행
php artisan key:generate
b1ix@LAPTOP-LAVVESZ MINGW64 /laravel/test_project1 $ php artisan key:generate Application key set successfully.
config 디렉토리 - 각종 config 파일이 존재
$value = config('app.timezone');
//config()헬퍼 함수를 통해서 config/app.php의 timezone값을 참조하는 모습
- 사용자 지정 config파일을 생성시에는, config디렉토리에 임의의 파일을 생성하고 config('파일명.키값')함수로 사용가능 - config/menu.php 파일 생성
return [
	'menu1' => 'menu1 text'
];
- 해당 옵션 사용시 config('menu.menu1') 식으로 사용하면 "menu1 text"가 반환된다 timezone과 locale설정 - config/app.php 페이지에서 설정 가능하다 - local의 경우 한국으로 바꾸기 위해서 ko로 설정 했다면, resources/lang 위치에 해당 파일이 있어야 한다 - lang-ko 링크 https://github.com/caouecs/Laravel-lang/tree/master/src/ko
'timezone' => 'Asia/Seoul',
'locale' => 'ko'
지역화 - resources/lang/{locale} 위치에 파일을 만들고 사용 - 예를 들어, 위의 설정에서 local을 ko로 해놓고, resources/lang/ko/lang1.php 파일을 생성 후 아래와 같이 작성
return [
 'test_text' => '테스트 문자1',
 '테스트문자' => '테스트 문자2',
];
-
__
헬퍼함수로 만들어 놓은 값들을 사용 가능 - __('파일명.키값') 형태로 사용가능하며, 해당 값이 없을경우엔 그대로 표시됨 - 블레이드 템플릿 안에서는
{{ }}
혹은
@lang
지시어로 사용 가능
echo __('lang1.test_text')."<br>";
echo __('lang1.테스트문자')."<br>";
echo __('lang1.test_text3');
테스트 문자1 테스트문자2 lang1.test_text3
blade 문법 -
@forelse
@if와 @foreach의 결합 뷰로 넘어온 변수에 값이 있고 사용 가능하면 @forelse를 타고, 그렇지 않으면 @empty를 탄다
@forelse($items as $key=>$val)
  The item is {{ $key }}, {{$val}}
@empty
  There is no item !
@endforelse
-
@include
ex) @include('footer') : footer.blade.php 파일을 포함 -
@extends
페이지 상속, ex) main/layout1.blade.php 파일을 상속 받을 경우: @extends('main/layout1') -
@section @yield
@section으로 정의하고 @yield로 가져와서 사용
@section('section1')
section1 stop<br>
@stop
@section('section2')
section2 show<br>
@show

@yield('section1')
@yield('section2')
section2 show section1 stop section2 show
- blade의
{{ }}
구문은 XSS공격 방지를 위해서 htmlspecialchars()가 실행되고 출력된다 - htmlspecialchars()함수를 실행시키지 않은채로 출력하려면
{! !}
구문을 사용하면 된다 css, js 파일 강제 refresh -
asset()
헬퍼 함수는 자동으로 url을 완성시켜준다 - 자주 바뀌어서 강제로 refresh 되어야 하는 파일은 아래처럼 하면 된다
<script src="{{ asset('js/app.js?v='.time()) }}" defer></script> 
- 해당 페이지를 소스보기 하면 아래처럼 표시된다
<script src="http://localhost:8000/js/app.js?v=1549615332" defer></script>
모든 뷰파일에서 데이터 공유 -
app\Providers\AppServiceProvider.php
View::share
를 이용하여 값을 공유 할 수 있다.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        View::share('aaa', 'abcdeade');
    }
}
- 위와 같이 작성시, 임의의 view파일에서 {{$aaa}} 로 사용 가능하다 의존성 주입 - 라라벨의 핵심 기능중 하나이다 - 참고링크 https://laravel.kr/docs/5.7/container#시작하기
namespace App\Http\Controllers;

 use App\User;
 use App\Repositories\UserRepository;
 use App\Http\Controllers\Controller;

 class UserController extends Controller
 {
	protected $users;

	// 타입 힌팅(Type Hinting)으로 의존성 부여
	public function __construct(UserRepository $users)
	{
		$this->users = $users;
	}

	public function show($id)
	{
		//UserRepository의 함수를 사용 가능해짐
		$user = $this->users->find($id);

		return view('user.profile', ['user' => $user]);
	}
 }
- __construct() 함수에 여러개의 인수를 등록하는것도 가능하다 파사드(Facade) - 서비스 컨테이너에서 사용 가능한 클래스들에 대한 정적(static) 인터페이스를 제공 한다 - 라라벨의 모든 파사드는
Illuminate\Support\Facades
네임스페이스 안에 정의되어 있다
use Illuminate\Support\Facades\Cache;

Route::get('/cache', function () {
	return Cache::get('key');
});
- 파사드(Facade)와 헬퍼(helper)함수는 동작이 겹치는 것들이 있다.
//아래 두 구분은 동일한 동작을 한다
use Illuminate\Support\Facades\View;
...
return View::make('profile');

return view('profile');
confit/database.php 설정 - strict모드(컬럼유효성검사)를 켜고 끄는 설정이 포함되어 있다 - 참조 http://b1ix.net/335
 'mysql' => [
		'strict' => true,
],
DB파사드 - 쿼리빌더 - 데이터베이스를 만들고 운영하는데 도움을 주는 다양한 쿼리 인터페이스를 제공한다 - 링크 https://laravel.kr/docs/5.7/queries php artisan tinker DB 사용 예제 - 아래 접속은 .env파일에 db설정이 되어 있어야 사용 된다 - 아래 예제는 DB파사드로 소스에서도 그대로 사용 가능하다
$ php artisan tinker Psy Shell v0.9.9 (PHP 7.2.12 — cli) by Justin Hileman >>> DB::select('select * from testbl1') => [] >>> DB::select('select * from users') Illuminate/Database/QueryException with message 'SQLSTATE[42S02]: Base table or view not fo und: 1146 Table 'test.users' doesn't exist (SQL: select * from users)' >>> >>> DB::insert('insert testbl1 set name="aa", age="12", r_date=now()') => true >>> DB::update("update testbl1 set name=?", ['bbbb']) => 1 >>> DB::select("select * from testbl1") => [ {#2915 +"idx": 1, +"name": "bbbb", +"age": "12", +"r_date": "2019-01-15 18:39:10", }, ] >>> DB::table('testbl1')->whereIdx(1)->select('name')->get(); => Illuminate\Support\Collection {#2921 all: [ {#2927 +"name": "bbbb", }, ], }
모델(MODEL) -
php artisan make:model 모델명
으로 생성 -
-m
혹은
--migration
옵션을 넣어주면, 자동으로 migration까지 생성해 준다 - laravel엔 Models 디렉토리가 없어서 만들때 Models/모델명식으로 만들어야 관리에 좋다 - 참조 https://laravel.kr/docs/5.7/structure#모델디렉토리는어디에? - model을 지우는 명령어는 따로 존재하지 않는다, 생성된 model 파일을 지우면 된다.(-m 사용시 마이그레이션 파일도)
$ php artisan make:model Models/Member -m Model created successfully. Created Migration: 2019_02_11_204345_create_members_table
- 위의 예제 참조, Member라는 이름의 모델 생성시 마이그레이션 파일명에 테이블(table)명이 members로 이름지어짐 - 생성한 모델에 $table변수로 따로 DB테이블명을 입력해주지 않으면, 자동으로 "모델명s"식으로 DB테이블을 인식한다 - 테이블은 기본적으로 updated_at, created_at 필드가 포함되어 생성, 사용하지 않으려면 아래처럼 하면 된다
class Member extends Model{
	public $timestamps = false;
}
- 모델은 쿼리를 조회 할 수 있는 쿼리 빌더로 사용 가능하다
//컬럼 각각을 이름으로 출력하기
$members = App\Member::all();
foreach ($members as $val) {
    echo $val->name;
}

//값들만 가져오기
$members = App\Member::all()->toArray();
print_r($members);

//기타 사용법
$member2 = App\Member::where('active', 1)->orderBy('name', 'desc')->take(10)->get();
- 그밖의 모델의 자세한 사항들 링크 https://laravel.kr/docs/5.7/eloquent 컨트롤러(Controller)에서의 모델(Model) 사용 - 모델을 컨트롤러에서 사용하려면, use로 명시해주고 새로운 객체를 생성하거나, 정적(static) 메소드로 사용하면 된다
namespace App\Http\MemberControllers;

use App\Models\Member;
use App\Http\Controllers\Controller;

class MemberController extends Controller
{
	public function search($id)
	{
		$member = new Member;
		return $member->where('id', $id);
	}
}
php artisan migrate 예제 - 기본적으로 DB는 미리 만들어져 있어야 마이그레이션이 가능하다 -
php artisan make:migration '테이블명'
database/migrations 디렉토리에 '생성시간_테이블명' 형식의 파일 생성 - 생성된 파일의 up()에는 마이그레이션 실행동작, down()에는 롤백 동작을 지정 가능 -
php artisan migrate
마이그레이션 실행 -
php artisan migrate:rollback
롤백 - 마지막 마이그레이션 시점으로 돌림 -
php artisan migrate:refresh
다시 실행 -
php artisan migrate:reset
제거- 마이그레이션을 처음시점으로 되돌림 - 위 명령어로 테이블이 생성되면 migrations테이블(마이그레이션 테이블 목록)도 자동 생성됨
b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel/test_project1 $ php artisan make:migration create_posts_table Created Migration: 2019_01_16_072425_create_posts_table b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel/test_project1 $ php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table Migrating: 2019_01_16_072425_create_posts_table Migrated: 2019_01_16_072425_create_posts_table b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel/test_project1 $ php artisan migrate Migrating: 2019_01_16_080309_add_name_to_posts_table Migrated: 2019_01_16_080309_add_name_to_posts_table b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel/test_project1 $ php artisan migrate:rollback --step 1 Rolling back: 2019_01_16_080309_add_name_to_posts_table Rolled back: 2019_01_16_080309_add_name_to_posts_table
컬럼수정하기 - 참고링크: https://laravel.kr/docs/5.8/migrations#컬럼수정하기 - 순서 1.
composer require doctrine/dbal
doctrine/dbal의존성을 추가
b1ix@LAPTOP-LTOAQ5FF MINGW64 /c/D/git/galaxyManagement_laravel_was (master) $ composer require doctrine/dbal Using version ^2.9 for doctrine/dbal . . . Package manifest generated successfully.
2. migration 파일 생성
b1ix@LAPTOP-LTOAQ5FF MINGW64 /c/D/laravel/test_project1 (master) $ php artisan make:migration modify_settings_table Created Migration: 2019_06_25_112456_modify_settings_table
3. change()함수를 사용하여 수정할 컬럼 정의(예제에서는 컬럼 크기를 2000으로 확장)
class ModifySettingsTable extends Migration
{
	public function up()
	{
		Schema::table('settings', function (Blueprint $table) {
			$table->string('explain', 2000)->change();
		});
	}
	...
4. migrate 명령어 실행
b1ix@LAPTOP-LTOAQ5FF MINGW64 /c/D/laravel/test_project1 (master) $ php artisan migrate Migrating: 2019_06_25_112456_modify_settings_table Migrated: 2019_06_25_112456_modify_settings_table
Seeder -
php artisan make:seeder seeder클래스명
명령어로 seeder 파일 생성 - 클래스 작성후
composer dump-autoload
명령어로 오로로도 재설정 -
php artisan db:seed --class=seeder클래스명
명령어로 seeder 실행 - --class 옵션이 없을시에는 기본적으로 만들어져 있는 DatabaseSeeder클래스가 실행됨 -
php artisan migrate:refresh --seed
명령어로 seeder를 지우고 새로 작성해줌 인증 - laravel에 내장된 인증을 사용시
php artisan make:auth
php artisan migrate
명령어를 실행 - 참고링크 https://laravel.kr/docs/5.7/authentication -
Auth::routes();
의 구현 위치
vendor\laravel\framework\src\Illuminate\Routing\Router.php
- 기본 인증의 로그인 유지 시간은 php.ini의 session.gc_maxlifetime설정(기본 1440초)을 따라간다 미리 등록되어 있는 미들웨어 -
app/Http/Kernel.php
파일에 명시되어 있다 - 새로운 미들웨어를 만들었다면 해당 부분에 명시해 놓고 사용 가능하다
protected $routeMiddleware = [
 'auth' => \App\Http\Middleware\Authenticate::class,
 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
 ...
];
//key로 불러와서 사용
$this->middleware('auth');
미들웨어 만들기 -
php artisan make:middleware 미들웨어이름
명령어로 생성시 app/Http/Middleware 디렉토리에 자동 생성된다 - 만들어진 미들웨어 파일의 handle($request, Closure $next) 함수에서 동작 정의 기본적인 라우팅 - 5.2버전까지는
app/Http/routes.php
- 참고: https://laravel.kr/docs/5.2/routing - 5.3버전 부터는 routes디렉토리에서, 보통은
routes/web.php
파일만 사용 - 참고: https://laravel.kr/docs/5.3/routing route 목록 확인 -
php artisan route:list
b1ix@LAPTOP-LAVVESZ MINGW64 /c/D/laravel/test_project1 $ php artisan route:list +--------+----------+----------+------+--------------------------------------------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+----------+------+--------------------------------------------+--------------+ | | GET|HEAD | / | | App\Http\Controllers\IndexController@index | web | | | GET|HEAD | api/user | | Closure | api,auth:api | +--------+----------+----------+------+--------------------------------------------+--------------+
CSRF토큰 예외처리 -
app/Http/Middleware/VerifyCsrfToken.php
에서 예외처리 가능 - 테스트로 만들어 놓은 test_controller와 그 하위 URL들을 CSRF토큰 체크하지 않도록 예외에 추가 해놓을 수 있다
class VerifyCsrfToken extends Middleware
{
	protected $addHttpCookie = true;
	protected $except = [
		'test_controller',
		'test_controller/*'
	];
}
헬퍼(helper) 함수 - laravel에는 미리 등록되어 어느곳에서든 사용 할 수 있는 helper 함수가 다수 존재한다 - 제공되는 helper함수 목록 https://laravel.kr/docs/5.7/helpers - 커스텀으로 helper함수를 등록하려면, 1. 적당한 위치에 파일을 하나 만든다, 필자는 app\helpers\custom_helper1.php 생성 2. composer.json파일에서 autoload 부분에 file키를 추가하고, 해당 file위치 추가
"autoload": { "psr-4": { "App\\": "app/" }, "classmap": [ "database/seeds", "database/factories" ], "files":[ "app/helpers/custom_helper1.php" ] }
3.
composer dump-autoload
명령어를 실행
$ composer dump-autoload Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: beyondcode/lara ..... Package manifest generated successfully. Generated optimized autoload files containing 3748 classes
4. app\helpers\custom_helper1.php 파일에 함수를 추가하면 어디서든 해당 함수를 사용 가능하다 이벤트(Event) & 리스너(Listener) -
app\Providers\EventServiceProvider.php
파일에서 이벤트 리스너를 등록 가능하다 - 예를 들어 인증에서 지원하는 이벤트중에 Login완료 이벤트에 아래와 같이 임의의 Listener를 등록해놓는다.
namespace App\Providers;

use Illuminate\Support\Facades\Event;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
	protected $listen = [
		Registered::class => [
			SendEmailVerificationNotification::class,
		],
		//Login 완료 이벤트
		\Illuminate\Auth\Events\Login::class => [
			//임의의 리스너등록
			\App\Listeners\LoginSucessListener::class,
		],
	];

	public function boot()
	{
		parent::boot();
	}
}
- 위처럼 등록을 한 뒤에
php artisan event:generate
명령어로 Listener를 자동생성 가능하다 - 위 명령어로 app\Listeners\LoginSucessListener.php파일이 생성 되었다.
namespace App\Listeners;

use Illuminate\Auth\Events\Login;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class LoginSucessListener
{
	public function __construct()
	{
		//
	}
	public function handle(Login $event)
	{
		// 로그인 완료 후 이 부분이 실행 된다
	}
}