페이지

2018년 2월 25일 일요일

CHAPTER 1 머신러닝 시작하기

1.1 머신러닝 소개
"데이터를 이용해서 명시적으로 정의도지 않은 패턴을 컴퓨터로 학습하여 결과를 만들어내는 학문 분야".

데이터, 패턴인식, 컴퓨터를 이용한 계산

1.2 머신러닝을 이해하는 데 필요한 배경지식

1.2.1 수학(선형대수, 미분, 통계, 확률)

1.2.2 프로그래밍

1.3 머신러닝 발전사

1.3.1 머신러닝의 역사와 현재 트렌드

고전적 인공지능 시대
1950년대 유명한 컴퓨터 학자인 앨런 튜링은 인공지능을 판별하는 튜링 데스크를 제안했는데, 이는 기계가 인간과 얼마나 비슷하게 대화하는지를 기준으로 기계의지능을 판별하는 테스트.

신경망 시대
1957년에 퍼셉트론(perceptron)이라는 기초적인 신경망이 개발. 이를 여러 개 묶어 복잡한 신경망을 구성하면서 입력과 출력을 굉장히 유연하게 연결할  수 있었지만, 당시 신경망에는 여러가지 문제점이 있었습니다. 우선 그 시대에는 구할 수 있는 데이터가 굉장히 한정적이라 신경망 성능이 생각보다 신통치 않았고, 기초 이론의 부족으로 한정적인 패턴만 학습이 가능했습니다. 많은 학자가 신경망 구축에 뛰어들었지만, 예상보다 결과가 잘 나오기 않아 침체된 상태가 이어졌습니다. 이 시기를 '인공지능의 겨울'이라 부르곤 합니다.

통계학적 머신러닝 시대
1990년대에 들어 통계학을 전산학과 접목시켜 대규모에서 패턴을 찾는 시도가 기존에 비해 진일보된 성과를 냈습니다. 기존의 방법과 가자으 큰 차이점은 데이터에 훨씬 더 중요한 비중을 두었다는 것입니다. 그 결과 기존의 그 어떤 방법보다 성능이 좋았기 때문에 큰 관심을 받고 산업의 여러 분야에 도입되었습니다. 이 시기에 머신러닝이라는 용어가 등장 했으며, 차후에 딥러닝이 나온 이후 이런  통계학에 중심을 둔 기법들을 통계학적 머신러닝알고 부르게 됩니다.

빅데이터 시대
통계학적 머신러닝은 웹에서 쏟아지는 데이터, 대용량 저장장치, 분산 처리 기술과 결합하여 엄청난 시너지를 만들었습니다. 빅데이터는 용어가 2010년대부터 유행했는데, 빅데이터 시대에는 기존보다 더 큰 데이터를 분석하기 위해 기존보다 휠씬 더 큰 규모의 머신러닝 시스템을 만들게 되고 그 덕택에 성능도 더욱 좋아지게 됩니다.

딥러닝 시대
데이터가 많아지고 연산 능력이 증가하면서(특히 GPU가 발전하면서) 머신러닝 연구자들은 예전 신경망 이론에 다시 한번 눈길을 돌렸습니다. 기존의 신경망 시대보다 훨씬 더 많은 데이터와 새로 개발된 이론을 합치자 단순히 통계학적 머신러닝만 사용하는 모델을 넘어서는 결과를 얻을 수 있게 되었습니다. 기존의 신경망보다 훨씬 더 복잡한, 즉 깊이가 깊은 신경망을 사용하게 되었기 때문에 이를 딥러닝이라고 부르게 됩니다. 딥러닝 시대의 신경망 연구는 60년대의 신경망 연구와는 성황과 성과가 달랐습니다. 오랜 기간 연구가 진행된 통계학적 머신러닝을 기존의 신경망에 접목했고, 데이터가 폭발적으로 증가해서 복잡한 신경망을 학습할 만한 기반도 생겼습니다. 그 덕분에 성능이 이전보다 훨씬 잘 나오게 되었습니다.

현재 트렌드
현재 머신러닝은 대량의 데이터를 바탕으로 하는 딥러닝 기법을 주로 사용합니다. 기존에는 해결하기 힘들었던 음성 인식, 번역, 이미지 인식에서 특히 좋은 성과를 보이고 있습니다. 이러한 성과는 다음과 같은 최근의 새로운 연구 결과에 의해 가능했습니다.

- 셩격이 다른 데이터를 연관시켜서 데이터를 더 효율적으로 사용하는 딥러닝 구조의 개발. 예) 비디오에 있는 자막과 이미지를 동시에 학습시키거나 영어, 프랑스어, 스페인어를 동시에 학습시키기
- 통계학적 머신러닝의 기법을 조합해 데이터를 더 효율적으로 사용하는 딥러닝(원샷, 제로샷 러닝) 기술의 발전
- 머신러닝, 특히 딥러닝을 거대 규모로 빠르게 연산할 수 있는 시스템의 발전(하드웨어 소프트웨어 모두)
- 딥러닝의 더 효울적인 학습을 위한 기술(드롭아웃, 비동기 SGD등)의 발전
- 데이터에 대한 더 큰 관심으로 인해 양적, 질적으로 크게 성장한 데이터 수집 기술의 발전

1.3.2 머신러닝의 3가지 관점
통창력, 데이터 적합성, 이론적 엄정성

통찰력, 통찰력 있는 모델      데이터에 대한 지식      데이터의 대한 믿음
데이터 적합성, 데이터 자체에 얼마나 가까운 모델을 만들 수 있는지     많은 데이터  데이터에 잘 맞는 모델
이론적 엄정성. 기법을 분석하기 쉬운지, 계산이 쉽게 가능한지   증명이 가능한 수학이론   잘 정의되고 보장된 성능

통찰력을 중시하는 경우는 결국 데이터가 어떤 패턴을 가지고 있다고 믿으며, 그 패턴에 대한 지식을 혹보하는 것을 중요시한다는 뜻입니다. 이처럼 데이터에 대한 믿음(prior라고 부릅니다)을 중시하는 대표적인 기법으로 베이지언 기법이 있습니다. 베이지언 기법은 현재의 가정에서 부족한 부분을 보완할 수 있는 데이터를 특히 중요하게 생각합니다.

데이터 적합성을 중시하는 기법들은 관측된 데이터를 가장 중요하게 생각합니다. 데이터에 대한 지식이 희박한 경우 또는 데이터가 아주 많아서 기존 지식 없이도 머신러닝 기법이 잘 동작하는 상항을 가정합니다. 이 경우는 노이즈에 영향을 많이 받으므로 보다 많은 데이터를 이용하여 노이즈의 영향을 줄이는 기술이 많이 쓰입니다 대표적으로 딥러닝과 랜덤 포레스트가 여기에 해당합니다. 둘 다 기업에서 많이 쓰는데, 모델이 수학적으로 간단해서 실제 구현하기 쉽고 스케일을 키우기도 좋기 때문입니다. 통계학에서 말하는 베이지언과 빈도론자(프리쿼티스트)중에 빈도론자에 대앙하는 부분입니다.

이론적 엄정성은 머신러닝 알고리즘 이론에 대한 분석에 집중합니다. 머신러인 알고리즘이 어느 정도의 성능을 보장하고, 거대한 스케일의 데이터를 얼마나 쉽게 다르며, 잘못될 확률이 얼마나 적은지에 대한 해답을 구하는 부분입니다. 많은 머신러닝 이론이 성능 보장을 위해 개발되었습니다. 이에 해당하는 대표적인 기법으로 스팩트럴 러닝, 서포트 벡터 머신(SVM), 볼록 최적화가 있습니다. 사실 이 관점은 너무 이론적인 데 치중하므로 쓸모없는 게 아닌가 하는 의문을 가질 수도 있습니ㅏㄷ 하지만 수학적으로 확실하게 증명되는 성능에 대한 보장은 의학, 로봇, 무인자동차, 우주여행등의 분야에서 매우 중요합니다.

최근에는 이용 가능한 데이터가 증가함에 따라 데이터 적합성에 중점을 둔 기법이 주로 개발됩니다. 하지만 한 가지 관점만 중요하게 여기는 머신러닝 기법은 없다고 할 수 있습니다. 앞서 언급한 통찰력, 이론적 엄정성, 데이터 적합성에 대한 중요도를 다르게 두되 모두 고려하고 있다고 해야 할 것 입니다. 이 3가지 관점은 머신러닝 기법이 잘 동작하는데 필요한 핵심 연구 방향입니다. 앞으로 머신러닝 기법을 분류해서 살펴볼 때 이 3가지 관점을 생각해보는 것이 이해와 분석에 도움이 될 것입니다.

1.4 머신러닝의 분류
머신러닝 기법은 풀고자 하는 목표에 따라 크게 지도학습, 비지도학습, 강화학습으로 분류할 수 있으며, 풀어내는 기법에 따라 통계와 딥러닝으로 분류할 수 있습니다.

1.4.1 지도학습, 비지도학습, 강화학습

머신러닝은 풀고자 하는 목표에 따라 3가지로 나누어볼 수 있습니다.

지도학습은 주어진 데이터와 레이블(정답)을 이용해서 미지의 상태나 값을 예측하는 학습 방법입니다. 대부분의 머신러닝 문제는 지도학습에 해당합니다. 예를 들어 '예전의 주식 시장 변화를 보고 내일의 주식 시장 변화 예측하기', '문서에 사용된 단얼르 보고 해당 문서의 카테고리 분류하기', '사용자가 구매한 상품을 토대로 다음에 구입할 상품 예측하기' 등이 여기에 속합니다.

비지도학습은 데이터와 그에 주어진 레이블 간의 연관 관계를 구하는 것이 아니라 데이터 자체에서 유용한 패턴을 찾아내는 학습 방법입니다. 예를 들어 비슷한 데이터끼리 묶는 군집화, 데이터에서 이상한 점을 찾아내는 이상 검출, 데이터 분포 추측이 있습니다. 지도학습과 가장 다른 점은 데이터가 주어졌을 때 특정 값을 계산하는 함수를 만드는 대신 데이터의 성질을 직접적으로 추측한다는 것입니다.

강화학습은 기계(에이전트)가 환경과의 상호작용(선택과 피드백의 반복)을 통해 장기적으로 얻는 이득을 최대화하도옥 하는 학습방법입니다. 지도학습과는 달리, 강화학습의 경우에는 입력값-출력값(레이블)의 쌍이 명시적으로 정해지지 않습니다. 예를 들어 바둑 프로그램이 바둑을 둔다고 했을 때 현재 판에서 다음 수를 선택하는 것을 학습하는 과정을 지도학습이라고 볼수 있습니다. 그런데 다음 수만을 고려하는게 아니라 게임 승패까지의 전체 수를 고려하여 게임에서 이길 경우 점수를 받고 그렇지 않으면 점수를 받지 못하도록 하여 일련의 이기는 수를 학습하는 과정은 강화학습니다.

강화학습에 대한 다른 예로 화성 탐사 로봇이 경로를 탐색하는 과정을 들 수 있습니다. 지구에서는 화성의 환경에 대한 데이터를 얻을 수 없으므로, 로봇은 실제로 환경이 어떤지에 대한 정보가 거의 없습니다. 따라서 어디로 갈지를 판단하고자 할 때, '현재 가진 정보를 이용해 다음 해동(action) 정하기'(이를 이용(exploitation이라고 합니다)와 '새로운 정볼르 얻기 위해 가보지 않은 곳 가기'(이를 탐색(exploration이라고 합니다) 중에서 하나를 선택해야 겠지요. 강화학습은 각각의 행동에 대한 피드백을 받아서 다음 행동을 정하는 알고리즘을 학습해나갑니다.

1.4.2 지도학습의 세부 분류
지도학습은 세부적으로 어떤 것을 예측하는냐에 따라 다시 희귀, 분류, 랭킹으로 구분할 수 있습니다.

1.4.2.1. 희귀와 분류
지도학습의 경우 데이터를 통해 학습하는 레이블이 어떤 성질을 지니는지에 따라서 크게 희귀(regression)와 분류(classification)로 구분합니다.

희귀의 경우에는 숫자값을 예측합니다. 대개 연속된 숫자(예를 들면 실수)를 얘측하는데, 예를 들어 기존 온도 추이를 보고 내일 온도를 예측하는 일을 들 수 있습니다.

분류는 입력 데이터들을 주어진 항목들로 나누는 방법입니다. 희귀와는 다르게 항목'1'과 항목'2'는 서로 다른 수치값이 아니라 서로 다른 항목임을 나타냅니다. 예를 들어 어떤 문서가 도서관 어떤 분류에 해당하는지 고르는 경우를 들 수 있습니다.

희귀와 분류는 서로 다른 것처럼 보일 수도 있지만, 희귀를 통해 손싑게 분류를 구현하거나 분류를 통해 희귀를 구현할 수있을 만큼 유사합니다. 예를 들어 어제의 온도와 구름의 양으로 내일의 날씨가 좋을지 안 좋을지 예측하는 분류시스템을 만든다고 했을 때, 날씨가 좋을 경우를 1, 나쁠 경우를 0으로 두어 희귀를 이용하여 날씨가 좋을 확률을 0부터 1 사이의 값으로 구하고, 이 값이 0.8이상이면 좋음, 아니면 나쁨으로 분류할 수 있습니다. 반대로 데이터를 받았을 때 먼저 분류를 구현한 다음, 그 분류에 따라서 연속적인 숫자값을 예측하는 방법을 생각해 볼 수 있습니다. 옐르 들어 사용자 그룹을 '행복한 사용자', '보통 사용자', '불행한 사용자'로 일차 분류한 다음에 '사용자 기분'이라는 연속적인 숫자값을 각각의 그룹에 (+0.1, 0, -1과 같은 식으로)부여하면 분류를 이용해서 휘귀한 것이 됩니다.

이렇게 각각 상호 전환이 가능하지만 수학적으로 더 간단하게 정의되는 '회귀'가 머신러닝의 더 기본적인 도구로 쓰입니다.

1.4.2.2 추천 시스템과 랭킹학습
추천 시스템은 상품에 대한 사용자 선호도(별점, 구매 여부 등)를 예측하는 시스템입니다. 상품과 사용자 데이터를 이용하여 값 혹은 레이블을 예측하는 것이므로 회귀의 일종으로도 볼 수 있습니다. 하지만 그 기법과 세팅이 특이해서 따로 분류하여 설명하겠습니다. 예를 들어 온라인 동호회에서 영화를 추천한다고 가정합시다. 다양한 추천 방법이 있겠지만, 각 영화에 대한 평점 데이터를 이용하여 아직 평점이 없는 영화 점수를 예측하고 그중 점수가 가장 높은 영화를 추천하는 방식을 취할 수 있습니다. 회귀와 다른점은 입력과 출력이 아니라 관객과 영화, 관객과 점수 등 다양한 관계를 고려한다는 것 입니다.

랭킹학습(learnning to rank)은 희귀에서처럼 각 입력 데이터의 출력값을 예측하는 것이 아니라 데이터의 순휘를 예측합니다. 예플 들어 영화 평점을 가지고 특정 관객이 각 영화에 대해 몇 점을 줄지 예측하는 것은 회귀입니다. 반면 좋아할 만한 영화 10편을 추천한다면 랭킹학습에 해당 합니다.

1.4.3 비지도학습의 세부 분류
비지도학습은 지도학습과는 달리 데이터를 직접 모델링하는 기법입니다. 대표적으로 군집화와 토픽 모델링, 밀도 추청, 차원 축소 등의 기법이 있습니다.

1.4..3.1 군집화와 토픽 모델링
군집화(클러스터링)는 비지도학습의 분류 중 하나로 비슷한 데이터들을 묶어서 큰 단위로 만드는 기법입니다. 즉, 비슷한 데이터들을 묶어서 몇 개의 그불을 만들어 데이터 패턴을 파악합니다. 옐르 들어 신문 기사를 수집하여 군집화를 적용해보면 비슷한 내용의 기사가 스포츠 클러스터 혹은 곙제 클러스터 등으로 묶이게 됩니다.

토픽 모델링은 군집화와 매유 유사하지만 주로 텍스트 데이터에 대해 사용됩니다. 토픽 모델링은 보통 한 문서가 토픽에 따라 만들어지고 그에 따라 단어가 생성되어 문서가 쓰여진다는 가정에 접근합니다. 군집화는 더 일반적인 데이터에 해당되기 때문에 가정의 성격이 크게 다릅니다. 또한 많은 군집화 기법이 문서 하나를 클러스터 하나로 분류하지만, 토픽 모델링은 일반적으로 관련 정보를 확률로 표현합니다(예를 들면 0.5는 스포츠, 0.4는 연예, 0.1은 경졔).

1.4.3.2 밀도 추정
밀도 추정은 관측한 데이터를 생성한 원래의 분포를 추측하는 방법입니다. 예를 들어 각국의 학생들의 키와 몸무게를 모아놓은 통계 자료에서 키와 몸무게의 관계를 분석한다고 합시다. 단순히 각각의 경우에 해당하는 뎅터 수를 세는 방법도 있지만, 여러가지 다른 기법으로 더 정확한 분폴ㄹ 얻을 수도 있습니다. 커널 밀도 추정과 가우스 혼합모델이 대표적인 기법입니다.

1.4.3.3 차원 축소
차원 축소는 말 그대로 '데이터의 차원을 낮추는' 기법으로, 디멘셔널리티 리덕션이라고 합니다. 보통은 데이터가 복잡하고 높은 차원을 가져서 시각화하기 어려울 때 2차원이나 3차원으로 표현하기 위해 사용합니다. 여러 가지 기법이 있지만, 일반적으로 주요 패턴을 찾아서 해당 패턴을 낮은 차원에서 보존하는 방식으로 이루어집니다. 이 기법은 독립적으로 쓰이지만, 데이터에 적합한 머신러닝 기법을 찾는 데이터 분석 초기 단계에 적용하기도 합니다. 대표적인 기법으로 주성분 분석(PCA) 및 특잇값 분해가 있습니다. 자세한 내용은 6.4.3절 '잠재성 요인 모델'과 7.3.4 절 '주성분 분석'에서 공부하겠습니다.

1.4.4 딥러닝
딥러닝은 신경망을 층층이 쌓아서 문제를 해결하는 기법의 총칭입니다. 딥러닝은 머신러닝이 풀고자 하는 목표에 따라 분류한 개면이 아니며, 사용하는 기법이 특정 형태를 가지는 것을 말합니다. 즉, 앞서 설명한 지도학습이나 비지도학습을 딥러닝을 이용해서 풀 수도 있고 통계학적인 방법을 이용해서 풀 수도 있습니다.

이는 데이터양에 의존하는 기법으로, 다른 머신러닝 기법보다 문제에 대한 가정이 적은 대신 다양한 패턴과 경우에 유연하게 대응하는 구조를 만들어 많은 데이터를 이용하여 학습시키는 것으로 모델의 성능을 향상시킵니다. 즉, 데이터에서 잘 동작하는 방법입니다.

최근에는 공공기관과 연구 기관에서 데이터를 공개하는 추세이고 이미 공개된 데이터가 많아 그러한 데이터를 잘 활용하면 다른 기법보다 딥러닝의 성능이 우수한 경우가 많습니다. 하지만 데이터가 많더라도 경우의 수가 너무 많거나 패턴이 너무 복잡하면 제대로 동작하기 어려울 수 있습니다. 이를 위해 많은 연구가 이루어지고 있으며, 딥러닝을 다른 통계적 머신러닝 기법과 함께 적용하는 방법도 개발 중 입니다. 더 자세한 이론은 2장에서, 예제는 7장에서 확인하기 바랍니다.



2018년 2월 13일 화요일

CHAPTER5 Frontend Components

Laravel is primarily a PHP framework, but it also has a series of components focused on generating frontend code. Some of thesse, like pagination and message bags, are PHP helpers that target the frontend, but Laravel also provides g Gulp-based build system called Elixir and some conventions around non-PHP assets.

Since Elixir is at the core of the non-PHP frontend components, let's start there.

Elixir
Elixir (not to be confused with the funcgtional programming language) is a build tool that provides a simple user interface and a series of conventions on top of Gulp. Elixir's core feature is simplifying the most common Gulp tasks by means of a cleaner API and a series of naming and application structure conventions.

A Quick Introduction to Gulp
Gulp is a JavaScript tool designed for compiling static assets and coordinating other steps of your build process.

Gulp is similar to Grunt, Rake, or make-it allows you to define anaction (called a "task" in Gulp) or series of actions to take every time you build your application. This will commonly include running a CSS preprocessor like Sass or LESS, copying files, concatenating and minifying JavaScript, and much more.

Gulp, and therefire Elixir, is based on the idea of streams. Most tasks will begin by loading some files into the stream buffer, and then the task will apply transformationis to the content-preprocess it, minify it, and then maybe save the content to a new file.

At ists core, Elixir is just a tool in your Gulp toolbox.l there isn't even such a thing as an Elixir file; you'll define your Elixir tasks in your gulpfile.js. But they look a log different from vanilla Gulp tasks, and you;ll have to do a log less work to get them running out of the box.

Let's look at a common example: runnig Sass to preprocess your CSS styles. In a normal Gulp environment, that might look a little bit like Example 5-1.

Example 5-1. Compiling a Sass file in Gulp

var gulp = require('gulp'),
     sass = require('gulp-ruby-sass'),
     autoprefixer = require('gulp-autoprefixer'),
     rename = require('gulp-rename'),
     notify = require('gulp-notify'),
     livereload = require('gulp-livereload'),
     lr = require('tiny-lr'(,
     server = lr();

gulp.task('sass', function() {
   return gulp.src('resources/asserts/sass/app.scss')
        .pip(sass({ 
             style: 'compressed',
             sourcemap: true
         }))
        .pipe(autoprefixer('last 2 version', 'ie 9', 'ios 6'))
        .pipe(gulp.dest('public/css'))
        .pipe(rename({suffix: '.min'}))
        .pipe(livereload(server))
        .pipe(notify({
             title: "Karani",
             message: "Styles task complete."
          }));
 });

Now, I've seen worse. It reads well, and it's clear what's going on. But there's a lot happening that you'll just pull into every site you ever mark. It can get confusing and repertitive.

Let's try that same task in Elixir (Exmaple 5-2).

Example 5-2. Compiling a Sass file in Elilxir

var elixir = require('laravel-elixir');

elixir(function (mix){
   mix.sass('app.scss');
});

Tha's it. That covers all the basics- preprocessing, notificationi, folder structure, autoprefixing, and much more.

ES6 in Elixir 6
Elixir 6, which coame out with Laravel 5.3, changed a lot fothe syntax to use ES6, the llatest version of JavaScript. Here's what Example 5-2 looks like in Elixir 6:

const elixir = require('laravel-elixir');

elixir(mix =>{
     mix.sass('app.scss')
 });
Don't worry; this does exactly the same thing.

Elixir Folder Structure
Much of Elixir's simplicity comes from the assumed directory structure. Why make the decision fresh in every new application about where the source and compiled assert live? Just stick with Elixir's convention, and you won't have to think about it ever again.

Every new Laravel app comes with a resources folder with an assets subfolder, which is where Elixir will expect your frontend assets to live. You Sass will live in reosurces/assets/sass, or your LESS in resources/assets/less, and your JavaScript will live in resources/assets/js. There will export to public/css and public/js.

But if you're interested in changing the structure, you can always change the source and public paths by changing the appropriate properties (assetsPath and public Path) on the elixir .config object.

Running Elixir

Since Elixir runs on Gulp, you'll need to set up a few tools before using it:

CHATER4 Blade Templating

Compared to most other backend languages, PHP actually functions relatively well as a templating language. But it has its shortcomings, and it's also just ugly to be using
Laravel offers a custom templating engine called Blade, which is inspired by .NET'S Razor engine. It boasts a concise syntax, a shallow learning curve, a powerful and intuitive inheritance model, and easy extensibility.

For a quick look at what writing Blade looks like, check out Example 4-1.

Example 4-1. Blade samples

{{ $group->title }}


{!! $group->heroImageHtml() !!}

@forelse ($user as $user)
    {{ $user->first_name }} {{$user -> last_name }}
@empty
    No user in this group
@endforelse

As you cna see, Blade introduces a convention in which its custom tags, called "directives," are prefixed with an @. You'll use directives for all of your control structures and also for inheritance and any custom functionality you want to add.

Blade's syntax is clean and concise, so at its core it's just more pleasant and tidy to work with than the alternatives. But the moment you need anything of any complexity in your templates-nested inheritance, complex conditionals, or recursion-Blade starts to really shine. Just like the best Laravel components, it takes complex application requirements and makes them easy and accessible.

Additionally, since all Blade syntax is compiled into normal PHP code and then cached, it's fast and it allows you to use native PHP in your Blade files if you want. However, I'd recommmend avoiding usage of PHP if at all possible-usually if you need to do anything that you can't do with Blade or a custom Blade directive, it doesn't belong in the template.

Using Twig with Laravel
Unlike many other Symfony-based frameworks, Laravel doesn't use Twig by default. But if you're just in love with Twig, there's a TwigBridge package that makes if easy to use Twig instead of Blade.

Echoing Data
As you can see in Example 4-1, {{and}} are used to wrap sections of PHP that you'd like to echo. {{ $variable }} is similar to in plain PHP.
It's different in one way, however, and you might've guessed this already: Blade escapes all echoes by default useing PHP's htmlentities() to protect your users from malicious script insertion. That means {{ $variable }} is functionally equivalent to . If yhou want to echo without the escaping, use {!! and !!} instead.

{{ and }} When Using a Frontend Templating Framework
You might've noticed that the echo syntax for Blade ({{ }}) is similar to the echo syntax for many frontend frameworks. So, how does Laravel know when you're wirting Blade versus Handlebars?

Blade will ignore any {{ that's prefaced with an @. So, it will parse the first of the following examples, but the second will be echoed out directly:

      // Parsed as Blade; the value of $bladeVariable is echoed to the view
      {{  $bladeVariable }}

       // @ is removed, and "{{   handlebarsVariable }}" echoed to the view directly
        @{{  handlebarsVariable }}

Control Structures
Most of the control structures in Blade will be very familiar. Many directly echo the name and structure of the same tag in PHP.

There are a few convenience helpers, but in general, the control structures just look cleaner than they would in PHP.

Conditionals
First, let's take a look at the control strucrures that allow for logic.

@if
Blade's @if ($condition) compiles to . @else, @elseif, and @endif also compile to the exact same syntax in PHP. Take a look at Example 4-2 for some examples.

Example 4-2. @if, @else, @elseif, and @endif

@if ( count($talks) === 1)
      There is one talk at this time period.
@elseif (cout($talks) === 0)
      There are no talks at this time period.
@else
      There are {{ count($talks) }} talks at this time period.
@endif

Just liek with the native PHP conditionals, you can mix and match these how you want. They don't have any special logic; there's literally a parser looking for someting with the shape of @if $condition) and replacing it with the appropriate PHP code.

@unless and @endunless

@unless, on the other hand, is a new syntax that doesn't have a direct equivalent in PHP. It's the direct inverse of @if. @unless condition) is the same as

Example 4-3. @unless and @endunless

@unless $user -> hasPaid())
      You can complete your payment by switching to the payment tab.
@endunless

Loops
Next, let's take a look at the loops.

@for, @foreach, and @while

@for, @foreach, and @while work the same in Blade as they do in PHP; see Examples 4-4, 4-5, and 4-6.

Example 4-4. @for and @endfor

@for ($i = 0; $i < $talk ->slotsCount(); $i++)
      The number is {{ $i }}
@endfor

Example 4-5. @foreach and @endforeach

@foreach ($talks as $talk)
      {{ $talk -> title }} ({{  $talk->length }} minutes)
@endforeach

Example 4-6. @while and @endwhile

@while   $item = array_pop($items))
    {{  $item->orSomething() }}
@endwhile


@forelse
@forelse is a @foreach that also allows you to program in a fallback if the object you're iterating over is empty. We saw it in action at the start of this chapter; Example 4-7 shows another example.

Exmaple 4-7. @forelse

@forelse $talks as $talk)
     {{ $talk -> title }} ( {{ $talk ->length }} minutes )
@empty
     No talks this day
@endforelse

$loop Within @foreach and @forelse
The @foreach and @forelse directives in Laravel 5.3 add one feature that's not available in PHP foreach loops: the $loop variable. Used within a @foreach or @forelse loop, this variable will return a stdClass object with the following properties:

index
     The 0-based index of the current item in the loop; 0 would mean "first item"

iteration
      The 1-based index of the current item in the loop; 1 would mean "first item"

remaining
      How many items remain in the loopo; if the current item is the first of three, this        will be 2

 count
      The count of items in the loop

 last
      A boolean indicating whether this is the last item in the loop

 depth
      How many "levels" deep this loop is: 1 for a loop, 2 for a loop within a loop, etc.

 parent
      A reference to the $loop variable for the parent loop item; if this loop is within
      another @foreach loop otherwise, null
 
               Here's an example fo how to use it:
                 

                      @foreach pages as $page)
                           
  • {{ $loop->iteratiion }} : {{ $page ->title }}

  •                              @if $page->hasChildren())
                               

                                    @foreach $page->children() as $child)
                                           
    • {{ $loop->parent->iteration }}.

    •                                            {{ $loop->iteration }}:
                                                 {{ $child->title }}
                                     @endforeach
                                   
                                      @endif
                               
                            @endforeach
                           

      or
      If you're ever unsure whether a variable is set, you're probably used to checking isset() on it before echoing it, and echoing something else if it's not set. Blade has a convenience helper,or , that does this for you and lets you set a default fallback: {{ $title ro "Default" }} will echo the value of $title if it's set, or "Default" if not.

      Template Inheritance
      Blade provides a structure for template inheritance that allows views to extends, modify, and include other views.

      Here's how inheritance is structured with Blade.

      Defining Sections with @section/@show and @yield

      Let's start with a top-level Blade layout, like in Example 4-8. This is the definition of the generic page wrapper that we'll later place page-specific content into.

      Example 48. Blade layout


           
                  My site | @yield('title', 'Home Page')
           
           
                 

                         @yield('content')
                 
                  @sectionfooterScripts')
                         
                  @show
           


      This looks a bit like a normal HTML page, but you can see we've yielded in two places(title and content), and we've defined a section in a third(footerScripts).

      We have threee Blade directive here that each look a little different: @yield('title', 'Home Page') alone, @yield('content')with a deined default, and @section ...
      @show with actual content in it.

      All three function essentially the same. All three are defining that there's a section with a given name (which is the first parameter). All three are defining that the section can be extended later. And all three are defining what to do if the section isn't extedned, either by providing a string fallback ('Home Page'), no fallback (which will just not show anything if it's not extednded), or an entrie block fallback (in this case,  ).

      What's different? Well, clearly, @yieldcontent') has no default content. But addtionanlly, the default content in @yield('title') only will be shown if it's never extended. If it is extended, its child sections will not have programmatic access to the default value. @section ... @show, on the other hand, is both defining a default and doing so in a way that its default contents will be available to its children, through @parent.

      Once you have a parent layout like this, you can extend it like in Example 4-9.

      Example 4-9. Extending a Blad layout

      @extendslayouts.master;)

      @section('title', 'Dashboard')

      @section('content')
               Welcom to your application dashboard!
      @endsection

      @section('footerScripts')
             @parent

             
      @endsection

      @show versus @endsection
      You may have noticed that Example 4-8 uses @section ... @show, but Example 4-9 uses @section ... @endsection. What's the difference?

      Use @show when you're defining the place for a section, in the parent template. Use @endsection when you're defining the content for a template in a child template.

      This child view will actually allow us to cover a few new concepts in Blade inheritance.

      @extends
      First, with @extends('layouts.master'), we define that this view should not be rendered on its own, but that is instead extends antoer view. That means its role is to define the content of various sections, but not to stand alone. It's almost more like a series of buckets of content, rrather than an HTML page. This line also defines that the view it's extending lives at resources/views/layouts/master.blade.php.

      Each file should only extend one other file, and the @extends call should be the first line of the file.

      @section and @endsection
      Second, with @section('title', 'Dashboard'), we provide our content for the first section, title. Since the content is so shortk, instead of using @section and @endsection we're just using a shortcut. This allows us to pass the content in as the second parameter of @section and then move on. If it's a bit disconcerting to see @section without @endsection, you could just use the normal syntax.

      Third, with @section('content') and on, we use the normal syntax to define the contents of the contentn section. We'll just throw a little greeting in for now. Note however, that when yhou;re using @section in a child view, you end it with @endsection r its alias @stop), instead of @show, which is reserved for defining sections in parent views.

      @prent
      Fourch, with @section('footerScripts') and on, we use the normal syntax to define the contents of the footerScripts section.

      But remember, we actually defined that content (or, at least, its "default") already in the master layout. So this time, we have two options:we can either overwrite the content from the parent view, or we can add to it.

      You can see that we have the option to include the content from the parent by using the @parent directive within the section. If we didn't, the content of this section would entirely overwrite anything defined in the parent for this section.

      @include
      Now that we've established the basics of inheritance, there are a few more tricks we can perform.
      What if we're in a view and want to pull in another view? Maybe we have a cll-to-action "sign up" button that we want to re-use around the site. And maybe we want to customize its button text every time we use it. Take a look at Example 4-10.

      Example 4-10. Includeng view partials with @include



          Here's why you should sign up for our app: It's Gread.
       
         @include('sign-up-button', ['text' => 'See just how great it is' ])




          {{ $text }}


      @include pulls in the partial and, optionally, passes data into it. Note that not only can you explicitly pass data to an include via the second parameter of @include, but you can also reference any variables within the included file that are available to the including view ($pageName, in this example). Once again, you can do whatever you want, but I would recommend you consider always explicitly passing every variable that you intend to use, just for clarity.

      @each
      You can probably imagin some circumstances in which you'd need to loop over an array or collection and @include a partial for each item. There's a directive for that:@each.

      Let's say we have a sidebar compposed of modules,and we want to include multiple modules, each with a different tile. Take a look at Example 4-11.

      Example 4-11. Using view partials in a loop with @each


         @eachpartials.module', $modules, 'module', 'partials.empty-module')




         

      {{ $module->title }}






          No modules :(


      View Composers and Service Injection
      As we covered in Chapter 3, it's simple to pass data to our views from the route definition (see Example 4-12).

      Example 4-12. Reminder on how to pass data to views
      Route::get('passing-data-to-views', function(){
         return view('dashboard')
                 ->with('key', 'value');
      });
      There are times, however, when you will find yourself passing the same data over and over to multiple views. Or, you might find yourself using a header partial or something similar that requires some data; will you now have to pass that data in from every route definition that might ever load that header partial?

      Binding Data to Views Using View Composers
      Thankfully, there's a simpler way. The solution is called a view composer, and it allows you to define that any t ime a particular view loads, it should have certain data passed to it-without the route definition having to pass that data in explicitly.

      Let's say you have a sidebar on every page, which is defined in a partial named partials.sidebar (resources/views/partials/sidebar.blade.php) and then included on every page, This sidebar shows a list of the last seven posts that were published on your site. If it's on every page, every route definition would normally have to grab that list and pass it in, like in Example 4-13.

      Example 4-13. Passing sidebar data in from every route

      Route::get('home', function(){
            return view('home')
                    ->with('posts', Post::recent());
      });

      Route::get('about', function(){
            return view('about')
                    ->with('posts', Post::recent());
      });

      That could get annoying quickly.Instead, we're going to use view composers to "share" that variable with a prescribed set of views. We can do this a few ways,, so let's start simple and move up.

      Sharing a variable globally
      First, the ismplest option: just globally "share" a variable with every view in your application like in Example 4-14.

      Example 4-14. Sharing a variable globally

      // Some service provider
      public funciton boot()
      {
          ....
         view()->share('posts', Post::recent());
      }

      If you want to use view()->share(),the besst place would be the boot() method of a service provider so that the binding runs on every page load. You can create a custom ViewComposerService Provider (see Chapter 11 for more about service providers), but for now just put it in App\Providers\AppServiceProvider in the boot() method.

      Using view()->share() makes the variable accessible to every view in the entire application, however, so might be overkill.

      Closure-based view composers
      The next option is to use a closure-based view composer to share variables with a single view, like in Example 4-15.

      Example 4-15. Creating a closure-based view composer

      view()->composer('partials.sidebar', function ($view){
          $view->with('posts', Post::recent());
      });

      As you can see, we've defined the name of the view we want it shared with in the first parameter(partials.sidebar)and then passed a closure to the second parameter; in the closure, we've used $view->with() to share a variable, but now only with a specific view.

      Anywhere a view composer is binding to a particular view (like in Example 4-15, which binds to partials.sidebar), you can pass an array of view names instead to bind to multiple views.

      You can also use an asterisk in the view path, as in partials.*, tasks.*, or just *:
      view()->composer(
            ['partials.header', 'partials.footer'],
            function(){
                $view->with('posts', Post::recent());
            }
      );

      view()->composer('partials.*', function(){
            $view->with('posts', Post::recent());
      });

      Class-based view composers
      Finally, the most flexible but also most complex option is to create a dedicated class for your view composer.

      First, let's create the view composer class. There's no formally defined palce for view composers to live, but the docs recommend App\Http\ViewComposers. So, let's create App\Http\ViewComposers\RecentPostsComposer like in Example 4-16.

      Example 4-16. A view composer
         namespace App\Http\Viewcomposers;

         user App\Post;
         user Illuminate\Contracts\View\View;

         class RecentPostsComposer
         {
              private $posts;
              public function __construct(Post $posts)
              {
                     $this->posts = $posts;
              }

              public function compose(View $view)
              {
                      $view->with('posts', $this->posts->recent());
              }
         }

      As you can see, we're injecting the Post model (typehinted constructor parameters of view composers will be automatically injected; see Chapter 11 for more on the container and dependency injection). Note that we could skip the private $posts and the constructor injection and just usse Post::recent() in the compose() method if we wanted. Then, when this composer is clalled, it runs the compose() method, in which we bind the posts variable to the result of running the recent() method.

      Like the other methods of sharing variables, this view composer needs to have a binding somewhere. Again, you'd likely create a custom ViewComposerServiceProvider, but for now, as seen in Exmaple 4-17, we'll just put it in the boot() method of App \Providers\AppServiceProvider.

      Example 4-17. Registering a view composer in AppServiceProvider

      //AppServiceProvider
      public function boot()
      {
         ...
         view()->composer(
            'partials.sidebar',
            \App\Http\Viewcomposers\RecentPostsComposer::class
          );
      }

      Note that this binding is the same as closure-based view composer, but instead of passing a closure, we're passing the class name of our view composer. Now, every time Blade renders the partials.sidebar view, it'll automatically run our provider and pass the view a posts variable set to the results of the recent() method on our Post model.

      Blade Service Injection
      There are three primary types of data we're most likely to inject into a view: collections of data to iterate over, single objects that we're displayingn on the page, and services that generate data or views.

      With a service, the pattern will most likely look like Example 4-18, where we inject an instance of our analytics service into the route definition by typehinting it in the route's method signature, and then pass it into the view.

      Example 4-18. Injecting service into a view via the route definition constructor
      Route::get('backend/sales', function(AnalyticsService $analytics){
           return view('bakcend.sales-graphs')
                  -> with('analytics', $analytics);
      });

      Just as with view composers, Blade's service injection offers a convenient shortcut to reduce duplicationin your route definitions. Normally, the content of a view using our analytics service might look like Exmaple 4-19.

      Example 4-19. Using an injected navigation service in a view


           {{ $analytics->getBalance() }} / PP $analytics->getBudget() }}


      Blade serviceinjection makes it easy to inject an instance of a class outside of the container directly from the view, like in Example 4-20.

      Example 4-20. Injecting a service directly into a view

      @injectanalytics', 'App\Services\Anaalytics')

           {{ $analytics->getBalance() }} / {{ $analytics->getBudget() }}


      As you can see, this @inject directive has acually made an $analytics variable available, whichwe're using later in our view.

      The first parameter of @inject is the name of the variable you're injecting, and the second parameter is the class of interface that you want to inject an instance of.
      This is resolved just like when you type hint a dependency in a constructor elsewhere in Laravel;if you're unfamiliar with how that works, go to Chapter 11 to learn more.

      Just like view composers, Blade service injection makes it easy to make certain data or functionality available to every instance of a view, without having toinject it via the route definition every time.

      Custom Blade Directives
      All of the built-in syntax of Blade tahtwe've covered so far-@if, @unless, and so  on - are called directives, Each Blade directive is a mapping between a pattern (e.g., @if ($condition)) and a PHP output( e.g., ).

      Directives aren't just for the core; you can actually create your  own. You might think directives are good for making little shortcuts to bigger pieces of code-for example, using @button('buttonName') and having it expand to a larger set of button HTML.
      This isn't a terrible idea, but for simple code expansion like this you might be better off including a view partial.

      I've found custom directives to be the most useful when they simplify some form of repeated logic. Say we're tired of having to wrap our code with @if (auth()->guest() (to check if a user is logged in or not)and we want a custom @ifGuest directive. As with view composers, it might be worth having a custom service provider to register these, but for no let's just put it in the boot() method of App\Profiders\AppServiceProvider. Take a look at Example 4-21 to see what this binding will look like.

      Example 4-21. Binding a custom Blade directive

      // AppServiceProvider
      public function boot()

           Blade::directive('ifGuest', function() {
                 return "guest()): ?>"
           });
      }

      We've now registered a custom directive, @ifGuest, which will be replaced with the PHP code guest()): ?>.

      This might feell strange. You're writing a string that will be returned and then executed as PHP, But what this means is that you can now take the complex, or ugly, or unclear, or repetitive aspects of your PHP templating code and hide them behind clear, simple, and expressive syntax.

      Custom directive result caching
      You might be tempted to do some logic to make your custom directive faster by performing an operation in the binding and then embedding the result within the returned string:

      Blade::directive('fiGuest', function(){
           // Antipattern! Do not cop.
          ifGuest = auth()->guest();
          return "";
      });

      The problem with this idea is that it assumes this directive will be re-created on every page load. However, Blade caches aggressively, so you're going to find yourself in a bad spot if you try this.

      Parameters in Custom Blade Directives
      What if you want to check a condition in your custom logic? Check ou Example 4-22.

      Example 4-22. Creating a Blade directive with parameters

      //Binding
      Blade::directive('newlinesToBr', function($expression){
            return "";
      });
      //In use
      @newlinesToBr($message->body)

      The $expression parameter received by the closure represents whatever's within the parentheses. As you can see, we then generate a valid PHP cod snippet and return it.

      $expression parameter scoping before Laravel 5.3
      Before Laravel 5.3, the $expression parameter also included the parentheses themselves. So, in Exmaple 4-22, $expression (which is $message->body in Laravel 5.3 and later) would have instead been ($message->body), and we would've had to write .

      If you find yourself constantly writing the same conditional logic over and over, you should consider a Blade directive.

      Example: Using Custom Blade Directives for a Multienant App

      So, let's imagine we're building an application that supports multitenancy, which means users might be visiting the site from www.myapp.com, client1.myapp.com, client2.myapp.com, or elsewhre.

      Suppose we have written a class to encapsulate some of our multitenancy logic and named it Context. this class will capture information and logic about the context of the current visit, such as who the authenticated user is and whether the user is visiting the public website or a client subdomain.

      We'll probably frequently resolve that Context class in our views and perform conditionals on ti, like in Example 4-23. The app('context') is aa shortcut to get an instance of a class from the container, which we'll learn more about in Chapter 11.

      Example 4-23. Conditional on context without a custom Blade directive

      @if (app('context')-> isPublic())
          © Copyright MyApp LLC
      @else
           © Copyright {{ app('context') -> client ->name }}
      @endif

      What if we could simplify @if (app('context') ->isPublic()) to just @ifPublic?
      Le's do it, Check out Example 4-24/

      Example 4-24.Conditionals on context with a custom Blade directive

      // Binding
      Blade::directive('ifPublilc', function(){
             return "isPublic()): ?>";
      });

      // In user
      @ifPublic
          © Copyright MyApp LLC
      @else
          © Copyright {{ app('context')->client->name }}
      @eldif

      Since this resolves to a simple if statement, we can still rely on the native @else and @endif conditionals. But if we wanted, we could also create a custom @elseIfClient directive, or a separate @ifClient directive, or really whatever else we want.

      Testing
      The most common method of testing views is through application testing, meaning that you're actually calling the route that displays the views and ensuring the views have certain content (see Example 4-25). You can also click buttons or submit forms and ensure that you are redirected to a certain page, or that you see a certain error.
      (You'll learn more about testing in Chapter 12.)

      Example 4-25. Testing that a view display certain content

      // EventsText.php
      public function test_list_page_show_all_events()
      {
          $event1 = factory(Event::class) -> create();
          $event2 = factory(Event::class) -> create();
       
         $this->visit('events')
               ->see($event1->title)
                ->see($event2->ttile)
      }
      You can also test that a certain view has been passed a particular set of data, which, if it accomplishes your testing goals, is less fragile than checking for certain text on the page. Example 4-26 demonstrates this approach.

      Example 4-26. Testing that a view was passed certain content

      // EventsTest.php
      public function test_liat_pageshows_all_events()
      {
          $event1 = factory(Event::class)->create();
          $event2 = factory(Event::class)->create();

          $this->visit('events');

          $this->assertViewHas('events', Event::all());
          $this->assertViewHasAll([
             'events' => Event::all(),
             'title' => 'Events Page'
          ]);
          $this->assertViewMissing('dogs');
      }

      In 5.3, we gained the ability to pass a closure to $assertViewHas(), meaning we can customize how we want to check more complex data structures. Example 4-27 illustrates how we might use this.

      Example 4-27. Passing a closure to assertViewHas()

      //EventsTest.php
      public function test_list_page_shows_all_events()
      {
           $event1 = factory(Event::class)->create();
           $this->visit('events/' . $event1->id);
           $this->assertViewHas('event', function($event) use ($event1) {
                 return $event->id === $event1->id;
            });
      }

      TL;DR
      Blade is Laravel's templating engine. Its primary focus is a clear, concise, and expressive syntax with powerful inheritance and extensibility. Its "safe echo" brackets are {{ and }}, it unprotected echo brackets are {!! and !!}, and it has a series of custom tags called directives that all begin with @@if and @unless, for example).

      You can define a paret template and leave "holes" in it for content useing @yield and @section/@show. You can then teach its child views to extedd it using @extends('parent.view.name'), and define their sections using @section/@endsection. You use @parent to reference the content of the block's parent.

      View composers make it easy to define that, every time a particular view or subview loads, it should have certain information available to it. And service injection allows the view itself to request data straight from the application container.




























      CHAPTER 3 Routing and Controllers

      The essential function of any web application framework is to take requests from a user and deliver responses, usually via HTTP(s). This means defining an application's routes is the first and most important project to tackle when learning a web framework; without routes, you have no ability to interact with the end user.

      In this chapter we will examine routes in Laravel and show how to define them, how to point them to the code they should execute, and how to use Laravel's routing tools to handle a diverse array of routing needs.

      Route Definitions
      In a Laravel application, yhou will define your "web" routes in routes/web.php and your "API" routes in routes/api.php. Web routes are those hat will be visited by your end users; API routes are those for your API, if you have one, For now, we'll primaryly focus on the routes in routes/web.php.

      In projects running versions of Laravel prior to 5.3, theere will be only one routes file, located at app/Http/routes.php

      The simplest way to define a route is to match a path (e.g.,/)with a closure, as seen in Example 3-1.

      Example 3-1. Basic route definition

      //routes/web.php
      Route::get('/', function(){
             return 'Hello, World!';
      });


      What's a Closuer?
      Closures are PHP's version of anonymous functions. A closure is a function that you can pass around as an object, assign to a variable, pass as a parameter to other functions and methods, or even serialize.

      You've now defined that, if anyone visits / (the root of your domain), Laravel's router should run the closure defined there and return the result. Not tat we return our content and don't echo or print it.

      A quick introduction to middleware
      You might be wondoering, "Why an I returning 'Hello, World!' instead of echoing it?"
      There are quite a few answers, but the simplest is that there are a lot of wrappers around Laravel's request and response cycle, including something called middleware. When your route closure or controller method is done, it's not time to send the output to the browser yet; returning the content allows it to contnue flowing though the response stack and the middleware before it is returned back to the user.

      Many simple websites could be defined entirely within the web routes file.With a few simple GET routes combined with some templates as illustrated in Example 3-2, you can serve a classic website easily.

      Example 3-2. Sample website

      Route::get('/', function(){
             return view('welcome');
      });

      Route::get('about', funciton(){
              return view('about');
      });

      Route::get('products', function(){
               return view('products');
      });

      Route::get('services', function (){
               return view('service');
      });

      Static calls
      If you have much experience developing PHP, you might be surprised to see static calls on the Route class. This is not actually a static method per se, but rather service location using Laravel's facades, which we'll cover in Chapter 11.

      If you perfer to avoid facades, you can accomplish thes same definitions like this:
      $router->get('/', function (){
           return 'Hello, World!';
      });

      HTTP Methods
      If you're not familiar with the idea of HTTP methods, read on in this chapter for more information, but for now, just know that every HTTP request has a "verb", or action, along with it. Laravel allows you to define your routes based on which verb was used; the most common are GET and POST, followed by PUT, DELETE, and PATCH.
      Each mothod communicates a different thing to the server, and to yhour code, about the intentions of the caller.

       Route Verbs
      You might've noticed that we've been using Route::get in our route definitions. This means we're telling Laravel to only match for these routes when the HTTP request use the GET action. But what if it's a form POST, or maybe some JavaScript sending PUT or DELETE requests? There are a few other options for methods to call on a route definition, as illustrated in Example 3-3.

      Example 3-3. Route verbs

      Route::get('/', function(){
            return 'Hello, World!';
      });

      Route::post('/', function () {});

      Route::put('/', function (){});

      Route::delete('/', function(){});

      Route::any('/', function(){});

      Route::match(['get','post'], '/', function(){});

      Route Handling
      As you've probably guessed, passing a closuer to the route definitiion is not the only way to teach it how to resolve a route. Closures are quick and simple, but the larger your application gets, the clumsier it becomes to put all of your routing logic in one file. Additionally, applications using route closures can't tacke advantage of Laravel's route caching (more on that later), which can shave up to hundreds of milliseconds off each request.

      The other common option is to pass a controller name and method as a string in place of the closure, as in Example 3-4.

      Example 3-4, Routes calling controller methods

      Route:: get('/'. 'WelcomeController@index');

      This is telling Laravel to pass requests to that path to the index() method of the App \Http\Controllers\WelcomeController controller. This metohd will be passed the same parameters and treated the same way as a closure you might've alternatively put in its place.

      Route Parameters
      If the route you're defining has parameters-segments in the URL structure that are variable-it's simple to define them in your route and pass them to your closure(see Example 3-5).

      Example 3-5. Route parameters

      Route::get('users/{id}/friends', function ($id){
      //
      });

      The Naming Relationship Between Route  parameters and Closuer/Controller Method Prarameters

      As you can see in Example 3-5, it's most common to use the same names for your route parameters ({id}) and the method parameters they inject into your route definition (function ($id)). But is this necessary?

      Unless you're using route/model binding, no. The only thing that defines which route parameter matches with which method parameter is their order (left to right), as you can see here:

      Route::get('users'/{userId}/comments/{commentId}', function (
                    $thisIsActuallyTheUserId,
                    $thisisReallyTheCommentId
                   ){
                //
         });

      That having been said, just because you can make them differnet doesn;t mean you should. I recommend keeping them the same for the sake of future developers, who could get tripperd up by inconsistent naming.

      You can also make your route parameters optional by including a question mark(?) after the parameter name, as illustrated in Example 3-6. In this case, you should also provide a default value for the route's corresponding variable.

      Example 3-6. Opptional route parameters

      Route::get('users/{id?}, function ($id = 'fallbackId'){
      //
      });
      And you can use regular expressions (regexes) to define that a route should only match if a parameter meets particular requirements, as in Example 3-7.

      Example 3-7. Regular expression route constraints

      Route::get('users/{id}', function($id){
       //
      })-> where('id', '[0-9]+');

      Route::get('users/{username}', function ($username){
        //
      }) -> where('username', '[A=Za-z]+');

      Route::get('posts/{id}/{slug}', function ($id, $slug){
      //
      })-> where(['id'=> '[0-9]+', 'slug'=>'[A-Za-z]+'])';

      As you've probably guessed, if you visit a path that matches a route string, but the regex doesn't match the parameter, it woun't be matched.since routes are matched top to bottom, users/abc would skip the first closure in Example 3-7, but it would be matched by the secound closure, so it would get routed there. On the other hand, posts/abc/123 wouldn't match nay of the closures, so it would returna 404 Not Found error.

      Route Names
      The simplest way to refer to these routes elsewhere in your application is just by their path. There's a url() helper to simplify that linking in your views, if you need it; see Example 3-8 for an example. The helper will prefix your route with the full donain of your site.

      Exmaple 3-8. URL helper
      < a href = "">
      //outputs

      However, Laravel also allows you to name each route, which enables you to refer to it without explicityl referencing the URL. This is helpful because it means you can give simple nkcknames to complex routes, and also becuase linking them by name means you don't have to rewrite your frontend links if the paths change(see Example 3-9)

      Example 3-9. Defining route names

      //Defining a route with anme in routes/web.php
      Route::get('members/{id}', 'MembersController@show')->name('members.show');

      //Link the route in a view using the route() helper


      This example illustrates a few new concepts. First, we're using fluent route definition to add the name, by chaining the name() method after the get() method. This method allows us to name the route, giving it a short alias to make it easier to reference elsewhere.

      Defining custom roeutes in Laravel 5.1
      Fluent route definitions don't exist in Laravel 5.1. You'll need to instead pass an array to the second parameter of your route definition; check the Laravel docs to see more about how this works.
      Here's Example 3-9 in Laravel 5.1:

      Route::get('members/{id}', [
             'as' => 'members.show',
             'user' => 'Memberscontroller@show'
        ]);

      In our example, we've named this route members.show; resourcePlural.action is a common convention within Laravel for route and view names.

      Route Naming Conventions
      You can anme your route anything you'd like, but the common conventiion is to use the plural of the resource name, then a period, then the action. So, here are the routes most common for a resource named photo:

      photos.index
      photos.create
      photos.store
      photos.edit
      photos.update
      photos.destroy
      To learn more about these conventions, see "Resource Controllers" on page 41.

      We also introduced the route() helper. Just like url(), it's intended to be used in views to simplify linking to a named route. If the route has no parameters. You can simply pass the route name: (route('members.index')) and receive a route string http://myapp.com/members/index). If it has parameters, pass them in as an array as teh second parameter like we did in this example.

      In general, I recommend using route names instead of paths to refer to your routes, and therefore using the route() helper instread of the url() helper. Somethimes it can get a bit clumsy-for exmapel, if your're working with multiple subdomanins- but it provides an incredible level of flexiblity to later change the application's routing structure without major penality.

      Passing Route Parameters to the route() Helper
      When your route has parameters(e.g., users/{id}), you need to define thosse parameters when you're using the route() helper to generate a link to the route.

      There are a few different way to pass thers parameters. Let's imagine a route defined as users/{userId}/comments/{commentId}. If the user ID is 1 and the comment ID is 2, let's look at a few options we have available to us:

      Option 1:
            route('users.comments.show', [1,2])
      //http://mysqpp.com/users/1/comments/2

      Option 2:
             route('users.comments.show', ['userId' => 1, 'commentId' =>2]
        //http://myapp.com/users/1/comments/2


      Option 3:
             route('users.comments.show', ['commentId' => 2, 'userId' => 1]
       // http://myapp.com/users/1/comments/2

      Option 4:
               route('users.comments.show', ['userId' => 1, 'commentsId' =>2, 'opt'=>'a'])
        //http://myapp.com/users/1/comments/2?opt=a

      As you can see, nonkeyed array values are assigned in order; keyed array values are matched with the route parameters matching their keys, and anything left over is added as a query parameter.


      Route Groups
      Often a group of routes share a particular characteristic - a certain authentication requirement, a path prefix, or perhaps a controller namespace. Defining these shared characteristics again and again on each route not only seems tedious but also can muddy up the shape of your routes file and obscure some of the structures of your application

      Route groups allow you to group serveral routes together, and apply any shared configuration settings once to the entire group, to reduce this duplication. Additionally, route groups are visual cues to future develpers ( and to your own brain) that these routes are grouped together.

      To group two or more routes together, yo u"surround" the route definitions with a route group, as shwn in Example 3-10. Un reality, you're actually passing a closure to the group definition, and the grouped routes within that closure.

      Example 3-10. Defining a route group

      By default, a route group doesn't actually do anything. There's no difference between the group in Example 3-10 and separating a segment of your routes with code comments. The empty array that's the first parameter, however, allows you to pass a varierty of configuration settings that will apply to the entire route group.

      Middleware
      Probably the most common use for route groups is to apply middleware to a group of reoutes. We'll learn more about middleware in Chapter 10, but, among other things, they're what Laravel uses for authenticating users and restricting guest users from using certain parts of a site.

      In Exmaple 3-11, we're createing a route group around the dashboard and account view and applying the auth middleware to both. In this example, it means users have to be logged in to the application to view the dashboard or the account page.

      Example 3-11. Restricting a group of routes to logged-in users only

      Route::group(['middleware' => 'auth'], function (){
          Route::get('dashboard', function () }
             return view('dashboard');
          });
          Route::get('account', function(){
             return view('account');
          });
       });

      Applying middleware in controllers
      Ofter it's clearer and more direct to attach middleware to your reoutes in the controller instead of at the route definition. You can do this by calling the middleware() method in the constructor of your controller. The string your pass to the middleware() method is the name of the middleware, and you can optionally chain modifier methods (only() and except()) to define which methods will receive that middleware:

      class DashbardController extends Controller
      {
              public function  __construct()
             {
                  $this- > middleware('auth');
                  $this -> middleware('admin-auth')
                         -> only('admin');
                  $this -> middleware('team-member')
                         -> except('admin');
             }
        }
      Note that, if you're doing a lot of "only" and "except" customizations, that's ofter a sign that you should break out a new controller for the exceptional routes.

      Path Prefixes
      If you have a group of routes ghat share a segment of their path-For example, if your site's API is prefixed with /api - you can use route groups to simplify this structure(see Example 3-13).

      Example 3-12. Prefixing a group of routes

      Route::group(['prefix' => 'api'], function (){
             Route::get('/', function(){
                 //Handles the path / api
             });
             Route::get('users', function() {
               //Handles the path /api/users
            });
       });

      Note that each prefixed group also has a /route that represents the root of the prefix - in Example 3-12 that's /api.

      Subdomain Routing
      Subdomain routing is the same as route prefixing, but it's scoped by subdomain instead of route prefix. There are two primary uses for this. First, you may want to present different sections of the application (or entirely different applications) to different subdomains. Example 3-13 show how you can achieve this.

      Exampel 3-13. Subdomin routing

      Route::group(['domain' => 'api.myapp.com'], function(){
              Route::get('/', function(){
                 //
               });
       });

      Second, you might want to set part of the subdomain as a parameter, as illustrated in Example 3-14. This is most often done in cases of multienancy (think Slack or Harverst, where each company gets its own subdomain, like tighten.slack.co).

      Example 3-14. Parameterized subdomain routing

      Route::grouop(['domain' => '{account}.myapp.com'], function (){
          Route::get('/', function($account) {
           //
          });
           Route::get('users/{id}', function ($account, $id){
             //
           });
        });

      Note that any parameters for the group get passed into the grouped routes' methods as the first parameter(s).

      Namespace Prefixed
      When you're grouping routes by subdomain or route prefix, it's likely their controllers have a similar PHP namespace. In the API example, all of the API routes' controllers might be under an API  anmespace. By using the route group namespace prefix, as shown in Example 3-15, you can avoid long controller refeerences in groups like "API/ControllerA@index" and "API/ControllerB@index".

      Example 3-15. Route group namespace prefixes

      //App\Http\Controllers\ControllerA
      Route::get('/', 'ControllerA@index');

      Route::group(['namespace' => 'API']. function() {
           // App\Http\Controllers\API\ControllerB
           Route::get('api/', 'ControllerB@index');
       });

      Name Prefixes
      The prefixes don't stop ther. It's common that route names will reflect the inheritance chain of path elements, so users/commments/5 will be served by a route named user.comments.show. In this case, it's common to user a route group around all of the routes that are beneath the users.comments resource.

      Just like we can prefix URL segments and controller namespaces, we can aslo prefix strings to the route name. With route group name prefixes, we can define that every route within this group should have a given string prefixed to its name. In this context, we're prefixing "users." to each route name, then "comments." (see Example 3-16).

      Example 3-16. Route group name prefixes

      Route::group(['as' => 'users.', 'prefix' => 'users'], function(){
          Route::group(['as' => 'comments.', 'prefix'=>comments'], function (){
            //Route name will be users.comments.show
            Route::get('{id};, fuinction (){
                //
             }) -> name('show');
          });
        });

      Views
      In a few of the route closures we've looked at so far, we've seen something along the lines of return view('account'). What's going on here?

      If you're not familiar with the Model-View-Controller (MVC) pattern, views(or templates) are files that describe what some particular output should look like. You might have views for JSON or XML or emails, but the most common views in a web framework output HTML.

      In Laravel, there are two formats of view you can use out of the box: plain PHP, or Blad templates (see Chapter 4). The difference is in the filename: about.php will be rendered with the PHP engine, and about.blade.php whill be rendered with the Blade engine.

      Three ways to load a view()
      There are three different ways to return a view. For now, just concern yourself with view(), but if you ever see View::make(), it's the same thisng, and you could also inject the Illuminate\View\ViewFactory if you prefer.

      Once you've loaded a view, you have the option to simply return it (As in Example 3-17), which will work fine if the view doesn't rely on any variables from the controller.


      Example 3-17. Simple view() usage

      Route::get('/', function (){
             return view('home');
       });

      This code looks for a view in resources/views/home/blade.php or resource/views/home/php, and loads its contents and parses any inline PHP or control structures until you have just the view's output. Once you return it, it's passed on to the rest of the response stack and eventualluy returned to the user.

      But what if you need to pass in variables? Take a look at Example 3-18.

      Example 3-18. Passing variables to views

      Route::get('task', function (){
          return view('tasks.index')
                  ->with('task', Task::all());
        });
      This closure laods the resources/views/tasks/index.blade.php or resources/views/tasks/index.php view and passes it a single variable named tasks, which contains the reuslt of the Task::all() method. Task::All() is an Eloquent database query we'll learn about in Chapter 8.

      Using View Composers to Share Variables with Every View
      Sometimes it can become a hassle to pass the same variables over and voer. There may be a variable that you want accessible to every view in the site, or to a certain class of views or a certain included subview - for example, allviews related to tasks, or the header partial.

      It's possible to share certain variables with every template or jeust certain templates, like in the following code:
      view() -> share('variableName", 'variableValue');

      To learn more, check out "View composers and Service Injectio" on Page64.

      Controllers
      I've mentioned controllers a few times, but until now most of the exmaples have shown reute closures. If you're not familiar with the MVC pattern(Figure 3-1), controlelrs are essentially clases that organize the logic of one or more routes together in on place. Controllers tend to group similar routes together, especically if your application is structured along a traditionally CRUD-like foramt: in this case, a controller might handle all the actions that can be performed on a particular resource.

      What is CRUD?
      CRUD stands for create, read, update, delete, which are the four primary operations that web applications most commonly provide on a resource. For example, you can create a new blog post, you can read that post, you can update it, or you can delete it.

      It may be tempting to cram all of the applicationn's logic into the controllers, but it's better to think of controllers as the traffic cops that route HTTP requests around your applications. Since there are other ways requests can come into your application - cron jobs, Artisan command-line calls, queue jobs, etc. - it's wise to not rely on controllers for much behavior. This means a controller's primary job is to capture the intent of an HTTP request and pass it on to the rest of the application.

      So, let's create a controller. One easy way to do this is with an Artisan command, so from the command line run the following:

      php artisan make:controller TasksController

      Artisan adn Artisan generators
      Laravel comes bundled with a command-line tool called Artisan.
      Artisan can be used to run migrations, create users and other database records manual, onetime tasks.
      Under the make namespace, Artisan provides tools for generating skeleton files for a variery of system files. That's what allows us to
      run php artisan make:controller.
      To learn more about theis and toehr Artisan features, see Chapter 7.

      This will create a new file named TasksController.php in app/Http/Controllers, with the contents shown in Example 3-19.

      Example 3-19. Default generated controller
      namespace App\Http\Controllers;
      use Illuminate\Http\Reqeust;
      use App\Http\Requests;

      class TasksController extends Controller
      {

      }

      Modify this file as shown in Example 3-20, creating a new public method called home(). We'll just return some text there.

      Example 3-20. Simple controller example
      use App\Http\Controllers\Controller;
      class TasksController extends Controller
      {
             public function home()
             {
                       return 'Hello, World!';
           }
      }

      Then like we learned before, we'll hook up a route to it, as shown in Example 3-21.

      Example 3-21. Route for the simple controller

      // reoutes/web.php
      Route::get('/', 'TasksController@home');

      That's it. Visit the / route and you'll see the words "Hello, World!"

      Controller Namespacing
      In Example 3-21 we referenced a controller with the fully qualified class name of App \Http\Controllers\TasksController, but we only used the class name. This isn't because we can simply reference controllers by their class names. Rather, we can ignore the App\Http\Controllers\ when we refuerence controllers; by default, Laravel is configured to look for controllers within that namespace.

      This means that if you have a controller with the fully qualified class name of App \Http\Controllers\API\ExercisesController, you'd reference it in a route definition as API\ExercisesController.

      The most common use of a controller method, then, will be something like Example 3-22.

      Example 3-22. Common controller method example.

      //TasksController.php
      ....
      public function index()
      {
             return view('tasks.index')
                   ->with('tasks', Task::all());
      }

      This controller method loads the resourcs/views/tasks/index.blade.php or resources/views/tasks/index.php view and passe it  a single variable named tasks, which contains the result of the Task::all() Eloquent method.


      Generating resource controllers
      If you ever use php artisan make:controller in Laravel prior to 5.3, you might be expecting it to autogenerate methods for all of the basic resource routes like create() and update(). You can bring this behavior back in Laravel 5.3 by passing the -- resource flag when you create the controller:
      php artisan make:controller TasksController --resource

      Getting User Input
      The second most common action to perform in a controller method is to take input from the user and act on it. That introduces a few new concepts, so let's take a look at a bit of sample code and walk through the new pieces.

      First. let's bind it quickly; see Example 3-23.

      Example 3-23. Binding basic form actions

      //routes/web.php
      Route::get('tasks/create', 'TasksController@create');
      Route::post('tasks', 'TasksController@store');

      Notice that we're binding the GET action of tasks/create (which shows the form) and the POST action of tasks/ (which is where we POST when we're createing a new task). We can assume the create() method in our controller just shows a form, so let's look at the store() mtthod in Example 3-24.

      Example 3.24. Common from input contrller method

      // TaskController.php
      ....
      public function store()
      {
              $task = new   Task();
              $task -> title = Input::get('title');
              $task -> description = Input::get('description');
              $task -> save();
         
              return redirect('tasks');
      }
      This example makes use of Eloquent models and the redirect() functionality, and we'll talk agbout them more later, but you can see what we're doing here: we create a new Task, pull data out of the user input and set it on the task, save it, and then redirect back to the page that shows all task.

      There are two main ways to get user input from  a POST: the Input facade, which we used here, and the Request object, which we'll talk about next.

      Importing facades
      If you follow any of these examples, whether in controllers or any other PHP class that is namespaced, you might find errors showing that the facade cannot be found. This is because they're not present in every namespace, but rather they're made available the root namespace.

      So, in Example 3-24, we'd need to import the Input facade at the top of the file, There are two ways to do that: either we can import \Input, or we can import Illuminate\Suppert\Facades\Input.
      For example:
      namespace App\Http\Controllers;
      use Illuminate\Support\facades\Input;

      class TaskController
      {
           public function store()
           {
              $task = new   Task();
              $task -> title = Input::get('title');
              $task -> description = Input::get('description');
              $task -> save();
         
              return redirect('tasks');
            }
      As you can see, we can get the value of any user-provided information, whether from a query parameter or a POST value, using input::get('filedName'). So our user filled out two fields on the "add task" page:"title" and "description." We retrieve both using the Input facade, save them to the database, and then return.

      Injecting Dependencies into Controllers
      Laravel's facades paresent a simple interface to the most useful classes in Laravel's codebase. You can get information about the current request and user input, the session, caches, and much more.

      But if you prefer to inject your dependencies, or if you want to use a service that doesn't have a facade, you'll need to find some way to bring instances of these classes into your controller.

      This is our first exposure to Laravel's service container. For now, if this is unfamiliar you can think about it as a little bit of Laravel magic; or, if you want to know more about how it's actually functioning, you can skip ahead to Chapter 11.

      All controller methods (including the constructors) are resolved out of Laravel's container, which means anything you typehint that the container knows how to resolve will be automatically injected.

      As a nice example, what if you'd refer having an instance of the Request object instead of using the facade? Jest typehint Illuminate\Http\Request in your method parameters, like in Example 3-25.

      Example 3-25. Controller method injecting via typehinting
      //TasksController.php
      .....
      public function store(\Illuminate\Http\Request $request)
      {
              $task = new   Task();
              $task -> title = $request->input('title');
              $task -> description = $request->input('description');
              $task -> save();
         
              return redirect('tasks');
      }

      So, you've defined a parameter that must be passed into the store() method. And since you typehinted it, and since Laravel knows how to resolve that class name, you're going to have the Reqeust object ready for  you to use in your method with no work on your parkt. No explicit binding, no anything else-it's just there are the $reqeust variable.

      By the way, this is actually how I and many other Laravel developers prefer to get the user input: inject an instance of the Reqeusedt and read the user input from there, instread of relying on the Input facade.


      Resource Controllers
      Sometimes naming the methods in your controllers can be the hardest part of writing a controller. Thankfully, Laravel has some conventions for all of the routes of a traditional REST/CRUD controller ( called a "resource controller" in Laravel); additionally, it ocmes with a generator out of the box and a convenience route definition that allows you to bind an entire resource controller at once.

      To see the mothods that Laravel expects for a resouce controller, let's generate a new controller from the command line:
      php aratisan make:controller MySampleResourceController --resource

      Now open app/Http/Controllers/MysampleResourceController.php. You'll see it comes prefilled with quite a few methods. Let's walk over what each represents. We'll use a Task as an example.

      The methods of Laravel's resource controllers

      For each, you can see the HTTP verb, the URL, the controller method name, and the "name". Table 3-1 shows the HTTP verb, the URL, the controller method name, and the "name" for each of these default methods.

      Table 3-1. The methods of Laravel's resource controllers

      Verb     URL            Controller method Name             Description
      GET      tasks           index()                tasks.index       Show all tasks
      GET      tasks/create  create()               tasks.create      Show the create task form
      POST    tasks           store()                tasks.store       Accept form submission
                                                                              from the create task form
      GET      tasks/{task}    show()                tasks.show      Show one task
      GET      tasks/          edit()                  tasks.edit        Edit one task
                {task}/edit

      PUT/PATCH tasks/{task} update()            tasks.update    Accept form submission from
                                                                             the edit task form
      DELETE   tasks/{task}   destroy()             tasks.destroy    Delete one task

      Binding a resource controller
      So, we've seen that these are the conventional route names to sue in Laravel, and also that it's easy to generate a resource controller with methods for each of these controller methods by hand, if you don't want to. Instead, there's a trick for that, and it's called "resource controller binding." Task a look at Example 3-26.

      Example 3-26. Resource controller binding

      //routes/web.php
      Route::resource('tasks', 'TasksController');

      This will automatically bind all of the routes for this resource to the appropriate method names on the specified controller. It'll also name these routes appropriately; for example, the index() method on the tasks resource controller will be named tasks.index.

      artisan route:list
      If you ever find yourself in a situation where you're wondering what routes your current application has available, there's  a tool for that: from the command line, run php artisan route:list and you'll get listing of all of the available routes.

      Route Model Binding
      One of the most common routing patterns is that the first line of any controller method tries to find the resource with the given ID, like in Example 3-27.

      Example 3-27. Getting a resource for each route
      Route::get('conferences/{id}', function ($id) {
            $conference = Conference::findOrFail($id);
       });
      Laravel provides a feature that simplifies this pattern called "route model binding."
      This allows you to define that a particular parameter name (e.g., {conference}) will indicate to the route resolver that it should look up an Eloquent record with that ID and then pass it in as the parameter instead of just passing the ID.

      There are two kinkds of route model binding:implicit and custom(or explicit).

      Implicit Route Model Binding
      The simplest way to use route model binding is to name your route parameter something unique to that model (e.g., name it $conference instead of $id), then typehint that parameter in the closure/controller method and use the same variable name there. It's easier to show than to describe, so take a look at Example 3-28.

      Example 3-28. Using an explicit route model binding
      Route::get('conferences/{conference}', function(Conference $conference){
          return view('conferences.show') ->with('conference', $conference);
      });

      Because the route parameter ({conference}) is the same as the method parameter ($conference), and the method parameter is typehited with a Conference model (Conference $conference), Laravel sees this as a route model binding. Every time this route is visited, the application will assume that whatever is passes into the URL in place of {conference} is an ID that should be  used to look up a Conference, and then that resulting model instance will be passed into your closure or controller method.

      Customizing the route key for an Eloquent model
      Any time an Eloquent model is looked up via a URL segment (usually because of route model binding), the default column Eloquent will because of route model binding), the default column Eloquent will look it up is its primary key(ID).

      To change the column your Eloquent model uses for URL lookups add a method to your model named getRouteKeyName*():

      public function getRouteKeyName()

                    return 'slug';
      }

      Now, a URL like conferences/{conference{ will expect to get the slug instread of the ID, and will perform its lookupas accordingly.

      5.2 Implicit route model binding was added in Laravel 5.2, so you won't have access to it in 5.1

      Custom Route Model Binding
      To manually configure route model bindings, add a line like the one in Example 3-29 to the boot() method in App\Providers\RoutesServiceProvider.

      Example 3-29. Adding a route model binding

      public function boot(Router $router)
      {
          // just allows the parent's boot() method to still run
          parent::boot($router);

         // perform the binding
          $router -> model('event', Conference::class);
      }

      You've now defined that whenever a route has a parameter in its definition named {event}, as demonstrated in Example 3-30, the route resolver will return an instance of the Conference class with the ID of that URL parameter.

      Example 3-3-. Using an explicit route model binding

      Route::get('events/{event}', function(Conference $event){
         return view('events.show') ->with('event', $event);
      });

      Route Caching
      If you're looking to squeeze every millisecond out of your load time, you may wantto take a look at route caching. One of the pieces of Laravel's bootstrap that can take anywhere from a few dozen to a few hundred milliseconds is parsing the routes/* files, and route caching speeds up this process dramatically.

      To cache your routes file, you need to be using all controller and resource routes (no routes closures). If you r app isn't using any route closures, you can run php artisan route:cache, Laravel will serialize the results of your routes/* files. If you want to delete the cache, run php artisan route:clear.

      Here's the drawback: Laravel will now match routes against that cached file instread of your actual routes/* files. You can make endless changes to those files, and they won't take effect until you run route:cache again. This means you'll have to recache every time you make a change, which introduces a lot of potential for confusion.

      Here's what I would recommend instead: since Git ignores the route cache file by default anyway, consider only using route caching on your production server, and run the php artisan route:cache command every time you deploy new code (whether via a Git post-deploy hook, a Forge deploy command, or as a part of whatever other deploy system you use). This way you won't have confusing local development issues, but your remeote environment will still benefit from route caching.

      Form Method Soofing
      Sometimes, you need to manually define which HTTP verb a from should send as. HTML forms only allow for GET or POST, so if you want any other sort of verb,  you'll need to specify that yourself.

      An Introduction to HTTP Verbs
      We've talked about the GET and POST HTTP verbs already. If  you're not familiar with HTTP verbs, the other two most common ones are PUT and DELETE, but rhere's also HEAD, OPTIONS, PATCH, and two others that are pretty much never used in normal web development, TRACE and CONNECT.

      Here's the quick rundown: GET requests a resource and HEAD asks for a headers-only version of the GET, POST creates a resource, PUT overwrites a resource and PATCH modifies a resource, DELETE deletes a resource, and OPTIONS asks the server which verbs are allowed at this URL.

      HTTP Verbs in Laravel
      As we've shown already, you can define which verbs a route will match in the route definition using Route::get(), Route::post(), Route::any(), or Route::match().
      You can also match with Route::patch(), Route::put(), and Route::delete().

      But how does one send a request other than GET with a web browser? First, the method attribute in an HTML form determines its HTTP verb: if your form has a method of "GET", it will submit via query parameters and a GET method; if the form has a method of "POST", it will submit via the post body and a POST method.

      JavaScript frameworks make it easy to send other requests, like DELETE and PATCH. But if you find yourself needing to submit HTML forms in Laravel with verbs other than GET or POST, you'll need to sue form method spoofing, which is spoofing the

      HTTP method in an HTML form.
      To inform Laravel that the form you're currently submitting should be treated as something other than POST, add a hidden variable named _method with the value of either "PUT", "PATCH", or "DELETE", and Laravel will match and route that form submission as if it were actually a request with that verb.

      The form in Example 3-31, since it's passing Laravel the method of "DELETE", will match routes defined with Route::delete() but not those with Route::post().

      Example 3-31. Form method spoofing

         


      CSRFJ Protection
      If you've tried to create and submit a form in a Laravel application already - including the form in Example 3-31 - you've likely run into the dreaded TokenMismatchException.

      By default, all routes in Laravel except "read-only" routes (those using GET, HEAD, or OPTIONS) are protected against cross-site request forgery (CSRF) attacks by requiring a token, in  the form of an input named _token, to be passed along with each request.
      This token is generated at the start of every session, and every non-read-only route
      What is CSFR?
      A cross-site request forgery is when one website pretends to be anoher. The goal is for someone to hijack your users' access to your website, by submitting forms from their website to your website via the logged-in user's browser.
      The best way around CSRF attacks is to protect all inbound routes -POST, DELETE, etc. -with a token, which Laravel does out of the box.

      You have two options for getting around this. The first, and preferred, method is to add the _token input to each of your submissions. In HTML  froms, that's simple;
      look at Example 3-32.

      Example 3-32. CSRF token

           
           
           


      In JavaScript applications, it's a bit mroe work, but not much. The most common solution for sites using JavaScript fraeworks is to stre the token on every page in a tag like this one:
       

      Storing the toekn is a tag makes it easy to bind it to the correct HTTP header, shich you can do once globally for all requests from your JavaScript framework, like in Example 3-33.

      Example 3-33. Globally binding a header for CSRF

      //in jQuery:
      $.ajaxSetup({
            headers: {
                 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
           }
      });

      //in vue:
      Vue.http.interceptors.push((request, next) => {
           request.headers['X-CSRF-TOKEN'] =
                 document.querySelector('#token').getAttribute('content');

          next();
      });

      Laravel will check the X-CSRF-TOKEN on every request, and valid tokens passed these will mark the CSRF protection as satisfied.

      Note that the Vue syntax for CSRF in this example is not necessary if you're working with the 5.3 Vue bootstrap; it already does  this work for you.

      Redirects
      So far the only tings we've returned from a controoler method or route definition have been views. But there are a few other structures we can return to give the browser instructions on how to behave.

      First, let's cover the redirect. There are two common ways to generate a redirect; we'll use the redirect global helper here, but you may prefer the facade. Both create an instance of Illuminate\Http\RedirectResponse, perform some convenience methods on it, and then return it. You can also do this manualluy, but you'll have to do a little more work yourself. Take a look at Example 3-34 to see a few ways you can return a redirect.

      Example 3-34. Different ways to return a redirect

      // Using the global helper to generate a redirect response
      Route::get('redirect-with-helper', function(){
          return redirect()->to('login');
      });

      // Using the global helper shortcut
      Route::get('redirect-with-helper-shortcut', function(){
            return redirect('login')
      });

      // Using the facade to generate a redirect response
       Route::get('redirect-with-facade', function(){
             return Redirect::to('login');
       });

      Note that the redirect() helper exposes the same methods as the Redirect facade, but it also has a shortcut; if you pass parameters directly to the helper, instead of chaining methods after it, it's shortcut to the to() redirect method.

      redirect() -> to()
      The method signature for the to() method for redirects looks like this:
          function to($to = null, $status = 302, $headers = [], #secure = null)
      $to is a valid internal path; $status is the HTTP status (defaulting to 302 FOUND); $headers allows you to define which HTTP headers to send along with yhour redirect; and $secure allows you to override the default choice of http versus https(which is normally set based on your current request URL). Example 3-35 shows another example of its use.

      Example 3-35. redirect()->to()
      Route::get('redirect', function(){
          return redirect()->to('home')'

         // or sam, useing the shortcut
          return redirect('home');
      });

      redirect()->route()
      The route() method is the same as the to() method, but rather than pointing to a particular path, it points to particular route name (see Example 3-36).

      Example 3-36. redirect()->route()
      Route::get('redirect', function (){
         return redirect()->route('conferences.index');
      });
      Note that, since some route names require paramters, its parameter order is a little dirrerent.route() has an optional second parameter for the route parameters:
          function route($to = null, $parameters = [], $status = 302, $headers = [])
      So, using it might look a little like Example 3- 37.

      Example 3-37. redirect()->route() with parameters
      Route::get('redirect', function(){
           return redirect()->route('conferences.show', ['conference' => 99]);
      });

      redirect()->back()
      Because of some of the built-in conveniences of Laravel's session implementation, your application will always have knowledge of what the user's previously visited page was. That open up the opportunity for a redirect()->() redirect, which simply reidrects the user to whatever page she came from. there's also a global shortcut for this:back().

      Other Redirect Methods
      The redirect service provides other methods ghat are less commonly used, but still available:

      - home() redirects to a route named home.
      - refresh() redirects to the same page the user is currently on.
      - away() allows for redirecting to an external URL without the default URL validation.
      - secure() is like to() with the secure parameter set to "true"
      - action() allows you to link to a controller and method like this: redirect()->action('MyController@myMethod').
      - getst() is used internally by the auth system (discussed in Chapter 9); when a user visits a route he's not authenticated for, this captures the "intended" route and then redirects the user (usually to  a login page).
      - intended() is also used internally by the auth system; after a successful authentication, this grabs the "intended" URL stored by the guest() method and redirects the user there.

      redirect()->with()
      When you're redirecting users to different pages, you ofter want to pass certain data along with them. You could manually flash the data to the session, but Laravel has some convenience methods to help you with that.

      Most commonly, you can pass along either an array of keys and valeus or a single key and value using with(), like in Example 3-38.

      Example 3-38. Redirect with data
      Route::get('redirect-with-key-value', function(){
           return redirect('dashboard')
                    ->with('error', true);
      });

      Route::get('redirect-with-array', function(){
            return redirect('dashbard')
                    ->with(['error' => true, 'message' => 'Whoops!']);
      });

      Chaining methods on redirects
      As with many other facades, most calls to the Redirect facade can accept fluent method chains, like the with() calls in Example 3-38. Learn more about fluency in "What Is a Fluent Interface?" on page 146.

      You can also use withInput(), as in Example 3-39, to redirect with the user's form input flashed; this is most common in the case of a validation error, where you want to send the user back to the form she just came from.

      Example 3-39. Redirect with form input

      Route::get('form', function(){
         return view('form');
      });

      Route::post('form', function(){
          return redirect('form')
                  ->withInput()
                  ->with(['error' => true, 'message' => 'Whoops!']);
      });
      The easiest way to get the flashed input that was passed with withInput() is using the old() helper, which can be used to get all old input (old()) or just the value for a particular key (old('username'), with the second parameter as the default if ehre is no old value). You'll commonly see this in views, which allows this HTML to be used both on the "create" and the "edit" view for this form:



      Speaking of validation, there is also a useful method for passing errors along with a redirect response:withErrors(). You can pass it any "provider" of errors, which may be an error string, an array of errors, or, most commonly, an instance of the Illuminate Validator, which we'll cover in Chapter 10. Example 3-40 shows an example of its use.

      Example 3-40. Redirect with errors
      Route::post('form', function (){
            $validator = Validator::make($request->all()), $this->validationRules);

            if($validator->fails()){
                  return redirect('form')
                          ->withErrors($validator)
                          ->withInput();
            }
      });

      withErrors() automatically shares an $errors variable with the views of the page it's redirecting to, for you to handle however you'd liek.

      The validate() shortcut in controller methods
      Like how Example 3-40 looks? If you're defining your routes in a controller, there's a simple and powerful tool that cleans up that code. Read more in "validate() in the controller Using VlidatesRequests" on page 103.

      Aborting the Request
      Aside from returning views and redirects, the most common way to exit a route is to about. There are a few globally available methods (abort(), abort_if(), and abort_unless()), which optionally take HTTP status codes, a message, and a headers array as parameters.

      As Example 3-41 shows, abort_if() and abort_unless() take a first parameter that is evaluated for its truthiness, and perform the abort depending on the result.

      Exampel 3-41. 403 Forbidden aborts
      Route::post('something-you-cant-do', function(Illuminate\Http\Request){
          abort(403, 'You cannot do that!');
          abort_unless($request->has('magicToken'), 403);
          abort_if($reqeust->user()->isBannerd, 403);
      });

      Custom Responses
      There are a few other options available for us to return, so let's go over the most common responses after views, redirects, and aborts. Just like with redirects, you can either use the response() helper or the Response facade to run these methods on.

      response()->make()
      If you want to create an HTTP response manually, just pass your data into the first parameter of response()->make(): e.g., return response()->make('Hello, World!'). Once again, the second parameter is the HTTP status code and the third is your headers.

      response()->json()and->jsonp()
      To create a JSON-encoded HTTP response manaually, pass your JSON-able content (arrays, collections, or whatever else) to the json() method: e.g., return response()->json(User::all());. It's just liek make(), except it json_encodes your content and sets the appropriate headers.

      response()->download() and ->file()
      To send a file for the end user to download, pass either an SplFileInfo instance of a string filename to download(), with an optional second parameter of the filename: e.g., return response()->download('file501751.pdf', 'myFile.pdf').
      To display the same file in the browser (if it's a PDF or an image or something else the browser cna handle), use response()->file() instead, which takes the same parameters.

      Testing
      In some other communities, the idea of unit testing controller methods is common, but within Laravel (and most of the PHP community), it't most common to rely on application testing to test the functionality of routes.

      For example, to verify that a POST route works correctly, we can write a test liek Example 3-42.

      Example 3-42. Writing a simple POST route test
      // AssignmentTest.php
      public function test_post_creates_new _assignment()
      {
              $this->post('/assigments', [
                    'title'=> 'My great assignment'
               ]);
              $this->seeInDatabase('assignments', [
                    'title'=> 'My great assigment'
               ]);
      }

      Did we directly call the controller methods? No. But we ensured that the goal of this route-to receive a POST and save its importnt information to the database-was met.
      You can also use similar syntax to visit a route and verify that certain text shows up on the page, or that clicking certain buttons does certain things (see Example 3-43).

      Example 3-43. Writing a simple GET route test

      // AssignmentTest.php
      public function test_list_page_shows_all_assignments()
      {
             $assigment = Assignment::create([
                   'title' => 'My great assignmnet'
             ]);

              $this->visit('assignments')
                      -> see)['My great assignment']);

        }

      TL;DR
      Laravel;s routes are defined in routes/web.php and routes/api.php, where you can define the expected path for each route, which segments are static and which are parameters, which HTTP verbs can access the route, and how to resolve it. You can also attach middleware to reoutes, group them, and give them names.

      What is returned from theroute closue or controller method dictates how Laravel responds to the user. If it's a string ro a view, it's presented to the user; if it's other sorts of data, it's converted to JSON and presented to the user; and if it's a redirect, it forces a redirect.

      Laravel provides a series of tools and conveniences to simplify common routing-related tasks and structures. These include resource controllers, route model binding and form method spoofing.