“Laravel”的版本间的差异

来自tomtalk
跳转至: 导航搜索
目录
Tom讨论 | 贡献
基本功能
第86行: 第86行:
  
 
从测试结果上看,cpus设为2运行效率最高。
 
从测试结果上看,cpus设为2运行效率最高。
 
=基本功能=
 
 
==路由==
 
 
<source lang='php'>
 
// 简单路由
 
Route::get('/', function () {
 
    return view('welcome');
 
});
 
 
//为多重动作注册路由
 
Route::match(['get', 'post'], '/get-post', function () {
 
    return 'get and post';
 
});
 
 
Route::any('foo', function () {
 
    return 'any foo ' . url('foo') . ' ' . url('router');
 
});
 
 
//路由参数
 
Route::get('posts/{pid}/comments/{comment?}', function ($pId, $commentId = 'empty') {
 
    return "postId = $pId, comments = $commentId";
 
});
 
 
//正则表达式限制参数。也可为参数设定全局规则pattern filter。
 
Route::get('user/{id}/{name?}', function ($id, $name = 'empty') {
 
    return "userId = $id, name = $name";
 
})->where(['id' => '[0-9]?', 'name' => '[a-z]+']);
 
 
//命名路由
 
Route::get('user/list', ['as' => 'userList', function () {
 
    return 'name router: ' . route('userList');
 
}]);
 
 
Route::get('user/info/{id?}', 'UserController@UserInfo')->name('userInfo');
 
 
//路由群组:中间件、命名空间、子域名、前缀
 
Route::group([
 
    /*'middleware' => 'auth',*/
 
    'namespace' => 'Member',
 
    'domain' => '{account}.tomtalk.net',
 
    'prefix' => 'member'], function () {
 
    Route::get('{id?}', 'MemberController@detail');
 
});
 
 
//CSRF保护:试了一下,还是不知道怎么用。
 
 
//路由模型绑定
 
Route::get('user/model/{user}', 'UserController@UserModel')->name('userModel');
 
 
//请求方法伪造 - echo method_field('PUT')
 
 
//抛出404错误 - abort(404)
 
</source>
 
 
==中间件==
 
 
HTTP中间件提供了一个方便的机制来过滤进入应用程序的HTTP请求。所有的中间件都放在app/Http/Middleware目录内。
 
 
 
;创建一个中间件
 
 
<source lang='bash'>
 
php artisan make:middleware OldMiddleware
 
</source>
 
 
<source lang='php'>
 
public function handle($request, Closure $next)
 
{
 
    if ($request->input('age') <= 200) {
 
        return redirect('home');
 
    }
 
 
    return $next($request);
 
}
 
</source>
 
 
;前置中间件/后置中间件
 
 
<source lang='php'>
 
public function handle($request, Closure $next)
 
{
 
    // 运行动作
 
 
    return $next($request);
 
}
 
 
public function handle($request, Closure $next)
 
{
 
    $response = $next($request);
 
 
    // 运行动作
 
 
    return $response;
 
}
 
</source>
 
 
 
;全局中间件
 
 
若是希望每个HTTP请求都经过一个中间件,只要将中间件的类加入到app/Http/Kernel.php的$middleware属性清单列表中。
 
 
 
;为路由指派中间件
 
 
 
;中间件参数
 
 
 
;Terminable中间件
 
 
有些时候中间件需要在HTTP响应被发送到浏览器之后才运行,例如,Laravel内置的「session」中间件存储的session数据是在响应被发送到浏览器之后才进行写入的。想要做到这一点,你需要定义中间件为「terminable」
 
 
==控制器==
 
 
===基础控制器===
 
 
<source lang='php'>
 
//一旦你指定了控制器路由的名称,则可以很容易地生成能实现该行为的URL。
 
$url = route('name');
 
 
//你也可以使用action辅助函数生成指向控制器行为的URL。
 
$url = action('FooController@method');
 
 
//你可以使用Route facade的currentRouteAction方法取到正在运行的控制器行为名称。
 
$action = Route::currentRouteAction();
 
</source>
 
 
===控制器中间件===
 
 
可将中间件指定给控制器路由,例如:
 
 
<source lang='php'>
 
Route::get('profile', [ 'middleware' => 'auth', 'uses' => 'UserController@showProfile' ]);
 
</source>
 
 
不过,在控制器构造器中指定中间件会更为灵活。你可以很容易地将中间件指定给控制器。你甚至可以对中间件作出限制,仅将它提供给控制器类中的某些方法。
 
 
<source lang='php'>
 
class UserController extends Controller
 
{
 
    public function __construct()
 
    {
 
        $this->middleware('auth');
 
        $this->middleware('log', ['only' => ['fooAction', 'barAction']]);
 
        $this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
 
    }
 
}
 
</source>
 
 
===RESTful资源控制器===
 
 
<source lang='php'>
 
Route::resource('photos', 'PhotosController');
 
 
//部分资源路由
 
Route::resource('photos', 'PhotosController', ['only' => ['index', 'show']]);
 
Route::resource('photos', 'PhotosController', ['except' => ['create', 'store', 'update', 'destroy']]);
 
 
//命名资源路由
 
Route::resource('photos', 'PhotosController', ['names' => ['create' => 'photo.build']]);
 
 
//嵌套资源
 
Route::resource('photos.comments', 'PhotoCommentController');
 
 
//附加资源控制器
 
//如果想在资源控制器中默认的资源路由之外加入其它额外路由,则应该在调用Route::resource之前定义这些路由。否则,由resource方法定义的路由可能会不小心覆盖你附加的路由:
 
Route::get('photos/popular', 'PhotosController@method');
 
Route::resource('photos', 'PhotosController');
 
 
//隐式控制器
 
Route::controller('users', 'UserController');
 
</source>
 
 
==请求==
 
 
===获取请求===
 
 
要通过依赖注入的方式获取HTTP请求的实例,就必须在控制器的构造器或方法中,使用Illuminate\Http\Request类型提示。
 
 
<source lang='php'>
 
use Illuminate\Http\Request;
 
 
class UserController extends Controller
 
{
 
    public function store(Request $request)
 
    {
 
        $name = $request->input('name');
 
        //
 
    }
 
}
 
</source>
 
 
如果控制器方法也有输入数据是从路由参数传入的,只需将路由参数置于其它依赖之后。
 
 
<source lang='php'>
 
public function update(Request $request, $id)
 
{
 
    //
 
}
 
 
//基本请求信息
 
$uri = $request->path();  //返回请求的URI
 
$url = $request->url(); //获取完整的网址
 
 
//获取请求的方法
 
$method = $request->method();
 
if ($request->isMethod('post')) {
 
    //
 
}
 
</source>
 
 
===获取输入数据===
 
 
<source lang='php'>
 
$name = $request->input('name');
 
 
$name = $request->name; //使用属性访问用户输入
 
 
//你可以在input方法的第二个参数中传入一个默认值。当请求的输入数据不存在于此次请求时,就会返回默认值:
 
$name = $request->input('name', 'Sally');
 
 
//确认是否有输入值
 
if ($request->has('name')) {
 
    //
 
}
 
 
//获取所有输入数据
 
$input = $request->all();
 
 
//获取部分输入数据
 
$input = $request->only(['username', 'password']);
 
$input = $request->only('username', 'password');
 
$input = $request->except(['credit_card']);
 
$input = $request->except('credit_card');
 
 
//将输入数据闪存至Session
 
$request->flash();
 
$request->flashOnly('username', 'email');
 
$request->flashExcept('password');
 
 
//闪存输入数据至Session后重定向
 
return redirect('form')->withInput();
 
return redirect('form')->withInput($request->except('password'));
 
 
//获取旧输入数据
 
$username = $request->old('username');
 
{{ old('username') }}
 
</source>
 
 
===Cookies===
 
 
<source lang='php'>
 
$value = $request->cookie('name');
 
 
//将新的 Cookie 附加到响应
 
$response = new Illuminate\Http\Response('Hello World');
 
$response->withCookie(cookie('name', 'value', $minutes));
 
return $response;
 
 
//如果要创建一个可长期存在,为期五年的 cookie。
 
$response->withCookie(cookie()->forever('name', 'value'));
 
</source>
 
 
===上传文件===
 
 
<source lang='php'>
 
$file = $request->file('photo');
 
 
//确认上传的文件是否存在:
 
if ($request->hasFile('photo')) {
 
    //
 
}
 
 
//确认上传的文件是否有效
 
if ($request->file('photo')->isValid()) {
 
    //
 
}
 
 
//移动上传的文件
 
$request->file('photo')->move($destinationPath);
 
$request->file('photo')->move($destinationPath, $fileName);
 
</source>
 
 
==blade模板==
 
 
所有 Blade 视图都会被编译缓存成普通的 PHP 代码,一直到它们被更改为止。这代表 Blade 基本不会对你的应用程序生成负担。
 
 
<source lang='php'>
 
@extends('layouts.master')
 
 
@section('title', 'LaravelExample')
 
 
@section('sidebar')
 
    @parent
 
 
    <div>
 
        sidebar
 
    </div>
 
@endsection
 
 
@section('content')
 
    <h3>变量的使用</h3>
 
    <p>目前的 UNIX 时间戳为 {{ $time }}。
 
    <p>目前的 UNIX 时间戳为 {{ time() }}。
 
    <p>目前的 UNIX 时间戳为 @{{ time() }}。
 
    <p>My name is {{ $name or 'Default' }}.
 
    <p>My name is {{ $html or 'html' }}.
 
    <p>My name is {!! $html or 'html' !!}.
 
 
    {{-- @符号如何显示 --}}
 
 
    <h3>include</h3>
 
    @include('usersList')
 
 
    <h3>each</h3>
 
    @each('userInfo', $users, 'name')
 
 
    {{-- 服务注入 --}}
 
 
    <h3>自定义模板指令</h3>
 
    @datetime(new Datetime())
 
@endsection
 
</source>
 
  
 
=系统架构=
 
=系统架构=

2016年9月18日 (日) 04:01的版本

目录

起步

安装

  1. 下载Laravel一键安装包。
  2. 配置Web服务器虚拟主机。
  3. 将网站根目录配置为laravel5/public。
  4. 能显示Laravel文字,说明安装成功。

Homestead

https://phphub.org/topics/2 Laravel 的 Homestead 开发环境部署

这是两年前的旧文了,不知现在是否还有效。

Mac安装

http://laravel-china.org/docs/5.1/homestead 按开发文档步骤安装,比较顺利。

  1. 安装Virtual Box
  2. 安装Vagrant
  3. 下载本地Lavravl项目代码
  4. 配置Homestead.yaml
  5. vagrant up
  6. vagrant reload --provision
  7. vagrant destroy --force

Windows安装

windows的安装步骤与Mac一样,只是电脑配置差异,有些问题要特别处理。


在BIOS中,开启虚拟化。

安装好Virtual Box、Vagrant,配置好Homestead.yaml后,vagrant up启动到一半不动了,直到超时退出。


在配置文件夹和站点目录

folders的map和to,配置反了,启动时vagrant找不到github_projets目录。

folders:
    - map: d:/github_projects
      to: /home/github_projects
 
sites:
    - map: laravel.example.com
      to: /home/github_projects/LaravelExample/public


运行composer install

正常启动Vagrant后,打开站点首页,报错,指示vendor目录下的文件找不到。


.ssh帐户可以注释掉
authorize: ~/.ssh/id_rsa.pub
 
keys:
    - ~/.ssh/id_rsa


cpus设置

i5CPU,双核四线程,跑了个负载。

ab -c 50 -n 2000 http://laravel.example.com/
 
cpus: 1    75.99     72.95
cpus: 2   111.95    114.54
cpus: 3   111.27    115.85
cpus: 4    92.57     95.45

从测试结果上看,cpus设为2运行效率最高。

系统架构

请求生命周期

require __DIR__.'/../bootstrap/autoload.php';
 
$app = require_once __DIR__.'/../bootstrap/app.php';  //创建服务容器
 
/**
 * 创建http核心(或者终端核心)。
 * config/app.php 
 * 1、注册服务提供者
 * 2、boot()
 * 3、注册中间件
 */
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 
 
/**
 * 1、路由分派
 * 2、执行路由中间件
 * 3、跳转到控制器
 */
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
 
$response->send();
 
$kernel->terminate($request, $response);

应用程序结构

服务提供者

服务提供者是所有Laravel应用程序启动的中心所在。包括你自己的应用程序,以及所有的Laravel核心服务,都是通过服务提供者启动的。

若你打开Laravel的config/app.php文件,你将会看到providers数组。这些都是你的应用程序会加载到的所有服务提供者类。当然,它们之中有很多属于「延迟」提供者,意味着除非真正需要它们所提供的服务,否则它们并不会在每一个请求中都被加载。


注册方法

如同之前提到的,在register方法中,你应该只将事物绑定至服务容器中。永远不要尝试在register方法中注册任何事件侦听器、路由或任何其它功能。否则的话,你可能会意外地使用到由尚未加载的服务提供者所提供的服务。


延迟提供者

若你的提供者仅在服务容器中注册绑定,你可以选择延缓其注册,直到真正需要其中已注册的绑定,延迟提供者加载可提高应用程序的性能。

要延迟提供者加载,可将defer属性设置为true,并定义一个provides方法。provides方法会返回提供者所注册的服务容器绑定。

服务容器

在服务提供者中,你总是可以通过$this->app实例变量访问容器。


绑定
  1. 绑定一个单例
  2. 绑定实例
  3. 绑定接口至实现
  4. 情境绑定
  5. 标记


解析

有几种方式可以从容器中解析一些东西。

$fooBar = $this->app->make('FooBar');

或者,你可以像数组一样从容器中进行访问,因为他实现了PHP的ArrayAccess接口:

$fooBar = $this->app['FooBar'];


容器事件

每当服务容器解析一个对象时就会触发事件。你可以使用resolving方法监听这个事件。

Facades

Facades为应用程序的服务容器中可用的类提供了一个「静态」接口。Laravel本身附带许多的facades,甚至你可能在不知情的状况下已经在使用他们!Laravel「facades」作为在服务容器内基类的「静态代理」,拥有简洁、易表达的语法优点,同时维持着比传统静态方法更高的可测试性和灵活性。

$user = Cache::get('user:'.$id);

如果我们查看Illuminate\Support\Facades\Cache类,你会发现没有静态方法get。

相反的,Cache facade继承了基底Facade类以及定义了getFacadeAccessor()方法。记住,这个方法的工作是返回服务容器绑定的名称。当用户在Cache facade上参考任何的静态方法,Laravel会从服务容器解析被绑定的cache以及针对对象运行请求的方法(在这个例子中是get)。

Contracts

Laravel的Contracts是一组定义了框架核心服务的接口(php class interfaces)。例如:

  • Illuminate\Contracts\Queue\Queue contract 定义了队列任务所需要的方法
  • Illuminate\Contracts\Mail\Mailer contract 定义了寄送e-mail需要的方法

框架对于每个contract都有提供对应的实现。


Contracts Vs. Facades

Laravel的facades提供一个简单的方法来使用服务,而不需要使用类型提示和在服务容器之外解析contracts。然而,使用contracts可以明显地定义出类的依赖,对大部分应用进程而言,使用facade就足够了,然而,若你实在需要特别的低耦合,使用contracts可以做到这一点。


简单性

当所有的Laravel服务都使用简洁的接口定义,就能够很容易决定一个服务需要提供的功能。可以将contracts视为说明框架特色的简洁文档。

除此之外,当依赖的接口足够简洁时,代码的可读性和可维护性大大提高。比起搜索一个大型复杂的类里有哪些可用的方法,你有一个简单,干净的接口可以参考。

系统服务

事件

Laravel事件提供了简单的侦听器实现,允许你订阅和监听事件,事件类通常被保存在app/Events目录下,而它们的侦听器被保存在app/Listeners目录下。

错误与日志

//.env
APP_DEBUG=true
 
// bootstrap/app.php
$app->withFacades();
 
//引用Log
use Log;
 
// 8个日志级别
Log::emergency($error);
Log::alert($error);
Log::critical($error);
Log::error($error);
Log::warning($error);
Log::notice($error);
Log::info($error);
Log::debug($error);

测试

public function testTom()
{
    $response = $this->call('get', '/userInfo');
    $result = json_decode($response->original);
 
    $this->assertEquals(
        'Tom', $result->name
    );
}

缓存

use Cache;
 
if (Cache::has('key')) {
    $coupon_total = Cache::get('key');
} else {
    $rs = Coupon_api::instance()->total();
 
    if ($rs['status']) {
        $coupon_total = $rs['data']['total_amount'];
    }
 
    Cache::put('key', $coupon_total, 5); //5 minutes
}

session

session使用
use Illuminate\Http\Request;
 
function blade(Request $request)
{
    //赋值
    session(['name'=> 'Tom']);
    $request->session()->put('name', 'Tom');
    $request->session()->push('students', 'Tom');
 
    //取值
    $name = session('name');
    $request->session()->get('students');
}


Session store not set on request.
// Kernel.php添加中间件
protected $middleware = [
    //...
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
];

SwaggerLume

https://github.com/DarkaOnLine/SwaggerLume

一、安装swagger包

composer require "darkaonline/swagger-lume 1.*"

二、为swagger配置lumen

// bootstrap/app.php
$app->withFacades();
 
// add this line before Register Container Bindings section:
$app->configure('swagger-lume');
 
// add this line in Register Service Providers section:
$app->register(\SwaggerLume\ServiceProvider::class);

三、配置及生成swagger

php artisan swagger-lume:publish-config (config/swagger-lume.php)
php artisan swagger-lume:publish
php artisan swagger-lume:generate

四、指定swagger路由

//config/swagger-lume.php
'routes' => [
    'api' => 'api-docs', // from 'api/documentation'
    'docs' => 'docs',
],

五、设置自动更新文档

//config/swagger-lume.php
 'generate_always' => env('SWAGGER_GENERATE_ALWAYS', true),

如果不设置,要手动执行swagger-lume:generate命令,文档才能看到最新变化。

Lumen

安装

安装composer

https://getcomposer.org/download/ 上下载安装文件。

利用Composer下载Lumen安装器

composer global require "laravel/lumen-installer=~1.0"

安装时包名写错了,留下包痕迹清除不了,把composer卸载,重新安装后,才能用正确的包名安装lumen。

创建Lumen运用程序

通过lumen new命令就能在你指定的目录中创建一个干净的Lumen应用程序骨架了。

lumen new app_name

部署到Web服务器

Lumen 几乎不需要任何配置就能开箱即用。你能立即开始你的编码工作了!

Lumen (5.2.8) (Laravel Components 5.2.*)

base64

杂项

指定302跳转

use Illuminate\Http\RedirectResponse;
return redirect('/userInfo', 302); //默认为301

技术文章收藏

十个Laravel5程序优化技巧

如何查看 Laravel 5 的所有数据库请求