# Laravel 筆記
###### tags: `Laravel` `PHP` `學習紀錄` `筆記` `note`
# 目錄
[TOC]
# 架構
## IOC
* 
## DI
* 
# 權限相關
* [Laravel Roles and Permissions: All CORE Things You Need To Know](https://youtu.be/kZOgH3-0Bko)
## Gate
* 在blade 中用 @can...@endcan包起來的區塊可以用gate控制權限
* [參考影片](https://youtu.be/kZOgH3-0Bko?t=369)
# Artisan
## ARTISAN 命令全攻略
* [哥布林文章](https://pandalab.org/articles/124)
* 
## php artisan serve 行為追朔
* ["php artisan serve"到底干了什么](https://segmentfault.com/a/1190000013025428)
* [源码解读:php artisan serve](https://zhuanlan.zhihu.com/p/27573264)
# HTTP
* [Laravel 底層是如何處理HTTP請求](https://iter01.com/584576.html)
# Laravel 技能樹
* [Laravel Learning Path](https://github.com/LaravelDaily/Laravel-Roadmap-Learning-Path)
# Polymorphic Relations
* [介绍 Eloquent 关联中的多态关联(Polymorphic Relations)
](https://learnku.com/articles/5375/describes-the-polymorphic-association-polymorphic-relations-in-the-eloquent-association)
# CRUD
* [較完整的CRUD](https://www.youtube.com/watch?v=rgOlkcTncv8)
* [Laravel DB Transactions: Example When/How to Use Them](https://www.youtube.com/watch?v=7daBdm2xgm8)
* 心得寫這
* [Laravel Form Request: Store/Update - Same or Separate Class?](https://youtu.be/YK8GZmuf8_0)
* 可用一個request class 檢查store & update
## Delete
* [刪除文章但是不刪除資料!聊 Soft Delete](https://ithelp.ithome.com.tw/articles/10219283)
# Queue
* [Laravel Queues 101: Example with Sending Emails](https://www.youtube.com/watch?v=rVx8xKisbr8)
* 重點整理
* php artisan queue:table
* 產生queue表
* php artisan migrate
* 在資料庫產生queue表
* 在config/queue.php 中把sync改成如下圖
* 
* send的動作改成queue or later
* 
* 在.env加入下圖的資訊
* 
* heroku的話記得要去setting加key、value
* php artisan queue:work
* 會持續檢查是否需要執行排程的動作
* heroku上還不確定怎麼實行
* 寄信功能 : Gmail有過一陣子就會被擋,需要手動放行可信任裝置的問題
- [stackoverflow討論](https://stackoverflow.com/questions/33939393/failed-to-authenticate-on-smtp-server-error-using-gmail)
- 目前是手動進入[這理](https://accounts.google.com/UnlockCaptcha)解權限問題
## Fail
* [Laravel Queue – 失敗任務處理](https://www.vnewin.com/laravel-queue-failed/)
# Collection
* [array 用的分頁](https://stackoverflow.com/questions/27064953/how-can-i-paginate-an-array-of-objects-in-laravel)
```php=
public function test()
{
return $this->paginate(GameReport::get())
->setPath(url()->current());
}
public function paginate($items, $perPage = 15, $page = null, $options = [])
{
$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
$items = $items instanceof Collection ? $items : Collection::make($items);
return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
}
```
# Eloquent
* [Laravel Eloquent: Deeper Relationships with One Query](https://youtu.be/5s-_SnVl-1g)
* 優化關連表的查詢方法
* [Eloquent Performance: TOP 3 Mistakes Developers Make](https://www.youtube.com/watch?v=cOzPpGnPCyk)
* ORM 三個可以改善效能的地方
* trait
* trait method 的名字在最前面加上boot 的話會自動被call
* [參考網址](https://www.youtube.com/channel/UCTuplgOBi6tJIlesIboymGA/community?lb=Ugxfa9pAFcoUbP_kFjx4AaABCQ)
* 
## hasManyThrough
* one has many have many
* [一對多對多 可直接不經過中間的多而取得下層的多](https://laravel.com/docs/7.x/eloquent-relationships#has-many-through)
* sql 語法是使用 inner join
## many to many 過程紀錄
* [官方文件](https://laravel.com/docs/8.x/eloquent-relationships#updating-many-to-many-relationships)
### 狀況
* 夢幻模擬戰的 使用者-英雄-陣營 發現是多對多的狀況
### 參考資料
* [說明如何取得在多對多的中間表的欄位資料](https://laraveldaily.com/pivot-tables-and-many-to-many-relationships/)
* [laraveldaily 影片](https://youtu.be/v6kX9U5xxqQ)
* 
* [示意圖網址](https://www.itsolutionstuff.com/post/laravel-many-to-many-eloquent-relationship-tutorialexample.html)
### 流程簡述
* 建立要建立的關連的table,在此例中 使用者-英雄-陣營 需要5張表
* 除了基本的三張表外,還需要紀錄 使用者-英雄 & 英雄-陣營 關係的兩張表,這種中間表在laravel 是使用==pivot==來稱呼
* 
* 
# 郵件驗證(Email Verification)
* [鐵人賽文章](https://ithelp.ithome.com.tw/articles/10224615)
* 可寄出一封附上認證連結的email
# Validation
* [可用的驗證規則](https://laravel.com/docs/7.x/validation#available-validation-rules)
# Middleware
* [Laravel Middleware 鐵人賽文章](https://ithelp.ithome.com.tw/articles/10208371)
# Observer
* 可在Model::create時自動添加東西
* [示範片段](https://youtu.be/6Woa7mkox48)
* 要在AppServiceProvider.php 中的 boot() 內做添加
* 
# Translation
* [Translations in Laravel](https://medium.com/@rosselli00/translations-in-laravel-b168722ecd91)
# JWT
* Json Web Token
* [HackMD](https://hackmd.io/@8irD0FCGSQqckvMnLpAmzw/SkqRnxqIM?type=view)
* [鐵人賽文章](https://ithelp.ithome.com.tw/articles/10247652)
* [鐵人賽文章](https://ithelp.ithome.com.tw/articles/10268604)
* 優點
- 無狀態的傳輸適用於 RESTful API 的設計
- 不需要 cookie
- 相較於 Session 所消耗的伺服器效能來得小
- 由於為無狀態輸出,減少 CSRF 攻擊的可能性
- 輸出檔案為 JSON,在各類終端皆支援其格式
- 主機端拿到 token 後不需要再去查詢使用者的訊息,適合用於微服務
* 缺點
* Token 被拿走,你的身份就會被盜用,這是 JWT 最大的缺點。
# Laravel Session
* [Session 該注意事項](https://blog.johnsonlu.org/laravel-session/)
* ==Laravel Session== 並不是使用 ==PHP Native Session==
* ==Laravel== 是透過 ==Middleware== 實作 **Session** 機制
# 他人筆記
* [好像是哥布林網站作者](https://hackmd.io/@javck)
* [官方文件重點整理成 Q&A ](https://medium.com/learn-or-die/laravel-the-basics-validation-%E5%AE%98%E6%96%B9%E6%96%87%E4%BB%B6%E5%8E%9F%E5%AD%90%E5%8C%96%E7%BF%BB%E8%AD%AF%E7%AD%86%E8%A8%98-6540bbb190db)
# 好用套件
* [Easily Add SweetAlert into Laravel Application](https://www.youtube.com/watch?v=HKDkI_8OL6I)
# Dependency Injection
* [Laravel Dependency Injection (依赖注入) 概念详解](https://learnku.com/articles/6117/laravel-dependency-injection-dependency-injection-concept-detailed)
# API該有的內容
* [How to build an API (without spending a fortune and going crazy)](https://www.mindk.com/blog/how-to-build-an-api/?fbclid=IwAR1hTkpyj8woVkAfuKA67WH7p5rJAM2kMeR5ihP1HauD-I-gb-8OMHreJJk)
# 152 Laravel Tips About Everything
* [影片](https://youtu.be/AD5QaDlDl_g)
* [文檔](https://github.com/LaravelDaily/laravel-tips)
# helpers
* [官方文檔](https://laravel.com/docs/7.x/helpers)
## 設定
* [在 Laravel 中新增全域函式 (helper)](https://medium.com/@cherub0526/%E5%9C%A8-laravel-%E4%B8%AD%E6%96%B0%E5%A2%9E%E5%85%A8%E5%9F%9F%E5%87%BD%E5%BC%8F-helper-e9c5564af87e)
## 好用helpers
* [abort_if() and abort_unless() – two small helpers](https://laraveldaily.com/abort_if-a-shorter-way-to-end-the-script/)
# 8+版本
* 解決速度問題
* [laravel/octane 試用心得](https://gist.github.com/y2468101216/737d4fcdd0bafc3d7ccd2ca67a1ee80b)
# Collection
* [7.x 可用方法](https://laravel.com/docs/7.x/collections#available-methods)
# Sanctum
* 輕量、功能較少的 JWT
* [參考網站](https://www.oulub.com/zh-TW/Laravel/sanctum)
# Guard
* 可用於避免在後台登入時,前台也登入的窘境
* [參考網站](https://iter01.com/588494.html)
# Sail
* 在 linux 可以用以下指令安裝
1. curl -s https://laravel.build/CUSTOMPROJECTNAME | bash
2. 目前正在 wsl 環境下測試能否正常使用
3. 在 wsl 環境直接使用 1 的指令可以快速安裝 laravel sail
4. 安裝完後(第一次有點久)使用 cd CUSTOMPROJECTNAME && ./vendor/bin/sail up 指令可快速啟動 laravel 專案
# Laradock
## php-worker
* 
* 
* [參考網站](https://ppqqbbdd1111.medium.com/laradock%E7%92%B0%E5%A2%83%E4%B8%8B%E5%BB%BA%E7%AB%8Blaravel-horizon%E4%B8%A6%E5%9C%A8jobs%E8%A3%A1%E9%9D%A2%E4%BD%BF%E7%94%A8docker%E6%8C%87%E4%BB%A4-1-313fdfaa2e10)
# Get Real With Laravel Echo
* [參考影片](https://laracasts.com/series/get-real-with-laravel-echo/episodes/8)
* [深入浅出 Laravel Echo](https://learnku.com/articles/17327)
# Sanctum
* [如何使用的影片](https://youtu.be/MT-GJQIY3EU)
* [chinese setting document](https://www.oulub.com/zh-TW/Laravel/sanctum#spa-authentication)
* [react setting](https://youtu.be/5mLSy4C-1iA)
* [他人操作文字記錄](https://ithelp.ithome.com.tw/m/articles/10253134)
* [20分左右的影片](https://youtu.be/BWNcuB3LQz8)
* [較長的操作影片](https://youtu.be/8Uwn5M6WTe0)
* [github](https://github.com/qirolab/laravel-sanctum-example)
# API 對接
* [參考](https://www.juststeveking.uk/working-with-third-party-services-in-laravel/)
* [官網參考](https://laravel.com/docs/9.x/http-client#making-requests)
# Auth
## 相關實用文章
* [Auth 实现细节](https://learnku.com/docs/laravel-kernel/auth-implementation-details/6933)
* [基于 Laravel Auth 实现自定义接口 API 用户认证详解](https://learnku.com/articles/14136/realization-of-user-interface-authentication-for-user-interface-api-based-on-laravel-auth)
* [laravel-security-authentication-官方文件原子化翻譯筆記](https://medium.com/learn-or-die/laravel-security-authentication-%E5%AE%98%E6%96%B9%E6%96%87%E4%BB%B6%E5%8E%9F%E5%AD%90%E5%8C%96%E7%BF%BB%E8%AD%AF%E7%AD%86%E8%A8%98-ad6314d2bf05)
* [Laravel 學習筆記(19) - 登入驗證 (Authentication)](http://blog.tonycube.com/2015/01/laravel-19-authentication.html)
* [[ Laravel ] 客製 Auth::guard()](https://ithelp.ithome.com.tw/articles/10229123)
* [跟著照做的筆記](https://www.positronx.io/laravel-socialite-login-with-github-example-tutorial/)
## Auth::id()
* 稍微解釋 Auth::id() 的運作過程
* 
# 如何正確在 Laravel 撰寫 PHPUnit 單元測試(Unit Test)
* [網站](https://blog.goodjack.tw/2018/07/laravel-phpunit.html)
# 品質檢測
* [開源程式碼檢測平台:SonarQube](https://ithelp.ithome.com.tw/articles/10215842)
# Swagger API 文件
* [他人筆記](https://hackmd.io/@ann-tsai-27/r1_8d9fDv)
# [[教程] 在不同的 Laravel 应用中提供(服务端)和使用(客户端) OAuth2 认证](https://learnku.com/laravel/t/41648)
# 圖片處理
## 準備
* 
* [參考](https://gist.github.com/jpswade/4592d98e3596da59b7408c076e1c34db)
## 需要的東西 來源二
* 
* [參考](https://www.bbs-rr.com/872.html)
## 實作內容
* 要求 php 要有 gd extension
* 目前完成接收前端傳進來的圖片 resize
* (待修改)圖片儲存的方式是 gd 的方式,不便於檔案移動、刪除
```php
<?php
namespace App\Http\Controllers\Apis;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Image;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class UploadImageController extends Controller
{
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$validated = $request->validate([
'image' => 'required|image',
]);
// 將圖片轉換成 base64
$base64 = file_get_contents(data_get($validated, 'image')->path());
// 將 base64 轉換成 GD class
$image = imagecreatefromstring($base64);
// 取得原始寬高
$originWidth = imagesx($image);
$originHeight = imagesy($image);
// 在此控制 resize 的圖片要多寬
$width = 300;
// 控制高度為原始比例
$height = round($width * $originHeight / $originWidth);
// 使用 imagecreatetruecolor() 函數生成一個新的圖片。另一種寫法 $resizedImage = imagescale($image, $width)
$resizedImage = imagecreatetruecolor($width, $height);
// 使用 imagecopyresampled() 函數將原始圖片縮放到指定大小
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $width, $height, $originWidth, $originHeight);
// 生成新的圖片名稱
$name = uniqid() . '.png';
// 生成圖片的完整路徑
$fullPath = storage_path('app/public/' . $name);
// 使用 imagepng() 函數將縮放後的圖片存儲到本地存儲空間中
imagepng($resizedImage, $fullPath);
// 生成給前端使用的 url
$imaPath = asset('storage/' . $name);
return response()->json(['image' => $imaPath]);
}
}
```
# 爬蟲 未完成
```php
<?php
use App\Http\Controllers\NoteController;
use App\Models\Image;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Symfony\Component\DomCrawler\Crawler;
use Carbon\Carbon;
Route::get('/test', function () {
// 設定 PTT 的網址和板名
$url = 'https://www.ptt.cc/bbs/C_Chat/M.1536493373.A.1D6.html';
$board = 'C_Chat';
// 從 PTT 獲取文章內容
$response = Http::withOptions(['verify' => false])
->get($url);
$html = $response->body();
// 解析 HTML,並取得文章標題、作者、時間和內文
$crawler = new Crawler($html);
return $crawler->text();
$title = $crawler->filter('.article-meta .article-meta-tag')->eq(2)->text();
$author = $crawler->filter('.article-meta .article-meta-value')->eq(0)->text();
$time_str = $crawler->filter('.article-meta .article-meta-value')->eq(3)->text();
$time = Carbon::parse(Str::after($time_str, ' '));
$content = $crawler->filter('#main-content')->text();
$content = Str::before($content, '--');
$result = [
'board' => $board,
'title' => $title,
'author' => $author,
'time' => $time,
'content' => $content
];
return $result;
// // 儲存文章到資料庫
// $post = new Post;
// $post->board = $board;
// $post->title = $title;
// $post->author = $author;
// $post->published_at = $time;
// $post->content = $content;
// $post->save();
});
```
# Socialite
## [Laravel Socialite 簡單的代價](https://medium.com/@Negaihoshi/laravel-socialite-%E7%B0%A1%E5%96%AE%E7%9A%84%E4%BB%A3%E5%83%B9-ff4ab3f406c1)
# websocket
## 大佛十多年前的 ws 鐵人文章
* [client](https://ithelp.ithome.com.tw/articles/10057934)
* [server](https://ithelp.ithome.com.tw/articles/10058046)
## [chat 參考](https://roy.usongrat.tw/article/56)
# CORS
## [講解的挺詳細的文章](https://blog.lishunyang.com/2020/03/course-of-cors.html)
# [Laravel ORM 分表查询](https://minsonlee.github.io/2022/08/laravel-orm-with-sharding)
* 分表的參考資料
# [Laradock Elasticsearch](https://ms0680146.medium.com/laravel-elasticsearch-69a6fc0f3d7)
# [在Laravel项目中使用Elasticsearch](https://learnku.com/articles/48200)
# 好用的片段程式碼
## 在 laravel 中取得 DB 的名稱 & 註解
* 對於前人開的表落落長的狀況,使用整理好的方式呈現需要的資訊
```php
$temp = [];
$tableName = 'p30_entertainment_wallet_stored';
$columnComments = DB::select("SELECT COLUMN_NAME, COLUMN_COMMENT
FROM information_schema.COLUMNS
WHERE TABLE_NAME = ?", [$tableName]);
foreach ($columnComments as $column) {
$columnName = $column->COLUMN_NAME;
$columnComment = $column->COLUMN_COMMENT;
$temp[] = [
$columnName,
$columnComment
];
}
return $temp;
```