首页 > PHP编程 > Laravel 5.1 教程1 – 10分钟写一个Blog

Laravel 5.1 教程1 – 10分钟写一个Blog

2015年9月27日

Laravel 5.1 教程1 – 10分钟写一个Blog

http://www.zhangxihai.cn/archives/120

原文地址:

http://laravelcoding.com/blog/laravel-5-beauty-the-10-minute-blog

在这篇文章中,我们将创建一个Blog,并完成数据测试。利用强大的Laravel5.1可以在不到10分钟内创建一个Blog。没有花哨的功能,也没有Blog管理后台,因为我们希望不用10分钟就能创建Blog。

章节目录

  • 开始前的准备工作
  • 0:00-2:30 – 创建文章(Posts)表
  • 2:30-5:00 – 向Posts表中填充测试数据
  • 5:00-5:30 – 创建配置项
  • 5:30-7:30 – 创建路由(routes)和控制器(controller)
  • 7:30-10:00 – 创建视图(views)

开始前的准备工作

注意:以下内容并非按照原文翻译,是胖子自己加的。

安装与配置Laravel5.1,请参考:

http://www.golaravel.com/laravel/docs/5.1/installation/

创建项目:

新建一个项目文件夹,例如:c:\wwwroot\myblog

从CMD命令行进入此文件夹

1
cd c:\wwwroot\myblog

使用composer命令安装Laravel

1
composer create-project laravel/laravel . --prefer-dist

如果你安装了laravel工具,可以进入c:\wwwroot目录下使用laravel命令进行创建

1
laravel new myblog

紧接着我们需要在mysql中创建一个myblog表,并配置mysql连接

打开config/database.php,我们发现laravel配置了很多连接模板

1
'default' => env('DB_CONNECTION''mysql'),

这一行参数指定的是默认的连接方式,默认是mysql

接着我们配置mysql连接

1
2
3
4
5
6
7
8
9
10
11
'mysql' => [
            'driver'    => 'mysql',
            'host'      => env('DB_HOST''localhost'),
            'database'  => env('DB_DATABASE''myblog'),    //表名
            'username'  => env('DB_USERNAME''root'),       //用户名
            'password'  => env('DB_PASSWORD''123456'),  //密码
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
],

这里的env是Laravel中新加的一个辅助方法,可以设置和获取一个环境变量,设置上面已经看到了,获取使用env(‘DB_HOST’)这样的方式,如果你不喜欢将连接参数设置成环境变量,可以直接用 ‘host’ =>’localhost’  这样的形式就可以了。

最后因为创建的是自用的blog,不需要密码重设功能,所以我们需要删除密码重设的前仪表,只要把

database/migrations/2014_10_12_100000_create_password_resets_table.php

删除掉就可以了。

至此,准备工作完成!

0:00-2:30 – 创建文章(Posts)表

首先,创建Posts的模型。

1
php artisan make:model --migration Post

这条命令生成的结果是:

1
2
Model created successfully.
Created Migration: 2015_03_22_210207_create_posts_table

这条命令做了两件事:

1.创建了一个app\Post.php的模型类

以下是胖子的备注:

因为Eloquent太过于强大,以及要从传统的MVC模式总解放出来,所以laravel5干掉了model文件夹,至于好处请看:

http://my.oschina.net/zgldh/blog/362063#OSC_h2_3

如果比较习惯于model文件夹,可以在app文件下任意地方自建一个models文件夹,例如

app\Models

由于laravel5遵循了php psr-r4的规范,所以只要命名空间和文件夹路径一致就可以被自动载入。

也就是说如果你要在app\Models下创建post.php,那么只要把内上面的命名空间改为namespace App\Models;就万事OK看了。

如果使用命令,命名空间会被自动设置为对应的文件夹。

1
php artisan make:model --migration Models\Post

2.创建了一个数据迁移用于创建post表,此迁移在database/migrations文件夹下(2015_03_22_210207_create_posts_table.php)

修改干创建的数据迁移,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
  /**
   * Run the migrations.
   */
  public function up()
  {
    Schema::create('posts'function (Blueprint $table) {
      $table->increments('id');
      $table->string('slug')->unique();
      $table->string('title');
      $table->text('content');
      $table->timestamps();
      $table->timestamp('published_at')->index();
    });
  }
  /**
   * Reverse the migrations.
   */
  public function down()
  {
    Schema::drop('posts');
  }
}

在数据迁移创建时默认生成的列外,我们额外添加了4个数据列;

Slug

我们将每篇文章的标题转换为slug值,并用它作为文章URI的一部分,这样可以使博客对搜索引擎更加友好。

Title

每篇文章都需要一个标题。

Content

每篇文章都需要一些内容。

Published_at

我们想控制文章何时被发布。

数据迁移已经被修改,现在运行迁移来生成表:

1
php artisan migrate

运行结果如下:

1
2
3
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2015_03_22_210207_create_posts_table

最后,修改app\Post.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
  protected $dates = ['published_at'];
  public function setTitleAttribute($value)
  {
    $this->attributes['title'] = $value;
    if (! $this->exists) {
      $this->attributes['slug'] = str_slug($value);
    }
  }
}

第9行

告诉Laravel5.1需要将published_at视为日期。

第11行

标题被赋值时,setTitleAttribute() 方法将会被调用。我们正常为属性赋值,在此行被保存到数据库前我们会将标题转换为 slug 并赋值给slug。

2:30-5:00 – 向Posts表中填充测试数据

现在有了存储文章数据的地方,我们来创建一些随机的数据吧。要是想它我们需要使用Laravel5.1的Model Factories(基于卓越的faker库创建)

在database/factories/ModelFactory.php中添加以下代码:

1
2
3
4
5
6
7
$factory->define(App\Post::classfunction ($faker) {
  return [
    'title' => $faker->sentence(mt_rand(3, 10)),
    'content' => join("\n\n"$faker->paragraphs(mt_rand(3, 6))),
    'published_at' => $faker->dateTimeBetween('-1 month''+3 days'),
  ];
});

行1

为App\Post定义一个工厂方法,这个方法以一个Faker实例对象作为参数。

行2

工厂方法返回一个列值数组。

行3

我们使用3-10个字符的随机句子作为标题。

行4

我们使用3-6个随机段落作为内容。

行5

我们使用随机的3天前到1个月的时间作为published_at

接着编辑database/seeds/DatabaseSeeder.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class DatabaseSeeder extends Seeder
{
  /**
   * Run the database seeds.
   */
  public function run()
  {
    Model::unguard();
    $this->call('PostTableSeeder');
  }
}
class PostTableSeeder extends Seeder
{
  public function run()
  {
    App\Post::truncate();
    factory(App\Post::class, 20)->create();
  }
}

行15

为post表调用seeder(原意为播种机,这里的意思是数据填充器)

行20

在这个文件中添加另外一个类,有时候规则就是用来被打破的(可能是遵循一个php文件一个类的规则)

行24

在post表中截取任何存在的记录。

行26

调用Post Model工厂方法20次,在数据库中创建最终记录。

最终要想将这些随机数据存进数据库,我们需要使用artisan命令来进行填充:

1
php artisan db:seed

运行结果是

1
Seeded: PostTableSeeder

一旦seed命令被执行,20行随机数据就会被填充到post表中。你可以使用你喜欢的数据库工具进行预览(比如phpmyadmin).

5:00-5:30 – 创建配置项

我们需要给blog配置一些参数,例如站点名称以及每页显示文章的数量。

创建config/blog.php , 添加如下代码:

1
2
3
4
5
<?php
return [
    'title' => 'My Blog',
    'posts_per_page' => 5
];

使用config(‘blog.title’)将返回站点名称。

提示:可以修改config/app.php 将时区从UTC改成本地时区。

5:30-7:30 – 创建路由(routes)和控制器(controller)

编辑app/Http/routes.php:

1
2
3
<?php
get('/', );
get('/post/{slug}', );

行2

当访问http://localhost/的时候,将会为用户返回BlogController下的index方法(完整路径App\Http\Controllers\BlogController)

行3

当访问http://localhost/posts/some-post-title-to-slug的时候,将会调用BlogController的showPost方法。Laravel中使用{参数名称}放在路径中用于获取可变参数, {?参数名称}表示这个参数可以有也可以不存在。

接着我们要创建BlogController,使用artisan命令创建一个空controller:

1
php artisan make:controller BlogController --plain

运行结果如下所示:

1
Controller created successfully

(–plain参数用于创建一个不带基本RESTFul方法的空controller)

BlogController.php将会被创建在app/Http/Controllers文件夹下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
namespace App\Http\Controllers;
use App\Post;
use Carbon\Carbon;
class BlogController extends Controller
{
    public function index()
    {
        $posts = Post::where('published_at''<=', Carbon::now())
            ->orderBy('published_at''desc')
            ->paginate(config('blog.posts_per_page'));
        return view('blog.index', compact('posts'));
    }
    public function showPost($slug)
    {
        $post = Post::whereSlug($slug)->firstOrFail();
        return view('blog.post')->withPost($post);
    }
}

行12

使用Eloquent查询文章(发布时间大于当前时间的排除在外)。

行13

文章以published_at时间倒叙排序。

行14

文章分页,分页的参数从config/blog.php中获取(config(‘blog.posts_per_page’));

行16

返回blog\index.blade.php视图,并传递$posts数据到视图中

行21

获取单篇文章,如果不存在就抛出异常。

行23

->withPost()是另外一种传递变量到视图的方法(胖子注:可以看做魔法方法,with+参数名。参数名首字母大写,在视图中就要用小写,这是和laravel默认的驼峰命名方法一致的)。 在此例中,我们传递$post变量到视图中。

你可以使用以下命令检查项目的路由表:

1
php artisan route:list

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
+----------+-------------+----------------------------------------------+
| Method   | URI         | Action                                       |
+----------+-------------+----------------------------------------------+
| GET|HEAD | /        | App\Http\Controllers\
    |
| GET|HEAD | post/{slug} | App\Http\Controllers\
 |
+----------+-------------+----------------------------------------------+

7:30-10:00 – 创建视图(views)

所有剩下的工作就是创建两个视图了,一个用于显示首页一个显示单篇文章。

创建resources/views/blog文件夹。

接着在此文件夹下创建index.blade.php,这个文件是以blade.php结尾的,代表着使用了laravel的模板引擎。

index.blade.php内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<html>
<head>
  <title>{{ config('blog.title') }}</title>
  <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"
        rel="stylesheet">
</head>
<body>
  <div class="container">
    <h1>{{ config('blog.title') }}</h1>
    <h5>Page {{ $posts->currentPage() }} of {{ $posts->lastPage() }}</h5>
    <hr>
    <ul>
      @foreach ($posts as $post)
        <li>
          <a href="/blog/{{ $post->slug }}">{{ $post->title }}</a>
          <em>({{ $post->published_at->format('M jS Y g:ia') }})</em>
          <p>
            {{ str_limit($post->content) }}
          </p>
        </li>
      @endforeach
    </ul>
    <hr>
    {!! $posts->render() !!}
  </div>
</body>
</html>

行3

这里我们我们使用双花括号来包裹从配置文件中获取的值,请注意使用两对算括号可以忽略输出(胖子注:可能是说会转义或者去掉HTML),使HTML更安全。

行4

我们将使用bootstrap提供的样式。

行10

因为$posts变量被分页,所以显示当前页和总页数方法;

行13

blade模板语法的forearch循环

行16

因为我们制定published_at为日期类型,所以我们可以使用format()方法进行格式化。

行24

这行有两个有趣的东西。第一个:注意我们是如何包容render()方法的 {!! !!}一对双括号,前后各两个感叹号。不像双花括号语法,这样写不会忽略输出(胖子注:可能说的是如果有html会直接输出)。第二是render()方法本身,我们用它来显示上一页和下一页的按钮。

最后的步骤是创建视图用于显示单篇文章,创建resources/views/blog/post.blade.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<head>
  <title>{{ $post->title }}</title>
  <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"
        rel="stylesheet">
</head>
<body>
  <div class="container">
    <h1>{{ $post->title }}</h1>
    <h5>{{ $post->published_at->format('M jS Y g:ia') }}</h5>
    <hr>
    {!! nl2br(e($post->content)) !!}
    <hr>
    <button class="btn btn-primary" onclick="history.go(-1)">
      « Back
    </button>
  </div>
</body>
</html>

内容很简单,啥也不解释了。

教程至此结束,下面都是一些巴拉巴拉的废话,不解释了。

分类: PHP编程 标签:
本文的评论功能被关闭了.