事前注意事項
今回はXAMPPを使うので、インストールするパスはc:\xampp\htdocsとする。
ゆえに以下コードで>になっているものは、C:\xampp\htdocs>という意味。
コードの上は公式、下が実際に入力したコードとする。
Laravelのインストール
>composer create-project laravel/laravel [プロジェクト名] [--prefer-dist] >composer create-project laravel/laravel laravelapp --prefer-dist
- 実行したカレントディレクトリにプロジェクト名のフォルダが作られ、その中にLaravel一式が入れられる。
- –prefer-distは現行バージョンを取得する意味だとか聞いたことある
- プロジェクト名を付けなければlaravelになった。laravel/laravelにしたから?
Laravelのバージョン
Laravelがインストールされているディレクトリで実行すること。
> php artisan -V
データベース作成
データベースは作っておく。データベース名は「xampp」にする。
CREATE TABLE people( id integer primary key auto_increment, name text not null, mail text, age integer );
ダミーデータを入力する
insert into people values(1,'yoshio','yoshio@edogawa.com',46); insert into people values(2,'goro','goro@edogawa.com',40); insert into people values(3,'hanakuso','hanakuso@edogawa.com',49);
権限付与
grant all on データベース名.対象 to ユーザ名@ホスト名 identified by 'パスワード'; grant all on xampp.* to dbuser@localhost identified by 'dbuser';
データベース接続
.envファイルを編集する。
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=xampp DB_USERNAME=dbuser DB_PASSWORD=dbuser
コントローラの作成
> php artisan make:controller コントローラー名 > php artisan make:controller HelloController
これでLaravelapp/app/Http/Controllers直下に作成される。
ルーティングの設定
routes/web.php内に記入
Route::get('パス','コントローラー@アクション'); Route::get('/hello','HelloController@index');
コントローラーからとりあえずDBにアクセス
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class HelloController extends Controller { public function index() { $items = DB::select('select * from people'); var_dump($items); } }
var_dumpの結果
array(3) { [0]=> object(stdClass)#1370 (4) { ["id"]=> int(1) ["name"]=> string(6) "yoshio" ["mail"]=> string(18) "yoshio@edogawa.com" ["age"]=> int(46) } [1]=> object(stdClass)#1371 (4) { ["id"]=> int(2) ["name"]=> string(4) "goro" ["mail"]=> string(16) "goro@edogawa.com" ["age"]=> int(40) } [2]=> object(stdClass)#1372 (4) { ["id"]=> int(3) ["name"]=> string(8) "hanakuso" ["mail"]=> string(20) "hanakuso@edogawa.com" ["age"]=> int(49) } }
コントローラーからViewへ受け渡し
連想配列として受け渡す。第二引数は配列にすること。
return view('フォルダ.ファイル',配列);
コントローラはこういう形。
class HelloController extends Controller { public function index() { $items = DB::select('select * from people'); return view('hello.index',[ 'items' => $items, ]); } }
View側はこういう形。resources/viewsディレクトリにhelloディレクトリを作りそこに置く。ファイル名はindex.blade.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>index</title> </head> <body> <h1>Index</h1> <table border="1"> <tr> <th>ID</th> <th>NAME</th> <th>MAIL</th> <th>AGE</th> </tr> @foreach($items as $item) <tr> <td>{{$item->id}}</td> <td>{{$item->name}}</td> <td>{{$item->mail}}</td> <td>{{$item->age}}</td> </tr> @endforeach </table> </body> </html>
結果はこんな感じ。
新規作成を作る
index.blade.phpに追記
</table>の後ろに追記
<a href="hello/add"><button>新規登録</button></a>
こんな感じになる。
web.phpに追記する
新規登録のボタンを押したルーティングを追加する。
Route::get('/hello/add','HelloController@add');
HelloController.phpに追記する
function indexの下に追記する
public function add() { return view('hello.add'); }
ちゃんとコントローラークラスの中に入るように注意。
add.blade.phpを作成する
置き場所はindex.blade.phpと同じ場所。resources/views/hello直下。
フォームのアクションをhello/createにして、createメソッドを実行するようにする。
postのときはcsrf_field()を入れなければ403エラーになので必ず入れること。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>index</title> </head> <body> <h1>新規登録画面</h1> <form action="/hello/add" method="post"> {{csrf_field()}} <p> <label for="name">名前</label> <input id="name" type="text" name="name"> </p> <p> <label for="mail">メール</label> <input id="mail" type="email" name="mail"> </p> <p> <label for="age">年齢</label> <input id="age" type="text" name="age"> </p> <input type="submit" value="登録する"> </form> </body> </html>
新規登録のボタンを押下してadd.blade.phpにアクセスするとこんな感じ
web.phpに追記する
下記を追加する。
Route::post('/hello/add','HelloController@create');
すると、こうなる。
Route::get('/hello/add','HelloController@add'); Route::post('/hello/add','HelloController@create');
パスは同じaddでいい。
getでアクセスした場合は、addメソッドでコントローラーに書かれたadd.blade.phpを表示する。
postでアクセスした場合は、createメソッドでコントローラーに書かれたDB::insertを実行する。
getは別画面からこの画面にアクセス。postはこの画面からこの画面にアクセス。
HelloControllerにcreateメソッドを追加する
入力した値を受け継いで、データベースに登録する処理です。
public function create(Request $request) { $param = [ 'name' => $request->name, 'mail' => $request->mail, 'age' => $request->age, ]; DB::insert('insert into people(name,mail,age) values(:name,:mail,:age)',$param); return redirect('hello'); }
データベースに登録した後はindex表示のhelloにredirectする。
viewとredirectの違いは、
- viewは引数に明記されたviewテンプレートを呼び出す
- redirectはweb.phpのルートにアクセスしたことになる。
更新処理を作る
indexで一覧表示されたものをクリックすると更新画面に飛んで、打ち替えたあと更新ボタンでデータベースを更新するものを作ります。
web.phpに追加する
今回はgetとpostを一気に書きます。
Route::get('/hello/edit','HelloController@edit'); Route::post('/hello/edit','HelloController@update');
getは更新用の画面を表示する、postは更新ボタンでDBを更新する用です。
さっきとまったく同じです。
index.blade.phpに/hello/editへのリンクを追記する
IDにリンクをつけクリックできるようにします。
<tr> <td><a href="hello/edit?id={{$item->id}}">{{$item->id}}</a></td> <td>{{$item->name}}</td> <td>{{$item->mail}}</td> <td>{{$item->age}}</td> </tr>
HelloControllerにeditメソッドを追加する
limit 1にして1レコードしか渡さないようにする。
public function edit(Request $request) { $param = [ 'id' => $request->id ]; $items = DB::select('select * from people where id = :id limit 1',$param); return view('hello.edit',[ 'items' => $items, ]); }
正式には下記のようにするらしい。
return view('hello.edit',[ 'form' => $items[0], ]);
limit 1などせずに、view側で{{$form->name}}などとする。
$items配列の[0]だけを渡して、view側で1件だけを処理している。
もし上記のように’items’ => $itemsで渡すと受け渡る配列は2次配列になるので、@foreachで処理しなければならない。
今回は@foreachで処理する。
これで処理するのはスマートではないのはわかるが、正直のところ‘form’ => $items[0]とする意味が理解できないので今回はこれは使わない。
edit.blade.phpを作成する
基本的にaddとあまり変わらない。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>edit</title> </head> <body> <h1>既存更新画面</h1> <form action="/hello/edit" method="post"> {{csrf_field()}} @foreach($items as $item) <input type="hidden name="id" value="{{$item->id}}"> <p> <label for="name">名前</label> <input id="name" type="text" name="name" value="{{$item->name}}"> </p> <p> <label for="mail">メール</label> <input id="mail" type="email" name="mail" value="{{$item->mail}}"> </p> <p> <label for="age">年齢</label> <input id="age" type="text" name="age" value="{{$item->age}}"> </p> @endforeach <input type="submit" value="更新する"> </form> </body> </html>
画面はこうなる。
更新ボタンを押すと/hello/editへpostして、その先でDBを更新するメソッドが動く。
IDは主キーにより変更できないので、画面上にはIDの枠はない。
しかしDBを更新するキーとして更新プログラム側にIDは受け渡してあげないといけない。
そのため<input type=”hidden”>を使って非表示の値を作ってあげる。
HelloControllerに更新処理updateを追加する
updateするに必要なすべてを$requestで受け取り、$param配列に入れてSQL文に渡す。
終わったらredirectでindexのhelloに戻ってくる。
public function update(Request $request) { $param = [ 'id' => $request->id, 'name' => $request->name, 'mail' => $request->mail, 'age' => $request->age, ]; DB::update('update people set name = :name, mail = :mail, age = :age where id = :id',$param); return redirect('hello'); }
削除処理を作る
更新処理で作ったindex一覧のリンクeditのview内に削除ボタンを設ければいいと思う。
edit.blade.phpに追加する
更新画面の中の</form>の後に削除ボタンを設ける。
</form> @foreach($items as $item) <a href="/hello/del?id={{$item->id}}"><button>削除する</button></a> @endforeach
これも微妙な書き方だと思う。
前提として、削除するなら削除メソッド側にIDを渡してあげないといけない。
それをクエリー文字列で渡している。
クエリー文字列とは?id=というやつ。
下記のようにすれば
<input type="submit" value="更新する"> <a href="/hello/del?id={{$item->id}}"><button>削除する</button></a> @endforeach </form>
更新ボタンを押しても、aとbuttonで作られた削除ボタンを押しても、formのactionが実行されてしまう。
なので削除ボタンを押しても、/hello/editの方に飛ぶ。
画面はこんな感じ。こうなってくると既存更新ではなく、更新削除画面の方がいいのかもしれない。
web.phpに追加する
上記で削除ボタンを押したら/hello/delに飛ぶようにしている。
Route::get('/hello/del','HelloController@delete');
HelloControllerにdeleteメソッドを追加する
クエリ文字列はRequestで受け取れるので他と同様。
DBクラスのdeleteメソッドも他と同じような感じ。
public function delete(Request $request) { $param = [ 'id' => $request->id, ]; DB::delete('delete from people where id = :id',$param); return redirect('hello'); }
以上。自分のレベルで自力で作ればこうなった。
他にいい書き方があるはずなので、これから探す予定。
コメント