laravel入门教程(一)

laravel入门教程(一)

本教程是针对 laravel 5 来讲解的

0.1、一个简单的示例

//文件:routes/web.php

Route::get('/','WelcomeController@index');

//文件:app/Http/Controllers/WelcomeController.php

namescpace app\Http\Controllers;

class WelcomeController{
    public function index(){
        return 'Hello, World!';
    }
}

访问http://xxxxxxxxx.xxx/ 就可以看见“Hello,World!”。
实际上,这种写法等价于另一种更为简便的写法

//文件:routes/web.php

Route::get('/',function(){
    return 'Hello, World!';
});

但是,为了保持与后面讲解内容的一致性和代码编写的一致性,最好使用第一种方法。第一种方法的第一个文件中定义了路由,当访问‘/’的路由的时候,就去找WelcomeController里面的index方法。第二个文件定义的就是WelcomeController控制器以及它的index方法。

0.2、一个访问数据库数据的demo

//文件:routes/web.php

Route::get('/',function{
    return Greeting::first()->body;
});
//文件:app/Greeting.php
//这个是模型文件

use Illuminate\Database\Eloquent\Model;

class Greeting extends Model{}

//文件:database/migrations/2018_06_03_123123_create_greetings_table.php
//这个是数据库迁移文件,后面会详细讲解

 use Illuminate\Database\Migrations\Migration;
 use Illuminate\Database\Schema\Blueprint;
 class CreateGreetingsTable extends Migration{
     public function up(){
         Schema::create('greetings',function(Blueprint $table){
            $table->increments('id');
            $table->string('body');
            $table->timestamps();
         });
     }//创建数据库的文件,这些文件都可以使用artisan命令自动生成,内容自己填充

     public function down(){
         Schema::drop('greetings');
     }//销毁数据库时的操作
 }

如果在greetings数据库里面存入一条数据:“Hello, World!”。就可以在首页看到了。

下面开始正式学习laravel

1、创建一个新的laravel项目

1.1、使用Laravel安装工具来安装Laravel
(1)、开发全局安装Composer
(2)、运行

composer global require “laravel/installer=~1.1”

安装laravel安装工具。启动一个全向的Laravel项目:

laravel new projectName

此命令会在当前目录下创建一个新的名为 projectName 的子目录,并在其中安装 一个全新的Laravel项目

1.2、使用Composer的create-project 来安装Laravel
(1)、输入以下命令:

composer create-project laravel/laravel projectName –prefer-dist

此命令会在当前目录下创建一个新的名为 projectName 的子目录,并在其中安装 一个全新的Laravel项目

1.3、创建好Laravel项目之后,生成的项目结构大致如下(因为版本不一样,可能稍有区别)

新安装的 Laravel 应用包含许多文件夹:
app目录包含了应用的核心代码;
bootstrap目录包含了少许文件用于框架的启动和自动载入配置,还有一个cache文件夹用于包含框架生成的启动文件以提高性能;

config目录包含了应用所有的配置文件;

database目录包含了数据迁移及填充文件,如果你喜欢的话还可以将其作为 SQLite 数据库存放目录;

public目录包含了前端控制器和资源文件(图片、JavaScript、CSS等);

resources目录包含了视图文件及原生资源文件(LESS、SASS、CoffeeScript),以及本地化文件;

storage目录包含了编译过的Blade模板、基于文件的session、文件缓存,以及其它由框架生成的文件,该文件夹被细分为成app、framework和logs子目录,app目录用于存放应用要使用的文件,framework目录用于存放框架生成的文件和缓存,最后,logs目录包含应用的日志文件;

tests目录包含自动化测试,其中已经提供了一个开箱即用的PHPUnit示例;

vendor目录包含Composer依赖;

App目录

应用的核心代码位于app目录下,默认情况下,该目录位于命名空间 App 下, 并且被 Composer 通过 PSR-4自动载入标准 自动加载。你可以通过Artisan命令app:name来修改该命名空间。

app目录下包含多个子目录,如Console、Http、Providers等。Console和Http目录提供了进入应用核心的API,HTTP协议和CLI是和应用进行交互的两种机制,但实际上并不包含应用逻辑。换句话说,它们只是两个向应用发布命令的方式。Console目录包含了所有的Artisan命令,Http目录包含了控制器、中间件和请求等。

Jobs目录是放置队列任务的地方,应用中的任务可以被队列化,也可以在当前请求生命周期内同步执行。

Events目录是放置事件类的地方,事件可以用于通知应用其它部分给定的动作已经发生,并提供灵活的解耦的处理。

Listeners目录包含事件的处理器类,处理器接收一个事件并提供对该事件发生后的响应逻辑,比如,UserRegistered事件可以被SendWelcomeEmail监听器处理。

Exceptions目录包含应用的异常处理器,同时还是处理应用抛出的任何异常的好地方。

注意:app目录中的很多类都可以通过Artisan命令生成,要查看所有有效的命令,可以在终端中运行php artisan list make命令。

2、配置

内容包括数据库连接,队列以及邮件设置都放置在config文件夹中。这里的每一个文件都将返回一个数组,数组中的每个值都可以通过一个配置键进行访问,该配置键有文件名和后续的键组成,以点好(.)进行分隔。所以,可以在config/services.php中创建如下所示的信息。

// config/services.php
return [
    'sparkpost' => [
        'secret' => 'aaaaaa'
    ]
];

现在可以使用

config(‘services.sparkpost.secret)

访问配置好的变量了。

每个环境中的任何配置变量都应该放在.env文件中(而不是提交给源代码控制)。如果希望在每个环境使用不同的Bugsnag API密钥,可以将配置信息从.env中提取出来,如下所示:

//config/services.php
return [
    'bugsnag' => [
        'api_key' => env('BUGSNAG_API_KEY')
    ]
];

.env()这个函数可以从.env文件中提取出该键名所对应的值。现在可以将该键名对应的信息添加到.env(当前环境的设置)和.env.example(适用于所有环境的模板)文件中。

BUGSNAG_API_KEY = oinfp9813410942

3、路由和控制器

在学习web框架时,定义好应用程序的路由是第一个也是最重要的一个环节。没有路由,就无法与终端用户进行交互。

在一个laravel应用程序中,一般是在routes/web.php中定义路由。如果是api的路由,则在api.php中定义路由。示例0.1就是一个路由定义的例子。

在详细介绍路由之前,先介绍几个概念:

闭包:闭包是php版本的匿名函数。闭包是一个函数,可以将它作为一个对象传递,并赋值给一个变量,将其作为参数传递给其他的函数和方法,甚至进行序列化。
中间件:laravel的请求和响应的过程包含很多封装起来的内容,包括所谓的中间件。仅仅定义路由闭包以及控制器方法,还不足以将输出发送给浏览器,所以这里采用返回内容的方式,这样返回的内筒可以继续在response stack以及中间件中运行(即继续在程序中处理该返回的内容),运行完成后再返回给浏览器共终端用户查看。

demo3.1

//简单的网站

Route::get('/',function(){
    return view('welcome');
});

Route::get('about',function(){
    return view('about');
});

Route::get('products',function(){
    return view('products');
});
Route::get('services',function(){
    return view('services');
});

上面的代码等价于

$router->get('/',function(){
    return view('welcome');
});

$router->get('about',function(){
    return view('about');
});

$router->get('products',function(){
    return view('products');
});
$router->get('services',function(){
    return view('services');
});

常用的HTTP方法有:GET/POST/PUT/DELETE/PATCH
进行替换就可以了。例如:

Route::get('/',function(){
    return '123';
});

Route::post('/',function(){
    return '456';
});

Route::put('/',function(){});
Route::delete('/',function(){});
Route::any('/',function(){});
Route::match(['get','post'],'/',function(){});

另一种方法是将控制器名称和方法作为字符串传递给闭包

Route::get('/','WelcomeController@index');

路由参数:如果定义的路由具有参数(可变的额URL地址段),那么可以在路由中定义它们,并将它们传递给闭包。

//路由参数示例
Route::get('users/{id}/friends',function(){
    //
});

一般只有get方法这样写参数。
在录用参数({id})中使用相同的名称,以及将对应的名字添加到路由定义的方法参数中(function{$sid)是十分常见的。除非使用路由/模型绑定,否则定义的路由参数与哪个方法参数相匹配仅由它们的顺序(从左到右)决定,如以下代码所示。

Route::get('users'/{userId}/comments/{commentId}',function( $thisIsActuallyTheRouteId, $thisisReallyTheCommentId ){ // });

也就是说,可以让它们使用不同的名称,也可以使用相同的名称。这里建议使它们的名称保持一致,以免未来开发人员在使用的时候可能因为不一致的命名而出现问题。
还可以用过在参数名称后添加一个问号(?)来实现路由参数的选择。

//可选路由参数
Route::get('users/{id?}',function($id = 'fallbackId'){
    //
});

在这种情况下,应该为相应的路由变量设置好默认值。并且可以使用正则表达式来定义一个路由,这个时候,只有该参数满足特定的模式时才会匹配

//通过正则表达式来定义路由 Route::get(;users/{id}',function($id){ // })->where('id','[0-9]+'); Route::get('users/{username}',function($username){ // })->where('username','[A-Za-z]+'); Route::get('posts/{id}/{slug}',function($id,$slug){ // })->where(['id'] => '[0-9]+',]slug' => '[A-Za-z]+');

路由名称
url()助手函数:写相对路径,可以自动补全站点全称

//在routes/web.php中定义具有名称的路由
Route::get('members/{id}','MembersController@show')->name('members.show');

//使用route()助手在视图中链接路由
<a href="">

路由组
允许多个路由组合在一起,并且可以将任何共享的配置应用于整个组,从而避免配置信息的重复。

//定义一个路由组
Route::group([],function(){
    Route::get('hello',function(){
        return 'Hello';
    });
    Route::get('world',function(){
        return ' World!';
    });
});

传入的空数组允许传递各种配置信息,这些配置将对组内的所有路由都生效。

中间件
路由组最常见的功能就是将中间件应用于一组路由中,但是在其他方面,路由组也常常被应用在权限控制方面。

//将一组路由限制为只允许登录用户访问
Route::group(['middleware' => 'auth'],function(){
    Route::get('aaa',function(){
        return view('aaaa');
    });
    Route::get('bbb',function(){
            return view('bbbb');
    });
});

此时中间件auth对aaa和bbb这两者都会生效。在此示例中,表示用户必须登录后才能查看控制中心(aaa)或账户页面(bbb)。

中间件在控制器中的应用:
通常,在控制器中使用中间件比在路由中使用中间件更为清晰和直接。可以在控制器中调用middleware()方法来使用中间件。参数代表中间件的名称,可以使用modifier方法(only()和except())来确定将由哪些方式接收中间件

class DashboardController extends Controller{
    public function __construct(){
        $this->middleware('auth');
        $this->middleware('admin-auth')->only('admin');
        $this->middleware('team-member')->except('admin');
    }
}

路径前缀

//为一组路由设置路径前缀
Route::group(['prefix' => 'api'],function(){
    Route::get('/',function(){
        //设置path /api
    });

    Route::get('users',function(){
        //设置path /api/users
    });
});

子域名路由
子域名路由的作用域是子域名,而不是路由前缀

//子域名路由
Route::group(['domain' => 'api.myapp.com'],function(){
    Route::get('/',function(){
        //
    });
});

//参数化的子域名路由
Route::group(['domain'=> '{acount}.myapp.com'],function(){
    Route::get('/',function($acount){
        //
    });
    Route::get('users/{id}',function($acount,$id){
        //
    });
});

你可能感兴趣的:(laravel)