路由,控制器,視圖咱們都學了一點了,從這裏開始,咱們先看下如何用migration
建立數據表,而後經過查詢構建器(query builder)和Elequent
去獲取數據。html
咱們以獲取全部的博客的帖子爲例,先寫一條路由:mysql
Route::get('posts', 'PostsController@index');
進入終端生成PostsController控制器類laravel
➜ php artisan make:controller PostsController Controller created successfully.
控制器中PostsController寫上index方法redis
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; class PostsController extends Controller { public function index() { return view('posts.index'); } }
在resources/views/
下 創建posts/index.balde.php的視圖文件,讓其繼承layout.balde.php.sql
@extends('layout') @section('content') <h1>全部的帖子</h1> @stop
開啓php artisan serve
服務, 瀏覽器輸入http://localhost:8000/posts 測試咱們從路由->控制器->視圖 這個流程是能跑通的了。數據庫
下面咱們先進入到config/database.php
文件中,config
文件夾內的文件都是一些配置文件,像數據庫,緩存,郵件,隊列等的配置都在這裏,或者你本身之後新建的配置文件也能夠放在這個文件夾內。 數組
咱們打開database.php,該文件就是返回一個數組:瀏覽器
<?php return [ 'fetch' => PDO::FETCH_CLASS, 'default' => env('DB_CONNECTION', 'mysql'), 'connections' => [ 'sqlite' => [ 'driver' => 'sqlite', 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', ], 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, 'engine' => null, ], 'pgsql' => [ 'driver' => 'pgsql', 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', '5432'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', ], ], 'migrations' => 'migrations', 'redis' => [ 'cluster' => false, 'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => 0, ], ], ];
laravel默認支持了以上幾種數據庫,你但願使用哪一種數據庫,在'default' => env('DB_CONNECTION', 'mysql'),
將env()的函數的第二個參數設置成爲你要使用的,好比說咱們如今用sqlite
緩存
'default' => env('DB_CONNECTION', 'sqlite'),
上面的sqlite對應的配置文件是:
'sqlite' => [ 'driver' => 'sqlite', 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', ],
上面的database_path()是laravel自帶的一個幫助函數,意思是獲取應用數據庫目錄的完整路徑,如個人是:"/usr/local/var/www/Laravel52/database", ok, 咱們在database目錄下創建database.sqlite
文件
傳統方法上,咱們可能會用Sequel Pro寫出原生的sql語句執行,或者使用mysql workbench創建ER圖模型,而後導入到數據庫中,這些方法均可以用,可是在多人開發的時候,維護本地的數據庫以及當添加了新表或者修改了表字段,變的很麻煩,好比你修改了表的字段,這時候你得告訴你的同事,我修改了哪些字段,而Laravel自帶的migration
很好的解決了這個問題,migration
能夠當作是數據庫的版本控制,你不管是添加了表,仍是修改了字段,你的同事只須要執行php artisan migrate
就能夠保證他的數據庫和你同樣了,這對於數據庫的線上部署也很是的方便。這個東西剛開始用的時候會有點不習慣,可是若是你一直堅持用下去,你會發現這的確是個好東西,千萬不要放棄它。
咱們打開database/migrations
目錄,裏面已經存在了兩個migration文件,一個是用來建立用戶users
表的,另外一個是用來建立密碼重置password_resets
表的。咱們打開2014_10_12_000000_create_users_table.php
這個文件:
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('users'); } }
上面的文件包含了up()
和down()
兩個函數,up()
中的內容是建立users表及其字段,而down()
函數是刪除users表。
咱們暫時不用這兩個文件,咱們先刪除它們,而後咱們來建立咱們的posts
表.
咱們到項目的根目錄執行php artisan
, 裏面有一個php artisan make:migration
的命令,其做用就是建立一個migration文件,若是你想看下這個命令的詳細信息和用法,能夠執行 php artisan -h make:migration
,咱們來試一下,進入終端,執行:
➜ php artisan make:migration create_posts_table --create=posts # 輸出下面的信息 Created Migration: 2016_11_14_062612_create_posts_table
對於migration文件的命名,一般若是是建立一個表,那麼咱們能夠寫create_xxx的複數形式_table
,後面跟上--create=表名
, 那若是是添加表的一個字段呢,咱們能夠寫add_字段名_to_表名_table
,後面跟上指定的表名--table=表名
,其實就是寫成一句通順的英文句子,這在團隊開發的時候是很是必要的。
再回頭打開在database/migrations
下建立的2016_11_14_062612_create_posts_table.php
文件,主要看up()
函數:
public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); }); }
這裏是調用了Schema
類的create方法,咱們要添加的表字段都會放在這個方法的閉包函數中,好比咱們的帖子須要一個字符串類型的標題,那麼只要這麼寫:
$table->string('title');
經過這句代碼的字面意思,你們就可以看懂,若是還想添加別的類型,查詢下laravel文檔
這裏咱們還要來看下$table->timestamps();
這句話,這句話能夠替咱們的表自動生成created_at
和updated_at
字段,而且laravel會自動維護它,好比咱們建立一篇帖子,咱們不用手動的寫明建立時間,laravel會自動的幫咱們填上建立時間,這很是有用,除了一些字典表外,別的表我建議你們均可以保留它。
好了,咱們在編輯下2016_11_14_062612_create_posts_table.php
的up()函數,最終以下:
public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('content')->nullable(); $table->timestamps(); }); }
migration文件咱們建立好了,下面咱們若是將該表生成到數據庫中呢,在終端進入項目根目錄,執行php artisan migrate
便可。
php artisan migrate # 輸出下面信息 Migration table created successfully. Migrated: 2016_11_14_062612_create_posts_table
注意:如今咱們尚未講到.env
文件的使用,你們執行上面的命令前,先把根目錄下的.env
文件中的下面代碼註釋掉,用英文的#註釋:
# DB_CONNECTION=mysql # DB_HOST=127.0.0.1 # DB_PORT=3306 # DB_DATABASE=homestead # DB_USERNAME=homestead # DB_PASSWORD=secret
下面咱們寫一些測試代碼看看數據庫的使用,對於一些簡單的測試代碼,咱們可使用php artisan tinker
工具,在終端進入這個工具,咱們能夠直接編寫咱們的php代碼,如:
和上面的方法同樣,你們用tinker
工具,在插入一條數據,而後經過代碼DB::table('posts')->get();
查看咱們如今posts
表中的全部數據以下:
=> [ {#626 +"id": "1", +"title": "My New Post Title", +"content": "new post content", +"created_at": "2016-11-14 07:22:32", +"updated_at": "2016-11-14 07:22:32", }, {#627 +"id": "2", +"title": "My Second Post Title", +"content": "Second post content", +"created_at": "2016-11-14 07:27:50", +"updated_at": "2016-11-14 07:27:50", },
測試沒有問題後,咱們將上面的代碼寫到咱們的控制器類中去,打開PagesController類,更改下index()函數以下:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use DB; // 使用DB命名空間 class PostsController extends Controller { public function index() { // 這裏使用了DB類,頭部須要引入DB的命名空間 $posts = DB::table('posts')->get(); return view('posts.index', compact('posts')); } }
下面打開posts/index.balde.php
視圖文件,修改以下:
@extends('layout') @section('content') <h1>全部的帖子</h1> @foreach ($posts as $post) <h2>{{ $post->title }}</h2> <p>{{ $post->content }}</p> @endforeach @stop
開啓serve
, 瀏覽器http://localhost:8000/posts 就能正確顯示了。
Laravel提供了另外一個很是強大的ORM Elequent
, 若是是第一次接觸Elequent
,不少人會去查一下它的意思是什麼,查查能夠,可是不用去糾結,它就是一個名字而已,就像artisan
也就是個名字,咱們不用過多的關心它的意思,咱們只要知道它能幹什麼就好了,用的多了,之後聽到這個詞,你就會知道它是個ORM,會聯想到它的一些用法和它的強大。咱們先簡單的看看這個Elequent
, 還在終端,在項目的根目錄下,咱們執行:
➜ php artisan make:model Post Model created successfully.
注意:模型 Model名通常都是表名的單數形式,好比表名叫posts, Model名則是Post, 表名叫users, 則Model名就是User, 這樣寫的好處是,Laravel能經過Model名自動找到對應的表名。
咱們在app/
目錄下打開,Post.php文件:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { // }
ok, 如今更改下PagesController.php中的代碼:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Post; class PostsController extends Controller { public function index() { $posts = Post::all(); return view('posts.index', compact('posts')); } }
在瀏覽器在訪問下,仍是獲得相同的輸出。是否是代碼更清晰了。
咱們在來作一個小功能,咱們給帖子列表上的每一個帖子標題添加一個連接,讓其跳轉到具體的帖子頁面,咱們的流程固然仍是,路由-》控制器-》視圖層
route.php添加一條路由:
Route::get('posts/{post}', 'PostsController@show');
一般咱們訪問一個帖子的路由通常是:posts/1
相似這種,咱們上面的{post}
,接受的其實就是帖子的id
, 咱們這裏爲何寫{post},而不寫{id}呢? 這個問題先放放,咱們接着往下走。
咱們而後進入PostsController.php, 編寫show()函數,以下:
// 這裏的$post變量接受路由{post}傳遞來的數值 public function show($post) { return $post; }
咱們訪問:http://localhost:8000/posts/1
, 頁面返回的數據是1
.咱們要獲取帖子id爲1的數據呢,咱們再改下show()函數:
public function show($postId) { $post = Post::find($postId); return $post; }
咱們訪問:http://localhost:8000/posts/1
上面代碼的修改,咱們獲得了咱們想要的數據,不過這樣作,代碼有點多餘,咱們寫代碼在易讀的基礎上固然是越少越好,Laravel提供了路由模型綁定的功能(其實就是依賴注入),咱們再來更改下show()函數:
public function show(Post $post) { return $post; }
咱們將$post指名爲Post的一個對象,當laravel執行到show()函數時,會自動實例話$post對象,這時候咱們返回$post,就能夠獲得一個具體的對象了。
咱們試下: http://localhost:8000/posts/2
注意:使用上面的路由模型綁定功能,必定要注意路由中的{post}
與對應控制器中的$post
這兩個變量名必定要如出一轍,若是你路由中的變量寫成{postId}
, 而控制器的中對應的變量使用$post
, 那麼路由模型綁定就不會成功了。
上面的show()函數對應的show.balde.php咱們沒有寫,這個你們本身去補上吧!