Laravel一些小技巧记录

最近在用Laravel5.5.26开发项目的时候, 得到一些小小的心得, 为方便以后查找使用, 在这里记录一下。

获取当前URL的路由名称:

$curRouteName = Route::currentRouteName();

定义路由的时候,同一个请示地址, 要把单独的请求放在Resource上面:

//获取权限菜单下子菜单
Route::post( 'permissions/publicGetSubMenus', 'PermissionsController@getSubMenus' )->name( 'permissions/publicGetSubMenus' );
Route::resource( 'permissions', 'PermissionsController' );

定义连接的时候,尽量用路由的名称,这样不论控制器怎么变, 链接永远是正确的链接:

{{route('home.quite')}}

开发自己的扩展包:

虽然实际开发中没有用到, 但是基本掌握了Laravel扩展包开发的基本流程, 来看一步骤:

1.定义Composer自动加载

"psr-4": {
  "App\\": "app/",
  "Zlong\\Laratest\\":"packges/zlong/Laratest/src/"
},
2.在app同级目录下, 建立目录,【packges/zlong/Laratest/src/】
3.新建一个服务提供者文件, LaratestServiceProvider.php, 继承 ServiceProvider,在这个服务提供者里面, 我们可以自定义路由,加载视图,语言包等操作
记得执行composer dumpautoload

接下来, 介绍一下定义路由和加载视图:

首页要加载此服务提供者, 编辑config/app.php,在providers数据加入,

Zlong\Laratest\LaratestServiceProvider::class

在boot方法内, 我们定义一个路由,

//自定义一个路由
$router = app( 'router' );
$config = [];
$config['namespace'] = __NAMESPACE__;
$router->group( $config, function ( $router ) {
    $router->get( 'laratest', function () {
        echo 'Hello, laratest';
    } );
} );

然后, 我们来看一下结果:

加载视图
首页要在packges/zlong/Laratest/src/目录下面新建views/laratest/header.blade.php ,

然后要在服务提供者内加入以下代码, 用来加载视图, 和发布视图

//加载视图
$this->loadViewsFrom( __DIR__ . '/../views/', 'Laratest' );
//发布,发布的时候要用 php artisin vendor:publish 来发布, 发布成功以后, 文件会被复制到resource/views/vendor/laratest/laratest/header.blade.php
$this->publishes([
    realpath(__DIR__ . '/../views/') => base_path('resources/views/vendor/laratest')
],'view');

提示:当请求一个扩展包的视图时,Laravel 会在第一时间检查 resources/views/vendor/下 是否有开发者提供的自定义版本视图存在,如果这个路径没有自定义的视图,Laravel  会搜索你在扩展包 loadViewsFrom 方法里所指定的视图路径

调用扩展包的视图

@include('Laratest::laratest.header');

自动加载公用函数文件:

在composer文件内autoload数组内加入

"files": [
  "helper/common_helper.php"  //文件位置app同级目录, helper/common_helper.php,记得执行composer dumpautoload
]

缓存开关

这个主要目的是在用到缓存的时候,如果是在本地开发, 也一直启用缓存, 那在开发调试的时候,有点麻烦, 在看Xblog 的时候,受到了启发, 本地开发的时候, 可以不开启缓存, 放到线上的时候,启用缓存。

定义接口文件:

namespace App\Repertory;

use Closure;

interface CacheSwitch
{
    public function setTag ( $tag );

    public function remember ( $key, Closure $entity, $tag = null );

    public function forget ( $key, $tag = null );

    public function clearCache ( $tag = null );

    public function clearAllCache ();
}

本地开发继承:CacheDisable

namespace App\Zl\Cache;


use App\Repertory\CacheSwitch;
use Closure;

class CacheDisable implements CacheSwitch
{
    public function setTag ( $tag )
    {
        // Do Nothing
    }

    public function remember ( $key, Closure $entity, $tag = null )
    {
        return $entity();
    }

    public function forget ( $key, $tag = null )
    {
        // Do Nothing
    }

    public function clearCache ( $tag = null )
    {
        // Do Nothing
    }

    public function clearAllCache ()
    {
        // Do Nothing
    }

}

线上开发继承:CacheEnable

namespace App\Zl\Cache;


use App\Repertory\CacheSwitch;
use Closure;

class CacheEnable implements CacheSwitch
{
    public $tag;
    public $cacheTime = 0;

    public function setTag ( $tag )
    {
        $this->tag = $tag;
    }

    public function remember ( $key, Closure $entity, $tag = null )
    {
        $this->cacheTime = config( 'cache.expire' );

        return cache()->tags( $tag == null ? $this->tag : $tag )->remember( $key, $this->cacheTime, $entity );
    }

    public function forget ( $key, $tag = null )
    {
        cache()->tags( $tag == null ? $this->tag : $tag )->forget( $key );
    }

    public function clearCache ( $tag = null )
    {
        cache()->tags( $tag == null ? $this->tag : $tag )->flush();
    }

    public function clearAllCache ()
    {
        cache()->flush();
    }
}

在AppServiceProvider中加入

//缓存开关
$this->app->singleton( 'Zcache', function () {
    if ( config( 'cache.enable' ) ) {
        return new CacheEnable();
    } else {
        return new CacheDisable();
    }
} );
//写入:app('Zcache')->remember('testkey', function(){}, 'tag');
//删除:app('Zcache')->forget('testkey', 'tag');

自定义Ajax请求时返回的信息

有时候, 我们需要有这样的需求,  提交表单,或是注册的时候,会根据我们提供的验证规则,返回Json信息, 返回的Json信息类似是这样的:

这样形式, 获取错误信息不是很方便。

我想要实现有错误直接返回错误信息, 这样更直接, 我是通过这种方式实现的。

编辑:app/Exceptions/Handler.php,加入这个函数

 protected function invalidJson ( $request, ValidationException $exception )
    {
        foreach ( $exception->errors() as $k => $r ) {
            if ( !empty( $r[0] ) ) {
                $error = $r['0'];

                return \Ajax::fail( $error ); //Ajax方法请参考:https://www.cnblogs.com/yjf512/p/4434106.html
            }
        }
    }

 

侧栏

网站一般都有侧栏,用来显示分类,标签,热门文章,热门评论啥的,但是这些侧栏都是相对独立的模块,如果在每一个引入侧栏的视图中都单独导入与视图有关的数据的话,未免太冗余了。。。所以最佳的做法是:新建一个widgets视图文件夹,再利用Laravel 的ViewComposers单独为侧栏绑定数据,这样侧栏就可以随便引入而不用关心数据是否绑定啦~~~

举个栗子?拿最常用的分类侧栏来说,在resources/views/widgets下新建你的分类侧栏视图文件categories.blade.php

<div class="widget widget-default">
    <div class="widget-header"><h6><i class="fa fa-folder fa-fw"></i>分类</h6></div>
    <ul class="widget-body list-group">
        @forelse($categories as $category)
            @if(str_contains(urldecode(request()->getPathInfo()),'category/'.$category->name))
                <li href="{{ route('category.show',$category->name) }}"
                    class="list-group-item active">
                    {{ $category->name }}
                    <span class="badge">{{ $category->posts_count }}</span>
                </li>
            @else
                <a href="{{ route('category.show',$category->name) }}"
                   class="list-group-item">
                    {{ $category->name }}
                    <span class="badge">{{ $category->posts_count }}</span>
                </a>
            @endif
        @empty
            <p class="meta-item center-block">No categories.</p>
        @endforelse
    </ul>
</div>

新建app/Http/ViewComposers文件夹,然后创建CategoriesComposer.php

<?php
namespace App\Http\ViewComposers;
use App\Http\Repositories\CategoryRepository;
use Illuminate\View\View;
class CategoriesComposer
{
    public function __construct(CategoryRepository $categoryRepository)
    {
        $this->categoryRepository = $categoryRepository;
    }

    public function compose(View $view)
    {
        $categories = $this->categoryRepository->getAll()->reject(function ($category) {
            return $category->posts_count == 0;
        });
        $view->with('categories', $categories);
    }
}

再在app/Providers文件夹下新建ComposerServiceProvider.php文件:

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
class ComposerServiceProvider extends ServiceProvider
{

    public function boot()
    {
        View::composer('widget.categories', 'App\Http\ViewComposers\CategoriesComposer');
    }

    public function register(){}
}

最后别忘了在config/app.php中的providers数组中添加App\Providers\ComposerServiceProvider::class啊。好了,现在你可以随时随地@include('widget.categories')了。对了,要善于在ViewComposer中利用Collection强大方法进行数据处理幺~~

0

发表评论

电子邮件地址不会被公开。