7. 从数据库获取数据- 从零开始学Laravel

从零开始学Laravel教程目录php

路由,控制器,视图咱们都学了一点了,从这里开始,咱们先看下如何用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_atupdated_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代码,如:

php artisan tinker

和上面的方法同样,你们用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咱们没有写,这个你们本身去补上吧!

相关文章
相关标签/搜索