Laravel工作汇总问题

摘要:汇总整理一些工作中遇到的容易忽略的问题。

中间键在闭包中可以使用,但是在方法中不能使用

如下图,两种调用方式

Route::group(['middleware'=>'check_jwt'],function(){
    Route::get('/user2',function(){
        return 'ok';
    });
    Route::get('/user','User\UserController@test');
});

经过排查是因为这里UserController 继承了BaseController同时使用了构造方法__controller,而构造方法的优先级是高于中间键的,所以造成了中间键失效。这里采用的解决办法是在构造方法中使用if过滤掉不存在的情况

if($request->header('Authorization'))

Syntax error or access violation: 1071


    方法1:升级MySql版本到5.5.3以上。

    方法2:手动配置迁移命令migrate生成的默认字符串长度,在AppServiceProvider中调用Schema::defaultStringLength方法来实现配置:

        use Illuminate\Support\Facades\Schema;

        public function boot()
        {
           Schema::defaultStringLength(191);
        }

Create插入数据

1、需要设置fillable或者$guarded属性否则不允许操作
2、需要创建对应的模型
3、只能插入一条数据,不能插入多条

4、DB::table('actions')->insert($actions); 用这个代替的时候不会自动插入created_at和updated_at字段

在父级BaseController中跳转失败

在父级中使用redirest跳转,会仍然是之前的页面。
这时候需要添加send方法
redirect('/erp')->send();

生成静态html

    	$test = '666666';
    	$string = view('welcome',compact('test'))->__toString();
    	file_put_contents('webTest/indexTest.html',$string);

此时生成文件会在public下的webTest目录下

网站切换多语言(使用session)

1、设置语言

	config/app.php 中设置主语言及备用语言
    	'locale' => 'en',
    	'fallback_locale' => 'zh_cn',

2、模版中设置对应切换语言的入口

         "{{ url('/changeLocale/en') }}">en
         "{{ url('/changeLocale/zh_cn') }}">zh

3、创建对应路由及方法
	
    Route::get('/changeLocale/{locale}','Test\TestController@changeLanguageTest');

    public function changeLanguageTest($locale)
    {
        if (in_array($locale, ['en', 'zh_cn'])) {
            session()->put('locale', $locale);
        }
        return redirect()
            ->back()
            ->withInput();
    }
4、创建对应中间键

	php artisan make:middleware SetLocaleLanguage

5、设置中间件

    public function handle($request, Closure $next)
    {
        if (\Session::has('locale') && in_array(\Session::get('locale'), ['en', 'zh_cn'])) {
            \App::setLocale(\Session::get('locale'));
        } else {
            session()->put('locale', 'en');
            \App::setLocale('en');
        }
        return $next($request);
    }
    (这里session及app 的 Facade需要使用全局命名空间\ 否则会报错对应class not found)

 6、注册中间键

	protected $routeMiddleware = [
		...
		'setLocale' => \App\Http\Middleware\SetLocale::class,
		...
	];

7、注册多语言文件

	resourcelang 注册编写对应语言包及语言包文件
	php
		return [
			'test'=> '测试',
		];

8、路由中使用

	Route::group(['middleware' => ['SetLocalLanguage']], function() {
		Route::get('/', function () {
	    		return view('welcome');
		});
	});

9、前台模版调用

	"">{{ trans('test.test') }}
         (第一个参数数文件名第二个参数是数据名)
	
	


展示原始信息(old函数)

return \Redirect::back()->withInput()->withErrors('Account password error');
需要使用withInput
前台使用{{old('field')}}

修改laravel自带的分页样式

php artisan vendor:publish

会将对应文件生成后放到views下的vendor中,只需进行修改即可

不使用用view composer进行其他页面的渲染

header使用@yield('seoHeader')
在详情页使用
@section('seoHeader')
    @if($configs)
        {{$configs[<span class="hljs-string">'seo_title'</span>]}}<<span class="hljs-regexp">/title>
        <meta name="keywords" content="{{$configs['seo_keywords']}}">
        {!! $configs['seo_web_js'] !!}
        {!! $configs['seo_page_js'] !!}
    @else
        <title>Greenshine</</span>title>
        <span class="xml"><span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"keywords"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Greenshien streetlight"</span>></span>
    @endif
@endsection
</span></code></pre><p><br></p></div>

Ajax发送delete请求


       $('.laravelDelete').on('click',function (evt) {
           evt.preventDefault();
           var url = $(this).attr('href');
           var type='DELETE';
           $.ajax({url,type}).then(function(v){
               console.log(v);
               location.reload();
           })

       })

Ajax发送非GET请求

1、设置header
<meta name="csrf-token" content="{{csrf_token()}}">
2、设置全局Ajax
$.ajaxSetup({
headers:{
'X-CSRF-TOKEN':$('meta[name="csrf-token"]').attr('content')
}
}); 3、设置具体ajax 在html中使用onclick出发,不用jq绑定类触发 $.post('/greenshine/ftps/testConnect',formData,function(v){
console.log(v);
});

在搜索后再进行分页,会让分页把搜索信息重置

 $files = Media::where('media_url', 'like', "%$mediaName%")->paginate(1);
        $files->withPath("/greenshine/medias?name=$mediaName");
使用withpath就可以处理

模型关联后报错

Call to a member function addEagerConstraints() on null

其实是 在模型中 定义的关联的地方没有写return

判断表是否有某个字段

use Illuminate\Support\Facades\Schema;

            if(Schema::hasColumn($value->module_table,'deleted_at')){
                dd(1);
            }else{
               dd(2);
            }

预加载With与select造成数据为null

            $data = Blog::with(
                ['categories'=>function ($query) {
                    $query->select('sc_blogs_categories.title');
                },'author'=>function ($query) {
                    $query->select('sc_authors.id', 'sc_authors.name');
                }]
            )
                ->select('id', 'title', 'author_id','seo_url', 'created_at', 'updated_at')
                ->where('website', $request->query('website')?:'')
                ->where('title', 'like', '%' . $request->query('title')?:'' . '%')
                ->orderBy('id', 'desc')
                ->paginate(
                    $request->query('pageSize')?:10,
                    ['*'],
                    'page',
                    $request->query('pageIndex')?:1
                );
需要在select的里面增加对应关联ID
在用 laravel 开发时,要关联模型查询和 with 预加载做统计。因为是统计所以并没有全部查出所有字段的必要。故我在 with 中用闭包 $query->select (' 字段名’'); 但是在查询后结果是 null。也就是说关联不上。
为什么呢?我终于在网上找到答案:不管一对一,一对多等等,laravel 的关联查询的原理简单来说就是先分别查出模型自身的数据和关联模型的数据,在根据你定义的主键 id 和外键_id 进行关联起来组成查询结果。所以呢,模型自身的数据在 select 时的必需字段必须要有定义关联是的主键 id(或自定义的关联字段),同样,关联模型的数据在 select 时的必需字段也要有定义关联时的外键_id (或自定义的关联字段).
在 with 中用闭包时 $query->select (' 自已想要的字段名 '. ' 定义的关联字段_id'); 模型自身在 ->select (' 至少要有关联的字段 id');


评论
  • 2019-12-18 18:38:30 by Eric-上海奥深商务咨询有限
    上面的修改不起作用,最后采用web.php中将对应方法改为了PUT
  • 2019-12-18 18:33:54 by Eric-上海奥深商务咨询有限
    formData = formData.splice(1); 将不要的值给去掉
  • 2019-12-18 18:31:24 by Eric-上海奥深商务咨询有限
    {{method_field('PUT')}} 会在form里面增加一条input name为_method值为PUT,这时候JQserializeArray();会拿到这个值,在ajax提交的时候方法就变成了PUT造成一个申请的bug
  • 2019-12-18 17:40:11 by Eric Guo
    <meta name="_token" content="{{ csrf_token() }}"/> 去掉会造成报错419