chengbocd

本文以laravel5.0.22为例。

生产环境建议使用laravel5.1版本,因为该版本是长期支持版本。5.1文档更详细:http://laravel-china.org/docs/5.1

环境需求

Laravel5.0 框架有一些系统上的需求:

PHP 版本 >= 5.4
Mcrypt PHP 扩展
OpenSSL PHP 扩展
Mbstring PHP 扩展
Tokenizer PHP 扩展

在 PHP 5.5 之后, 有些操作系统需要手动安装 PHP JSON 扩展包。如果你是使用 Ubuntu,可以通过 apt-get install php5-json 来进行安装。

我该使用Laravel吗

来自知乎网友的讨论:PHP框架Laravel还是Codeigniter? https://www.zhihu.com/question/21617669

CI比较接近原生的PHP,在原有PHP代码的基础上封装了很多类,因为它架构简单,所以容易扩展。从另一个角度来看,也就是没啥架构,最最原始的三层架构。

Laravel 简直就是一次创新,大量吸收了Java,RoR等其他框架的精华,在架构方面,已基本做到现有Php框架最佳,扩展性,伸缩性强大得一塌糊涂,非常适合团队作战。

对于新手来说,Laravel初看上去不太像Php的原本写法了,所谓优雅,就是你光凭代码就可以知道意思,而不用读注释,代码精简复用度非常高;Laravel开发人员都是PHP圈子最顶尖的高手,他们习惯用新的技术和架构,即便如此,Laravel其实上手并不难,一旦以你掌握了它的大致要点后,你会逐渐发现它在每一个方面都全面超越CI,且实用性非常高。(来源:知乎)

简单建议:
如果是个人项目,旨在研究,推荐Laravel;如果是外包或者公司项目,推荐Codeigniter或者ThinkPHP。

特点

RESTful Routing ;
设计精妙的 Blade 模板引擎, 轻快, 不失灵活 ;
合理的 ORM model 层, Eloquent ORM , 借鉴于 Rails 的成功;
migration 数据库版本系统 和 seeding ;
使用包管理器 Composer , 打开了一扇开往春天的门;
强调测试驱动, 整个核心经受过完整的测试, 高质量的代码;
命令行驱动, 可以做到高度自动化 (讲究效率, 代码生成器...) , 借鉴与 rails ;
合理使用 PHP 的新版本特性, 让写代码更加有乐趣, 跟上时代的步伐;
积极向上的社区, 这个很重要呀, 大家都在学习着, 创造着好的工具, 加快开发速度, 提高编程效率, 接受新知识的速度也很快.
对 php 标准化的支持 PHP-FIG — PHP Framework Interop Group

更多阅读:
1、最好的 PHP 框架是什么?为什么? - Charlie Jade 的回答 - 知乎
https://www.zhihu.com/question/19558755/answer/23062110

2、php - Laravel框架相对于其他框架比如CI、TP、Symfony等的优势是什么? - SegmentFault
https://segmentfault.com/q/1010000000489103

安装

使用Composer安装

很多人会卡在这一步。要么是不会Composer,要么就是无法使用Composer安装。

如果还不知道Composer,先去学习了解了解:

1、Composer使用 - 飞鸿影~ - 博客园
http://www.cnblogs.com/52fhy/p/5246013.html
2、Packagist / Composer 中国全量镜像
http://pkg.phpcomposer.com/
3、Composer 中文网
http://www.phpcomposer.com/

如果无法使用用Composer安装,很有可能是仓库访问不了,即被墙了。先更新Composer仓库源:

# 修改 composer 的全局配置文件(推荐方式)
# 打开命令行窗口(windows用户)或控制台(Linux、Mac 用户)并执行如下命令:

composer config -g repo.packagist composer https://packagist.phpcomposer.com

接下来正式开始安装吧!
这里以Laravel 5.0 版本为例(PHP 版本 >= 5.4)。

# 指定5.0.22版本,项目目录是learnlaravel5
composer create-project laravel/laravel learnlaravel5 5.0.22

等待安装(需要5分钟左右):

Installing laravel/laravel (v5.0.22)
  - Installing laravel/laravel (v5.0.22)
    Downloading: 100%

Created project in learnlaravel5
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
  - Installing jakub-onderka/php-console-color (0.1)
    Downloading: 100%

  - Installing vlucas/phpdotenv (v1.1.0)
    Downloading: 100%

  - Installing symfony/var-dumper (v2.6.4)
    Downloading: 100%

  - Installing symfony/translation (v2.6.4)
    Downloading: 100%

  - Installing symfony/security-core (v2.6.4)
    Downloading: 100%

  - Installing symfony/routing (v2.6.4)
    Downloading: 100%

  - Installing symfony/process (v2.6.4)
    Downloading: 100%

  - Installing symfony/http-foundation (v2.6.4)
    Downloading: 100%

  - Installing symfony/event-dispatcher (v2.6.4)
    Downloading: 100%

  - Installing psr/log (1.0.0)
    Downloading: 100%

...

Generating autoload files
> php artisan clear-compiled
> php artisan optimize
Generating optimized class loader
Compiling common classes
> php -r "copy(\'.env.example\', \'.env\');"
> php artisan key:generate
Application key [4FunRLeVWE0jc6QTs3h8vNbDnoa4Qi8Q] set successfully.

安装完便可以访问了:

http://localhost/laravel5/public/index.php

一键安装包下载

一键安装包是在 Laravel 官方 GitHub 仓库源码的基础上安装了依赖库(也就是已经做过 composer install,已经有了 vendor 目录),对于刚接触 Laravel 或者使用 Composer 受挫的用户能够提供快速上手实践 Laravel 的捷径。

Laravel 一键安装包。更新时间:2016年3月7日下午3点04分

master 7.45M http://down.golaravel.com/laravel/laravel-master.zip
v5.2.15 7.46M http://down.golaravel.com/laravel/laravel-v5.2.15.zip
v5.1.11 7.97M http://down.golaravel.com/laravel/laravel-v5.1.11.zip
v5.0.22 5.94M http://down.golaravel.com/laravel/laravel-v5.0.22.zip
v4.2.11 5.06M http://down.golaravel.com/laravel/laravel-v4.2.11.zip
v4.1.27 4.60M http://down.golaravel.com/laravel/laravel-v4.1.27.zip
v4.0.9 6.05M http://down.golaravel.com/laravel/laravel-v4.0.9.zip

来源:http://www.golaravel.com/download/

项目结构

app
|---Commands
|---Console
|---Events
|---Exceptions
|---Handlers
|---Http
    |---Controllers 控制器
    |---Middleware 中间件
    |---Requests 请求
    |---routes.php 路由
|---Providers
|---Services
|---User.php 模型文件
bootstrap
config
database
public
resources
|---lang
|---views 视图
    |---welcome.blade.php
    |---home.blade.php
storage
|---logs
tests
vendor
.env
artisan
composer.json
server.php

Laravel 框架有一个目录需要额外配置权限:storagevendor 目录要让服务器有写入的权限。

路由(Route)

路由文件在:app/Http/routes.php

默认的配置:

Route::get(\'/\', \'WelcomeController@index\');//匹配根目录到WelcomeController/index

Route::get(\'home\', \'HomeController@index\');//匹配home到HomeController/index

Route::controller(\'blog\', \'BlogController\');//匹配BlogController里的所有方法,但控制器里方法必须以get、post开头

//路由组
Route::controllers([
    \'auth\' => \'Auth\AuthController\',
    \'password\' => \'Auth\PasswordController\',
]);

控制器(Controllers)

控制器路径:app/Http/Controllers
示例:WelcomeController.php

<?php 
namespace App\Http\Controllers;

class WelcomeController extends Controller {

    public function index()
    {
        return view(\'welcome\');
    }
}

继承自根控制器:Controller.php

<?php namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesCommands;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;

abstract class Controller extends BaseController {

    use DispatchesCommands, ValidatesRequests;

}

生成url

url()方法可以生成符合规范的url。

echo url(\'greeting\');

//输出:http://localhost/laravel5/public/index.php/greeting

配置

配置文件:.env,包含了数据库和MAIL等配置。
config目录下也有相关配置。

模型(Model)

与Laravel4系列不同,旧的 app/models 目录已经完全被移除。相对的,Laravel5模型文件都放在 app 目录下,以及默认使用 App 命名空间。

示例:Blog.php

<?php 
namespace App;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model {
    public function listAll(){
        return $this->all();
    }
}

视图(views)

视图根路径:resources/views

视图与控制器对应关系:
例如:控制器里

view(\'welcome\'); //对应视图根路径下welcome.blade.php
view(\'admin.pages.edit\', $data); //对应对应视图根路径下admin/pages/edit.blade.php

视图文件代码上实际就是html。但自定义了一些标签。

在视图文件,我们可以使用PHP原生语法来获取传过来的数据:

<html>
    <body>
        <h1>Hello, <?php echo $name; ?></h1>
    </body>
</html>

或者使用Laravel的Blade模板标签:双大括号:

<html>
    <body>
        <h1>Hello, {{$name}}</h1>
    </body>
</html>

控制器(WelcomeController.php)里是这样的:

public function greeting() {
    return view(\'greeting\', [\'name\' => \'James\']);
}

注意,测试的时候要新建路由:

Route::get(\'greeting\', \'WelcomeController@greeting\');

访问:http://localhost/laravel5/public/index.php/greeting

传递数据到视图

// 使用传统的方法
$view = view(\'greeting\')->with(\'name\', \'Victoria\');

// 使用魔术方法
$view = view(\'greeting\')->withName(\'Victoria\');

模板标签语言

示例文件:
layout.blade.php 母视图

<html>
 <body>
    <h1>Laravel Quickstart</h1>
    
    @yield(\'content\')
 </body>
 </html>

users.blade.php 普通视图

@extends(\'layout\')

@section(\'content\')
    Users!
@endsection

1、输出:使用双花括号: {{$name}}
2、继承:@extends,将copy一份母视图过来。
引入:@include(\'shared.errors\')引入子视图
3、区域替换:@section...@endsection,该标签内的内容将替换在母视图使用@yield定义的内容。
4、条件语句:@if...@endif

@if (count($records) === 1)
    我有一条记录!
@elseif (count($records) > 1)
    我有多条记录!
@else
    我没有任何记录!
@endif

5、数据遍历、循环:

@for ($i = 0; $i < 10; $i++)
    目前的值为 {{ $i }}
@endfor

@foreach ($users as $user)
    <p>此用户为 {{ $user->id }}</p>
@endforeach

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>没有用户</p>
@endforelse

@while (true)
    <p>我永远都在跑循环。</p>
@endwhile

6、url生成:示例

{{ url(\'blog/detail/\'.$item->id) }}

# 或者
{{ url(\'blog/detail\',array(\'id\'=>$item->id)) }}

控制器里方法括号里接这个参数:

public function getDetail($id){

        $blog = new Blog();
        $detail = $blog->find($id);

        return view(\'detail\', array(
            \'detail\' => $detail
        ));
    }

7、public目录下资源引用

{{asset(\'/css/main.css\')}}

对应public目录下的css/main.css
8、视图可以显示PHP 函数的结果。实际上,可以放置任何想要的 PHP 代码到 Blade 显示的语法里面:

目前的 UNIX 时间戳为 {{ time() }}。

9、禁用渲染
由于许多 JavaScript 框架也使用「大括号」在浏览器中显示指定的表达式,因此可以使用 @ 符号来告知 Blade 渲染引擎该表达式应该维持原样。举个例子:

Hello, @{{ name }}.

10、缺省值:

{{ isset($name) ? $name : \'Default\' }}

# 或者
{{ $name or \'Default\' }}

11、显示未转义过的数据
默认输出的值会自动调用 PHP 的 htmlentities 函数,以避免 XSS 攻击。禁用:

Hello, {!! $name !!}.

参考:Laravel 5.1 中文文档:Blade 模板
http://laravel-china.org/docs/5.1/blade

数据库操作

Laravel中提供DB facade、查询构造器和Eloquent ORM三种数据库操作方式。本文接下来将讲解前两种方式。

数据库相关配置文件都在 config/database.php。默认从.env文件中读取配置。

目前 Laravel 支持四种数据库系统: MySQL、Postgres、SQLite、以及 SQL Server。

读写分离:

\'mysql\' => [
    \'read\' => [
        \'host\' => \'192.168.1.1\',
    ],
    \'write\' => [
        \'host\' => \'196.168.1.2\'
    ],
    \'driver\'    => \'mysql\',
    \'database\'  => \'database\',
    \'username\'  => \'root\',
    \'password\'  => \'\',
    \'charset\'   => \'utf8\',
    \'collation\' => \'utf8_unicode_ci\',
    \'prefix\'    => \'\',
],

使用DB类进行CURD

需要先引入。

use Illuminate\Support\Facades\DB;

例如:

public function greeting() {
    $results = DB::select(\'select * from blog where id = ?\', [1]);
    print_r($results);exit;
}

输出:

Array ( [0] => stdClass Object ( [id] => 1 [uid] => 1 [title] => test [content] => hello laravel5! [flag] => 1 [create_time] => 0 [update_time] => 0 ) )

更多方法(来自官方文档):

//执行 Select 查找
$results = DB::select(\'select * from users where id = ?\', [1]);
$results = DB::select(\'select * from users where id = :id\', [\'id\' => 1]);

//执行 Insert 语法
DB::insert(\'insert into users (id, name) values (?, ?)\', [1, \'Dayle\']);

//执行 Update 语法
DB::update(\'update users set votes = 100 where name = ?\', [\'John\']);

执行 Delete 语法
DB::delete(\'delete from users\');

//执行一般语法
DB::statement(\'drop table users\');

//监听查找事件
DB::listen(function($sql, $bindings, $time)
{
    //
});


//数据库事务处理
//你可以使用 transaction 方法,去执行一组数据库事务处理的操作:
DB::transaction(function()
{
    DB::table(\'users\')->update([\'votes\' => 1]);

    DB::table(\'posts\')->delete();
});

//手动事务
DB::beginTransaction();
DB::rollback();
DB::commit();


//获取连接
//若要使用多个连接,可以通过 DB::connection 方法取用:
$users = DB::connection(\'foo\')->select(...);

//你也可以取用原始底层的 PDO 实例:
$pdo = DB::connection()->getPdo();

//有时候你可能需要重新连接到特定的数据库:
DB::reconnect(\'foo\');

//如果你因为超过了底层 PDO 实例的 max_connections 的限制,需要关闭特定的数据库连接,可以通过 disconnect 方法:
DB::disconnect(\'foo\');


//查找日志记录
//Laravel 可以在内存里访问这次请求中所有的查找语句。然而在有些例子下要注意,比如一次添加 大量的数据,可能会导致应用程序耗损过多内存。 如果要启用日志,可以使用 enableQueryLog 方法:
DB::connection()->enableQueryLog();

//要得到执行过的查找纪录数组,你可以使用 getQueryLog 方法:
$queries = DB::getQueryLog();

DB类查询构造器

Laravel 查询构造器使用 PDO 参数绑定,以保护应用程序免于 SQL 注入,因此传入的参数不需额外转义特殊字符。

示例:

//获取所有数据列
$users = DB::table(\'users\')->get();

查询:

//根据条件查找,取得单一数据列
$user = DB::table(\'users\')->where(\'name\', \'John\')->first();
var_dump($user->name);


//从数据表中取得单一数据列的单一字段
$name = DB::table(\'users\')->where(\'name\', \'John\')->pluck(\'name\');

//取得单一字段值的列表:这个方法将会返回数据表 role 的 title 字段值的数组
$roles = DB::table(\'roles\')->lists(\'title\');
$roles = DB::table(\'roles\')->lists(\'title\', \'name\');


//指定查询字段
$users = DB::table(\'users\')->select(\'name\', \'email\')->get();
$users = DB::table(\'users\')->distinct()->get();
$users = DB::table(\'users\')->select(\'name as user_name\')->get();


//增加查询字段到现有的查询中
$query = DB::table(\'users\')->select(\'name\');
$users = $query->addSelect(\'age\')->get();

//使用 where 及运算符
$users = DB::table(\'users\')->where(\'votes\', \'>\', 100)->get();

//or
$users = DB::table(\'users\')
            ->where(\'votes\', \'>\', 100)
            ->orWhere(\'name\', \'John\')
            ->get();
            
//Between
$users = DB::table(\'users\')
            ->whereBetween(\'votes\', [1, 100])->get();
            
//Not Between
$users = DB::table(\'users\')
            ->whereNotBetween(\'votes\', [1, 100])->get();   
            
            
//In
$users = DB::table(\'users\')
            ->whereIn(\'id\', [1, 2, 3])->get();

//NotIn
$users = DB::table(\'users\')
            ->whereNotIn(\'id\', [1, 2, 3])->get();            

//Null 找有未配置的值的数据
$users = DB::table(\'users\')
            ->whereNull(\'updated_at\')->get();

//魔术语句            
$admin = DB::table(\'users\')->whereId(1)->first();

$john = DB::table(\'users\')
            ->whereIdAndEmail(2, \'john@doe.com\')
            ->first();

$jane = DB::table(\'users\')
            ->whereNameOrAge(\'Jane\', 22)
            ->first();            

//排序(Order By)、分群(Group By) 及 Having
$users = DB::table(\'users\')
            ->orderBy(\'name\', \'desc\')
            ->groupBy(\'count\')
            ->having(\'count\', \'>\', 100)
            ->get();
                    
//偏移(Offset) 及 限制(Limit)
$users = DB::table(\'users\')->skip(10)->take(5)->get();

//基本的 Join 语法
DB::table(\'users\')
            ->join(\'contacts\', \'users.id\', \'=\', \'contacts.user_id\')
            ->join(\'orders\', \'users.id\', \'=\', \'orders.user_id\')
            ->select(\'users.id\', \'contacts.phone\', \'orders.price\')
            ->get();
            
//Left Join 语法
DB::table(\'users\')
        ->leftJoin(\'posts\', \'users.id\', \'=\', \'posts.user_id\')
        ->get();
        
//更高级的 join 子句:
DB::table(\'users\')
    ->join(\'contacts\', function($join)
    {
        $join->on(\'users.id\', \'=\', \'contacts.user_id\')->orOn(...);
    })
    ->get();
    
DB::table(\'users\')
    ->join(\'contacts\', function($join)
    {
        $join->on(\'users.id\', \'=\', \'contacts.user_id\')
             ->where(\'contacts.user_id\', \'>\', 5);
    })
    ->get();   
    
//群组化参数
DB::table(\'users\')
    ->where(\'name\', \'=\', \'John\')
    ->orWhere(function($query)
    {
        $query->where(\'votes\', \'>\', 100)
              ->where(\'title\', \'<>\', \'Admin\');
    })
    ->get();
    
//上面的查找语法会产生下方的 SQL:
select * from users where name = \'John\' or (votes > 100 and title <> \'Admin\')

//Exists 语法
DB::table(\'users\')
            ->whereExists(function($query)
            {
                $query->select(DB::raw(1))
                      ->from(\'orders\')
                      ->whereRaw(\'orders.user_id = users.id\');
            })
            ->get();
//上面的查找语法会产生下方的 SQL:
select * from users
where exists (
    select 1 from orders where orders.user_id = users.id
)

//使用聚合方法
$users = DB::table(\'users\')->count();
$price = DB::table(\'orders\')->max(\'price\');
$price = DB::table(\'orders\')->min(\'price\');
$price = DB::table(\'orders\')->avg(\'price\');
$total = DB::table(\'users\')->sum(\'votes\');

新增:

//新增,不会返回新增ID
DB::table(\'users\')->insert(
    [\'email\' => \'john@example.com\', \'votes\' => 0]
);

//新增,返回新增ID
$id = DB::table(\'users\')->insertGetId(
    [\'email\' => \'john@example.com\', \'votes\' => 0]
);

//批量新增
DB::table(\'users\')->insert([
    [\'email\' => \'taylor@example.com\', \'votes\' => 0],
    [\'email\' => \'dayle@example.com\', \'votes\' => 0]
]);

更新:

//更新
DB::table(\'users\')
            ->where(\'id\', 1)
            ->update([\'votes\' => 1]);

//自增或自减一个字段的值
DB::table(\'users\')->increment(\'votes\');
DB::table(\'users\')->increment(\'votes\', 5);
DB::table(\'users\')->decrement(\'votes\');
DB::table(\'users\')->decrement(\'votes\', 5);

//也能够同时指定其他要更新的字段:
DB::table(\'users\')->increment(\'votes\', 1, [\'name\' => \'John\']);

删除:

//删除数据表中的数据
DB::table(\'users\')->where(\'votes\', \'<\', 100)->delete();

//删除数据表中的所有数据
DB::table(\'users\')->delete();

//清空数据表
DB::table(\'users\')->truncate();

更多查看:http://laravel-china.org/docs/5.0/queries

Eloquent ORM

相比DB类,Laravel 的 Eloquent ORM 提供优雅的 ActiveRecord 实现来和数据库的互动。 每个数据库表会有一个对应的模型文件。
详见下一章。

学习资料

推荐教程:
Laravel 5 系列入门教程(一)【最适合中国人的 Laravel 教程】 - 岁寒
https://lvwenhan.com/laravel/432.html

Laravel 5 中文文档:

  1. http://laravel-china.org/docs/5.0
  2. http://laravel-china.org/docs/5.1
  3. http://www.golaravel.com/laravel/docs/5.0/

更多:

分类:

技术点:

相关文章: