2016年9月30日 星期五

为迁移中的时间字段添加默认当前时间

$table->timestamp('something_at')->default(DB::raw('CURRENT_TIMESTAMP'));

from : http://laravel.so/tricks/dfdd910723f5e375a53170f04dcdf786

使用中间件禁用浏览器缓存

我们想要在部分路由上完全禁用浏览器缓存,比如验证码,或者其它要求不能在浏览器端缓存的页面,我们可以建立如下一个中间件来完成:
app/Http/Middleware/NoHttpCache.php:
 namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Routing\Middleware;

use Illuminate\Http\Response;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;

class NoHttpCache implements Middleware {

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // This step is only needed if you are returning
        // a view in your Controller or elsewhere, because
        // when returning a view `$next($request)` returns
        // a View object, not a Response object, so we need
        // to wrap the View back in a Response.
        if ( ! $response instanceof SymfonyResponse) {
            $response = new Response($response);
        }

        /**
         * @var  $headers  \Symfony\Component\HttpFoundation\HeaderBag
         */
        $response->header('Pragma', 'no-cache');
        $response->header('Expires', 'Fri, 01 Jan 1990 00:00:00 GMT');
        $response->header('Cache-Control', 'no-cache, must-revalidate, no-store, max-age=0, private');

        return $response;
    }
}
然后在 app/Http/Kernel.php 中 $routeMiddleware 中注册它就可以在路由中使用了:
...
use App\Http\Middleware\NoHttpCache;
...

/**
 * The application's route middleware.
 *
 * @var array
 */
protected $routeMiddleware = [
    'no_http_cache' => NoHttpCache::class,
];
在 routes.php 中对要禁用缓存的路由添加中间件:
Route::get('foo/bar', ['middleware' => 'no_http_cache', function () {
    // ...
}]);

from : http://laravel.so/tricks/e63b9350fa54e48e58f60a8e32c372d7

Laravel 中使用 Vue 组件化开发(配置)

现今前端组件化开发、MVVM 模式,给开发带来了很多的便利,可读性、可维护性更高。然而自 Laravel 5.3 开始,VueJS 成为框架默认的标配。
本文基于 Laravel 5.1 LTS 版本引入 Vue 2.0 进行配置。
我已在 Github 配置好, Laravel 5.1 和 Laravel 5.2 均有,Clone 下来后按照 README 安装依赖后即可用:https://github.com/jcc/vue-laravel-example

步骤一:配置 package.json

  1. 在根目录下修改 package.json, 可在 devDependencies 下配置你所需的所有依赖。我的配置如下:
     {
       "private": true,
       "scripts": {
         "prod": "gulp --production",
         "dev": "gulp watch"
       },
       "devDependencies": {
         "bootstrap-sass": "^3.3.7",
         "gulp": "^3.9.1",
         "jquery": "^3.1.0",
         "laravel-elixir": "^6.0.0-9",
         "laravel-elixir-vue": "^0.1.4",
         "laravel-elixir-webpack-official": "^1.0.2",
         "laravel-elixir-browsersync-official": "^1.0.0",
         "lodash": "^4.14.0",
         "vue": "^2.0.0-rc.2",
         "vue-resource": "^0.9.3",
         "vue-router": "^2.0.0-rc.3"
       }
     }
    
  2. 安装配置的依赖,在根目录下,运行:
    $ npm install
    
    当然你可以通过 npm install {package_name} --save-dev 的方式安装你所需的包。

步骤二:配置 gulpfile.js

Laravel 5.1 的 gulpfile.js 内容如下:
  var elixir = require('laravel-elixir');

  elixir(function(mix) {
      mix.sass('app.scss');
  });
可见还没使用 ES6 的语法,因此我们修改如下:
  const elixir = require('laravel-elixir');

  require('laravel-elixir-vue');

  elixir(mix => {
    mix.webpack('main.js');
  });
mix.webpack('main.js') 是将 resources/assets/js 下的所有文件进行编译合并,合并到 public/js/main.js 文件。

步骤三:配置 Vue 并创建基础例子

  1. 在 resources/assets 文件夹下 创建 js/main.js 文件,该文件主要引入 vue 、vue-router 等所需的包。
    main.js
     import Vue from 'vue/dist/vue.js'
     import App from './App.vue'
     import VueRouter from 'vue-router'
    
     Vue.use(VueRouter)
    
     import Example from './components/Example.vue'
    
     const router = new VueRouter({
       mode: 'history',
       base: __dirname,
       routes: [
         { path: '/example', component: Example }
       ]
     })
    
     new Vue(Vue.util.extend({ router }, App)).$mount('#app')
    
    由于 vue-router 需要 Vue.js 0.12.10+ 并不支持 Vue.js 2.0,因此以上的是根据 vue-router v2.0.0+ 的版本配置,配置跟 0.12.10+ 有明显区别。
  2. 在 js 文件夹下创建 App.vue 文件
    App.vue
     
    
  3. 在 js 文件夹下创建 components/Example.vue 文件
    Example.vue
     
    
     
    
    到此 vue 的配置已完成,接下来需要配置一下 Laravel, 让 Laravel 成功引导到 Vue

步骤四:定义路由、编译合并 JS 代码

  1. 定义路由,在 app/Http/routes.php 加入:
     Route::get('example', function () {
         return view('example');
     });
    
  2. 创建 example.blade.php 模板
     
     
     
       
       Example
     
     
       
  3. 编译合并 JS 代码
    在命令行下,输入:
     $ gulp
    
    如需实时编译,可输入 gulp watch

步骤五:访问

最后通过浏览器访问:http://laravel.app/example
vue-laravel-example
Laravel5.1 + Vue2.0 组件化配置
https://github.com/jcc/vue-laravel-example

from : http://laravel.so/tricks/7986d4d1e325f5ac849f14e47c36caa4

如何使用 created_at 以外的 Model 时间戳

有时候我们在一个已有的数据库上使用 laravel 进行开发,通常表的创建和更新时间的字段名并不是created_atupdated_at,也有时候只有一个创建时间而没有更新时间,那么我们在 model 定义的时候怎么处理呢?
这个时候可以用 model 的 boot() 方法
public static function boot()
{
    static::creating(function ($model) {
        $model->created = $model->freshTimestampString();
    });
    static::updating(function ($model) {
        $model->updated = $model->freshTimestampString();
    });
}
这样就可以使用自定义的时间戳字段名了,如果只有created的话,就去掉下面的static::updating

from : http://laravel.so/tricks/c0839ff6d1838fe3388f075ae31ed41b

Laravel 框架启动过程

详细的了解 laravel 框架的启动过程,有助于我们在不同的启动阶段进行扩展性的开发

1、入口文件

index.php
导入 composer 自动加载功能 ./bootstrap/autoload.php

2、启动文件

导入 laravel 容器 ./bootstrap/app.php
  1. 启动容器
    1. 注册容器自身(registerBaseBindings)
    2. 注册事件系统和路由系统(registerBaseServiceProviders)
    3. 注册 laravel 自有类别名(registerCoreContainerAliases)
  2. 注册 Http 处理器
  3. 注册 Cli 处理器
  4. 注册异常处理器

3、Http 处理器

  • 启动 Http 处理器:Illuminate\Contracts\Http\Kernel->handle($request)
  • 进入 Http 请求处理工作:Illuminate\Contracts\Http\Kernel->sendRequestThroughRouter
    1. 重新在容器中绑定 request
    2. 启动并配置 HTTP 相关的服务组件(Illuminate\Foundation\Bootstrap* 中的所有组件)
       启动顺序:
       1. DetectEnvironment Dotenv 配置
       2. LoadConfiguration Config 配置 (/bootstrap/cache/config.php 或者 /config/*)
       3. ConfigureLogging 日志系统配置
       4. HandleExceptions php报错配置
       5. RegisterFacades 注册外观
       6. RegisterProviders 注册用户服务提供器
       7. BootProviders 启动所有提供器
      
    3. 路由管理器 Pipeline :
      穿过全局中间件 $middleware
      Router->dispatch(Request $request);
      Router->dispatchToRoute(Request $request);
      Router->runRouteWithinStack(Route $route, Request $request)
    4. 匹配到路由 Pipeline :
      穿过路由中间件 $routeMiddleware
      Route->run(Request $request)
      Route->runController(Request $request)
      Controller->method()
    5. 业务逻辑
      • 处理反射
      • 用户业务逻辑
    6. 处理 Response
      • 字符串
      • 普通 Response
      • 跳转 Response
      • JsonResponse
      • ViewResponse

4、请求返回

  1. 应答对象发送到浏览器 $response->send();
  2. 运行可终止中间件(可终止中间件会是新的中间件实例,除非中间件被设置为单例模式)
  3. 应用终止后处理 Illuminate\Contracts\Http\Kernel->terminate($request, $response)

from : http://laravel.so/tricks/e977de4b9aab434e1fa66cec77f25f19

路由参数全局正则表达式模式

Route::pattern('id', '\d+');
Route::pattern('hash', '[a-z0-9]+');
Route::pattern('hex', '[a-f0-9]+');
Route::pattern('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}');
Route::pattern('base', '[a-zA-Z0-9]+');
Route::pattern('slug', '[a-z0-9-]+');
Route::pattern('username', '[a-z0-9_-]{3,16}');

from : http://laravel.so/tricks/042601cd52bb6605c5d9a35e95b89afa

怎么注册单例对象?

$this->app->singleton('foo', function()
{
    return new Foo();
});
\App::make('foo');  // 得到单例对象
使用 singleton 方法注册的对像只会在初次调用时初始化,后续的多次调用都是首次实例而不是重新创建。

from : http://laravel.so/tricks/5fc78cb10c4a097ea4f03390e66c13bf

获取模型修改前的原始值

我们经常会有这样的需求:当一个模型的属性修改后(写入数据库前),我们想看看之前的原始值。
比如像 GitHub issue 就是个典型的例子:https://github.com/overtrue/wechat/pull/81
overtrue changed the title from "wechat payment wike" to "[wiki] wechat payment" 20 hours ago
我把这个 issue 的标题从 "wechat payment wike" 改成了 "[wiki] wechat payment"。
我们在 Laravel 里这种东西通常使用 Eloquent 事件来记录修改日志:
Issue::saving(function(Issue $issue){
    if ($issue->isDirty('title')) {
        $user = Auth::user()->username;
        $oldTitle = $issue->getOriginal('title'); // 原始值
        $newTitle = $issue->title;   // 新值
        ActionLog::log("$user 把标题 $oldTitle 修改为 $newTitle");
    }
});
上面的关键在于 $issue->getOriginal('title') 用于获取修改前的值。
上面我使用了 Issue 模型的 saving 事件,当然这里的 ActionLog::log() 只是一个示例,至于你存到哪儿你随意。

from : http://laravel.so/tricks/f1bce76e72738b46465ac001e419b082

如何临时禁用模型 观察者

在开发过程中我们会遇到需要临时禁用模型监听器的情况,比如有这么一个例子:
使用定义了一个订单模型的观察者:
// OrderObserver.php


namespace App\Observers;

use App\Order;
use App\Services\SMS;
use Illuminate\Http\Request;

/**
 * Order observer.
 */
class OrderObserver
{

    /**
     * After order created.
     *
     * @param Order $order
     */
    public function created(Order $order)
    {
        (new SMS())->send('order_created', $order->consumer_phone, [$order->no]);
    }
}
它监听了一个 created 事件,即在订单创建后给用户发个短信。
在使用 faker 在 db:seed 填充数据的时候,我们是不需要给用户发短信的,这时候我们就希望能临时禁用掉观察者。
在 Laravel 模型里其实已经预留了一个方法:Model::unsetEventDispatcher(); 可以移除事件调度器。我们就可以在 seed 文件里使用它来完成了这个需求了:
Order::unsetEventDispatcher();

factory(App\Order::class, 10)->create(); // 创建10条假订单

from : http://laravel.so/tricks/f510d6530c7736f24c9398ac3b647aad

wibiya widget