SQLを直接実行

値を返さなくてもよいSQLの実行


	\DB::statement('DELETE FROM jobs'); // 全データを削除
	\DB::statement('ALTER TABLE jobs auto_increment = 1'); // idの自動インクリメントをリセットする
	

SELECT系のSQLを直接実行 | INSERT, UPDATE, DELETE

$data = \DB::select('select * from nekos where id= 4');
レスポンスはエンティティの配列となる。

SELECT系のSQLを安全に実行

$data = \DB::select('select * from nekos where id = :id', ['id' => 4]);
この方法は値はサニタイズされるようなのでセーフティなコーディングと言える。

selectメソッドは一応どんなSQLでも実行可能。

selectメソッドはSELECT文専用ではない。UPDATEなど他のSQLも実行できる。 つまり、selectメソッドは生のSQLを何でも実行できるメソッドである。 ちなみにUPDATEなどのSQLを実行したときのレスポンスは空配列「[]」になる。
一応、下記のような使い方も可能である。
$data = \DB::select("UPDATE `nekos` SET `neko_val`=2000,`neko_name`='シャム猫' WHERE id=4");

INSERTを直接実行

$res = \DB::insert("INSERT INTO `nekos`(`neko_val`, `neko_name`) VALUES (1001, 'ホンハブ')");
レスポンスはbool型のtrue。

INSERTを安全に実行

$res = \DB::insert("INSERT INTO `nekos`(`neko_val`, `neko_name`) VALUES (?, ?)", [1002, 'ヒメハブ']);

UPDATEを直接実行

$res = \DB::update("UPDATE `nekos` SET `neko_val`=100,`neko_name`='黒猫' WHERE id=4");

UPDATEを安全に実行

$res = \DB::update("UPDATE `nekos` SET `neko_val`=?,`neko_name`=? WHERE id=?", [101,'白猫',5]);

DELETE

$res = \DB::delete('delete from nekos where neko_name = ?', ['マンチカン']);

レスポンスを必要としないSQLの実行

$res = \DB::statement('ALTER TABLE nekos auto_increment = 1;');
レスポンスはbool型のtrueが返ってくる。


Laravelのトランザクション


		try {
			\DB::beginTransaction();
			
			// データベース操作...
			
			\DB::commit();
		} catch (\Exception $e) {
			\DB::rollback();
			
		}
	

\DB::beginTransaction();
\DB::commit();
\DB::rollback();

ユーザー情報を取得する | ユーザーID,ユーザー名,メールアドレスなどを取得する


	if(\Auth::id()){// idは未ログインである場合、nullになる。
		$user_id = \Auth::id(); // ユーザーID(番号)
		$user_name = \Auth::user()->name; // ユーザー名
		$user_email = \Auth::user()->email; // メールアドレス
		$user_password_hash = \Auth::user()->password; // ハッシュ化(解読不可)されたパスワード
		
	}
	

ログイン画面を作成

Laravel6および7でのログイン画面作成方法。
Windows10環境、Windows for bashを利用

  1. composerコマンドをbashで使えるようにする。
    参考→Windows環境でcomposerコマンドを使えるようにする【2020年】
  2. 下記のコマンドを実行する。(動くまで時間がかかる)
    $ composer require laravel/ui 2.*
  3. 下記のコマンドを実行し、ログイン画面関連のファイルを自動作成する。
    php artisan ui vue --auth
  4. URL「~ルート~/public/home」にアクセスするとログイン画面になる。
    例:
    http://localhost/animal/public/
  5. 初期状態のwelcomeページにログイン関連のリンクが表示されるようになっている。

スタイルの適用

下記の手順でBootstrapを適用するとスタイルが適用されたログイン画面になる。
Laravel Mix | vue.js, jQuery, Bootstrapなどを一つのapp.jsおよびapp.cssにまとめ、さらに圧縮する


注意

Laravel7では「php artisan make:auth」コマンドが使えなくなっている。



Laravel Mix | vue.js, jQuery, Bootstrapなどを一つのapp.jsおよびapp.cssにまとめ、さらに圧縮する

※コマンドはGit for windowsのGit Bashにて実行。
  1. 事前にnodeコマンドとnpmコマンドを使えるようにしておく。
  2. cdコマンドでプロジェクトのルートディレクトリまで移動する。
  3. 下記のコマンドでBootstrapの追加設定を行う。
    php artisan ui bootstrap
  4. 同様にVue.jsの追加設定を行う。(Vue.jsの最新が追加設定されるようである)。
    php artisan ui vue
  5. ルートディレクトリにpackage-lock.jsonが存在するなら削除
  6. npmでパッケージをインストールする。
    npm install
  7. パッケージをapp.js、app.cssにまとめる。
    npm run dev
    bootstrap.jsやvue.js, jqueryなど一つにまとめる。その一つにまとめたファイルがapp.jsである。app.cssも同様に各種CSSパッケージを一つにまとめたもの。
  8. app.js, app.cssを圧縮する
    npm run production

    圧縮前のapp.js

    圧縮後のapp.js
  9. ビューファイル(bladeファイル)にてapp.jsとapp.cssを読み込み bladeファイルのheader要素内に下記を追記する。
    
    				<script src="{{ asset('js/app.js') }}" defer></script>
    				<script src="{{ asset('/js/test.js') }}"></script>
    				
  10. 以上で終わり
    サンプル:Bootstarapが効いているか確認

DB: テーブル名の別名をtableメソッドに記述する方法 nekos AS Neko


		$query = ¥DB::table('nekos AS Neko')->
		select('id', 'neko_name as cat', 'neko_val', 'neko_date');
		dump($query->toSql()); // →"select `id`, `neko_name` as `cat`, `neko_val`, `neko_date` from `nekos` as `Neko`"
		
		$data = $query->get();
		dump($data);
	

Laravel7+jQuery「$ is not defined」のエラー

jQuery is not defined
JS読み込みとCSS読み込みが逆になると「$ is not defined」のエラーが発生するようだ。

「$ is not defined」のエラーが出る例

	<link href="{{ asset('/css/app.css') }}" rel="stylesheet">
	<script src="{{ asset('/js/app.js') }}" defer></script>
	

正しい方法

	<script src="{{ asset('/js/app.js') }}" defer></script>
	<link href="{{ asset('/css/app.css') }}" rel="stylesheet">
	

ビュー(Bladeテンプレート)に別のテンプレートを埋め込む | @include

(ルート)/resources/views/neko/index.blade.php

	<?php $test1="Hello big fish!";?>
	@include('layouts/common/test')
	

(ルート)/resources/views/layouts/common/test.blade.php

	テンプレートの埋め込みテスト<br>
	<?php echo $test1;?>
	

画面表示→http://localhost/(ルート)/public/neko
	テンプレートの埋め込みテスト
	Hello big fish!
	

テンプレートに引数追加することもできる

@include('demo.edit_form', ['neko'=>'ロイヤルアナロスタン'])
demo/edit_form(ルートresources/views/layouts/demo/edit_form.php)
猫の名前は?→<?php echo $neko; ?>


LaravelのAJAX

注意

画面表示直後に行う非同期通信に注意してください。
画面表示直後に非同期通信を行う仕組みにした場合、何回かブラウザリロードを繰り返していると「500 SERVER ERROR」、または「419 PAGE EXPIRED」エラーが時々発生します。 (エラーが起きない場合もあります。) 「500 SERVER ERROR」は暗号化キーのエラー、「419 PAGE EXPIRED」はCSRFトークンのエラーのようですが、どちらもきちんと設定しても発生します。 原因はセッションまわりのようです。これを回避にするにはsetTimeout関数などを用いてい1秒後に実行するなど、ある程度時間差を設けるのが良いです。

ビュー側(ブレードテンプレート/html)

	<input type="button" value="test_ajax" onclick="test_ajax()" />
	<input type="hidden" id="csrf_token" value="{{ csrf_token() }}" >
	<div id="err" class="text-danger" ></div>
	

JS側

フロント側
function test_ajax(){

	console.log('test_ajax');
	let fd = new FormData(); // 送信フォームデータ
	let data = {id:123, name:'古いねこ', age:15}; // バックエンド側に送信するデータ
	let json = JSON.stringify(data);
	fd.append( "key1", json );
	
	// CSRFトークンを送信フォームデータにセットする。
	let token = jQuery('#csrf_token').val();
	fd.append( "_token", token );
	
	jQuery.ajax({
		type: "post",
		url: 'neko/test_ajax_be',
		data: fd,
		cache: false,
		dataType: "text",
		processData: false,
		contentType: false,

	}).done((str_json, status, xhr) => {
	
		// 419エラーならトークンの期限切れの可能性のためリロードする(トークンの期限は2時間)
		if(xhr.status == 419)  location.reload(true);

		let res = null;
		try{
			res =jQuery.parseJSON(str_json); //パース
		}catch(e){
			alert('バックエンド側のエラー');
			console.log(str_json);
			$('#err').html(str_json);
			return;
		}
		
		if(res.err_msg == 'logout') location.reload(true); // すでにログアウトになっているならブラウザをリロードする。
		if(res.err_msg) {
			console.log(res.err_msg);//■■■□□□■■■□□□
			return;
		}
			
		console.log(res);//■■■□□□■■■□□□

	}).fail((xhr, status, errorThrown) => {
	
		// 419エラーならトークンの期限切れの可能性のためリロードする(トークンの期限は2時間)
		if(xhr.status == 419)  location.reload(true);
		alert('通信エラー');
		console.log(status);
		console.log(xhr.responseText);
		$('#err').html(xhr.responseText);
		
	});
}
	

PHP側

バックエンド、つまりAjaxの受信側。通常のコントローラクラスにて処理を記述。
	~ 略 ~
class NekoController
{
	~ 略 ~

	public function testAjax(){
		
		// すでにログアウトになったらlogoutであることをフロントエンド側に知らせる。
		if(\Auth::id() == null) return json_encode(['err_msg'=>'logout']);
		
		$json=$_POST['key1'];
		$res = json_decode($json,true);
 		$res['name'] = '新しい猫';
 		$res['age'] = 1;
 		$res['date'] = '2020-7-23';
		
 		$json = json_encode($res, JSON_HEX_TAG | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_HEX_APOS);

		return $json;
	}
	
	~ 略 ~
	

ルートパス


	~ 略 ~
	Route::post('neko/test_ajax_be', 'NekoController@testAjax');
	~ 略 ~
	

画面側の出力例




Larevelの日付更新エラー SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect date value: ...

日付系フィールドを含むデータをDB保存する際、以下のようなエラーが生じることがある。
SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect date value: ...

型を厳密にしている設定が原因と思われる。

解決方法

ルート/config/database.phpを開きstrictをtrueからfalseに変更する。
    'connections' => [
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => false,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],