# Laravel 筆記 ###### tags: `Laravel` `PHP` `學習紀錄` `筆記` `note` # 目錄 [TOC] # 架構 ## IOC * ![](https://i.imgur.com/dahVFNS.png) ## DI * ![](https://i.imgur.com/UqvbmQI.png) # 權限相關 * [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) * ![](https://i.imgur.com/QGTjcgx.png) ## 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改成如下圖 * ![](https://i.imgur.com/cyANrFW.png) * send的動作改成queue or later * ![](https://i.imgur.com/08Qevwp.png) * 在.env加入下圖的資訊 * ![](https://i.imgur.com/9bMxI1p.png) * 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) * ![](https://i.imgur.com/EbCp0TQ.png) ## 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://i.imgur.com/vCVa43Z.png) * [示意圖網址](https://www.itsolutionstuff.com/post/laravel-many-to-many-eloquent-relationship-tutorialexample.html) ### 流程簡述 * 建立要建立的關連的table,在此例中 使用者-英雄-陣營 需要5張表 * 除了基本的三張表外,還需要紀錄 使用者-英雄 & 英雄-陣營 關係的兩張表,這種中間表在laravel 是使用==pivot==來稱呼 * ![關連設定圖](https://i.imgur.com/7aFwZu7.png) * ![pivot table 新增、讀取的方法圖](https://i.imgur.com/20KnLMs.png) # 郵件驗證(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() 內做添加 * ![](https://i.imgur.com/BAUTksl.png) # 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://i.imgur.com/1z7Jyut.png) * ![](https://i.imgur.com/Et8sxtM.png) * [參考網站](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() 的運作過程 * ![](https://i.imgur.com/81vYTkC.png) # 如何正確在 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://i.imgur.com/vlyn864.png) * [參考](https://gist.github.com/jpswade/4592d98e3596da59b7408c076e1c34db) ## 需要的東西 來源二 * ![](https://i.imgur.com/m9A94EM.png) * [參考](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; ```