Laravel備忘

自分用備忘も兼ねた内容です。
Laravelのバージョンは10（10.23.1）となります。

## プロジェクトの作成
Composerインストール
Node.jsインストール
PowerShellなどで、プロジェクトを作成したいフォルダに移動後
```DOS 
D:\>cd laravel
composer create-project laravel/laravel sample-project --prefer-dist
```
ついでにNode.jsのモジュールもインストール
```DOS 
npm install
```
## 開発用組み込みサーバーを起動
PowerShellなどのコンソールで、プロジェクトを作成したいフォルダに移動後 php artisan serve
http://127.0.0.1:8000/ にアクセス
```DOS
D:\>cd laravel
D:\laravel> cd sample
D:\laravel\sample> php artisan serve
```
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635275/becde724-ae12-dd82-aed7-b50134909a52.png)

## マイグレーション　DBの自動構築
プロジェクト内の　database > migrations内のPHPファイルに基づき作成
コンソールでプロジェクトのフォルダに移動後
```cmd
php artisan migrate

//構築しなおす場合（データベースの中身は空に）
php artisan migrate:refresh
```
## コントローラーの作成
コンソールでプロジェクトのフォルダに移動後
```cmd
php artisan make:controller SampleController
```

## モデルの作成
コンソールでプロジェクトのフォルダに移動後
```cmd
php artisan make:model Sample
```
## 基本
```php
//ルート部分
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\コントローラー名;

Route::get('/',[コントローラー名::class, 'コントローラ内のfunction名']);
Route::post('/user', [UserController::class, 'index']);
Route::match(['get', 'post'], [UserController::class, 'index']); //get post 両方に対応
Route::redirect('/here', '/there'); //リダイレクトさせる場合
Route::view('/welcome', 'welcome'); //コントローラーを経由せずViewを表示
```
```php
//コントローラ部分
namespace App\Http\Controllers;

use App\Models\モデル名;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;

class コントローラ名 extends Controller
{
    public function function名(Request $request)
    {
        $クラス名 = new モデル名();
        $users = $クラス名 -> メソッド名;
        
        return view('userindex', ['users' => $users]);
    }
    
    public function function名(Request $request)
    {
        //リダイレクトする場合
        return redirect('リダイレクト先');
    }
}
```
```php
//モデル部分
namespace App\Models;

use Illuminate\Database\Eloquent\Models;
use Illuminate\Database\Eloquent\Builder;

class クラス名 extends Model
{
    public $変数 = ;

    public function ファンクション名(引数)
    {
        return 変数;
    }
}
```
## GET POST内容の受け取り
```php
public funtion ファンクション名(Request $request)
{
    $変数 = $request -> input('フォーム内で指定した名前');
}
```
## SESSION セッションの取り扱い
```php
public funtion ファンクション名(Request $request)
{
    //セッションの内容を変数に入れる
    if (!empty($request -> session() -> get('セッション名')))
    {
        $変数 = $request -> session() -> get('セッション名');
    }

    //セッションに入れる
    $request -> session() -> put('セッション名',内容);
}
```
## DB操作　クエリビルダ
```php
use Illuminate\Support\Facades\DB;

$items = DB::table('テーブル名') -> SELECT('利用するカラム名たち')
    -> WHERE('カラム名','内容')
    -> WHERE('条件を増やす場合のカラム名','内容')
    -> get();

//一件だけ抽出
$items = DB::table('テーブル名') -> WHERE('カラム名','内容') -> first();

//一件INSERT
$insert_naiyo = ['namae'=>'yamada' ,'age'=>'40'];
DB::table('テーブル名') -> insert
([
    $insert_naiyo
]);

//WHEREを満たすレコードをUPDATE
$update_naiyo = ['age' => '40','address' => 'tokyo'];
DB::table('テーブル名') -> WHERE('カラム名','内容') -> update($update_naiyo);

//WHEREを満たすレコードをDELETE
DB::table('テーブル名') -> WHERE('カラム名','内容') -> delete();
```
## データベース INNER JOIN
```PHP
$users = DB::table('users')
            ->join('contacts', 'users.id', '=', 'contacts.user_id')
            ->join('orders', 'users.id', '=', 'orders.user_id')
            ->select('users.*', 'contacts.phone', 'orders.price')
            ->get();
```
## データベースのUNION
```PHP
$first = DB::table('users')
            ->whereNull('first_name');

$users = DB::table('users')
            ->whereNull('last_name')
            ->union($first)
            ->get();
```
## 素のSQLを実行
```PHP
$users = DB::table('users')
             ->select(DB::raw('count(*) as user_count, status'))
             ->where('status', '<>', 1)
             ->groupBy('status')
             ->get();
             
//あるいはselectRawを使う
$orders = DB::table('orders')
                ->selectRaw('price * ? as price_with_tax', [1.0825])
                ->get();
```

## Laravelでバルクアップデート upsertの利用

```php
//更新内容の配列を用意　以下は例　
$update_naiyo = [];
foreach($a as $v){
	//データ一件分を連想配列で用意
	$data['mem_cd']  = $v['mem_cd'];
	$data['namae']   = $v['namae'];
	$data['address'] = $v['address'];
	$data['tel']     = $v['tel'];

	//更新したいデータ一件をに追加し、配列をつくっていく
	$update_naiyo[] = $data;
	$data = [];//空にする
}

//バルクアップデート（upsert）
DB::table(table名) -> upsert(
	$update_naiyo,
	['mem_cd','namae'],
	['address','tel']	
);
//upsert部分の二つ目の引数は、条件 WHERE=の項目を意味し、すべて一致すればUPDATE、なければINSERTされる。
//三つ目の引数が、更新あるいは新規作成されるカラム
```

## Laravelでバリデーション　整数　文字列 
```php
$validated = $request->validate([
    'content1' => ['integer','min:1','max:9'],  //整数であり、1以上、9以下か
    'content2' => ['string'], //文字列か
]);
```

## バリデーションエラー表示部分（blade内に） 
```php
//略
@if ($errors->any())
    <div>
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif 
```
## テストの実行
コンソールでプロジェクトのフォルダに移動後
```Bash
php artisan test
```
→testフォルダ内のテストがすべて実行され、結果が表示される
```php:Models\Sample.php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Sample extends Model
{
    use HasFactory;

    public function add_a_and_b ($a,$b)
    {
        return $a + $b;
    }
}
```
```php:tests\Feature\Test.php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\Sample;

class Test extends TestCase
{
    public function test_sample1(): void
    {
        $response = $this->get('/');
        $response->assertStatus(200);
    }
    public function test_add_a_and_b(): void
    {
        $sample = new Sample;
        $this -> assertSame ( 6 , $sample -> add_a_and_b ( 1 ,5));
    }
}
```
の場合
```
PASS  Tests\Feature\Test
✓ sample1      0.01s  
✓ add a and b  0.01s  
```
と表示される

## seeder 適当なデータをデータベースに自動作成

```php:database > factories > UseFactory.php
namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
 */
class UserFactory extends Factory
{

    protected static ?string $password;

    public function definition(): array
    {
        return [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => static::$password ??= Hash::make('password'),
            'remember_token' => Str::random(10),
        ];
    }

    public function unverified(): static
    {
        return $this->state(fn (array $attributes) => [
            'email_verified_at' => null,
        ]);
    }
}
```
```php:database > seeders > DatabaseSeeder.php
namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        \App\Models\User::factory(10)->create(); //10件のデータを全自動作成

        \App\Models\User::factory()->create
        ([
             'name' => Str::random(10),
             'email' => Str::random(10).'@gmail.com',
        ]);
        //1件を、半手動で
    }
}
```
コンソールで
```
php artisan DB:seed
```