DB::chunk()

  1. chunk 方法必须要使用orderBy设置一个排序字段(该字段最好是存在索引,速度较快)。
  2. chunk 方法是根据 limit 和 order by 关键字查询数据的这里就涉及到分页查询的问题所以需要排序字段。
  3. chunk 方法中不能删除当前查询表的数据,这样会导致查询数据混乱。
// sql: select `product_id`,`sku` from `oc_product` where `sku` like '%-bingshopping' order by `sku` asc
// 这里查询oc_product表sku后缀xxxxshopping相关数据 
DB::connection('mysql_us')
    ->table('oc_product')
    ->select(['product_id','sku'])
    ->where('sku','like','%xxxxshopping')
    ->orderBy('sku','ASC')
    ->orderBy('product_id','ASC')
    ->chunk(50, function($datum) use ($bar){
        foreach ($datum as $item){
            // 删除数据 这里又删除查询出来sku后缀xxxxshopping相关数据 
            // 这样会导致存在部分数据被删除 (主要是limit分页的页数在逐渐增大 会到某一个值page查不到数据)
            $this->delete($item->product_id, $item->sku);
        }

        $bar->advance();
    });

迁移

  1. 执行 php artisan migrate 数据库迁移,报错 Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email))
  2. 相关代码:
public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
}
  1. 以上是user表的migartion,可以看出name字段并没有声明长度,laravel默认了1071,而报错中看出数据库设置了最大是767,所以就报错了。
  2. Laravel 5.4默认使用utf8mb4字符编码,而不是之前的utf8编码。mb4的最大字符长度为4个字节,解决方法是手动配置迁移命令migrate生成的默认字符串长度,在AppServiceProvider中调用Schema::defaultStringLength方法来实现配置:
use Illuminate\Support\Facades\Schema;

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
   // 767/4  
   Schema::defaultStringLength(191);
}
  1. 参考:https://www.cnblogs.com/lindoubao/p/7231400.html

路由

  1. 路由比较多时会出现如下问题:模糊的路由包含了精确的路由。
<?php

use Illuminate\Support\Facades\Route;

Route::group(['prefix' => 'forum'], function($router){
    // 帖子 资源路由
    Route::resource('topics', 'TopicsController', ['only' => ['index', 'create', 'store', 'update', 'edit', 'destroy']]);

    // 编辑器上传接口
    Route::post('topics/upload_image', 'TopicsController@uploadImage')->name('topics.upload_image');

    // 帖子详情页 topic 帖子 id
    Route::get('topics/{topic}/{slug?}', 'TopicsController@show')->name('topics.show');

    // 帖子搜索功能 这个路由跟'topics/{topic}/{slug?}'重复 导致总是找不到方法
    Route::get('topics/search/topics', 'TopicsController@search')->name('topics.search');

    // 帖子点赞
    Route::post('topics/addFabulous/{topic_id?}/{fabulous?}', 'TopicsController@addFabulous')->name('topic.addFabulous');
});

缓存

  1. 配置文件缓存,php artisan config:cache 命令缓存./config目录下的所有配置文件到./bootstrap/cache/config.php里面。
  2. ./config目录配置文件存在闭包函数,缓存不能被执行。
  3. 缓存源码:
public function handle()
{
    // 执行清除缓存命令 就是删除config.php文件
    $this->call('config:clear');
    // 获取./config 配置文件信息 返回数组的形式
    $config = $this->getFreshConfiguration();
    // 获取需要缓存的路径./bootstrap/cache/config.php
    $configPath = $this->laravel->getCachedConfigPath();
    // 数据写入 var_export($config, true) 返回合法的php代码 参考该php函数
    $this->files->put(
        $configPath, '<?php return '.var_export($config, true).';'.PHP_EOL
    );

    try {
        require $configPath;
    } catch (Throwable $e) {
        $this->files->delete($configPath);

        throw new LogicException('Your configuration files are not serializable.', 0, $e);
    }

    $this->info('Configuration cached successfully!');
}

artisan

  1. -- 参数 如 --email 必须使用 option 或 options获取。
protected $signature = 'user:founder {--E|email=admin@admin.com : user email} {--Q|password=admin : user password}';

// 使用如下方法获取
$email = $this->option('email');
$password = $this->option('password');

// argument获取不带 `--` 参数的项
$this->argument('user')
  1. 使用table方法:
// 第二个参数是一个二维数组
$this->table(['email'], [['email'=>$email]]);

门面冲突

  1. 在使用laravel的开源论坛中遇到这么一个问题:Non-static method Redis::hSet() cannot be called statically。
  2. 问题原因在于 使用在Laravel中使用Redis时,都很喜欢用门面的形式 这导致冲突发生。
$redis = Redis::get('xxxx');
# 可能php安装勒redis扩展 而laravel又安装勒predis第三方包 导致系统不知如何寻找发生冲突
  1. 解决:
# 1. 所有的Redis使用完整的命名空间路径 如
$redis = Illuminate\Support\Facades\Redis::Redis::get('xxxx');

模型事件

// creating, created, updating, updated, saving,
// saved,  deleting, deleted, restoring, restored

// Eloquent 模型事件 触发机制 以下事件都是针对(单个)模型处理
// 触发Model事件需要先从数据库获取数据再操作时候才会触发
// saving   saved       Model调用save()方法新增或保存数据时被触发  update() create()
// deleting deleted     Model调用delete()方法删除数据时被触发
// creating created     Model调用save()方法新增数据时被触发 create()
// updating updated     Model调用save()方法保存数据时被调用 当前Model在数据库中存在时候    update()
// restoring restored   Model调用restore()方法恢复软删除模型被触发
// retrieved            从数据库中获取已存在的模型后触发 获取单个模型对象时(比如动作的依赖注入,first()获取数据find(1)获取等)
// forceDeleted         Model调用forceDelete()方法强制永久删除单个模型后被调用

mergeBindings

  1. 使用了mergeBindings后面不能够跟条件查询和join等其他方法,$queryVideos->toSql() 返回的是不带参数的sql,$queryVideos->getQuery()则是返回的完整sql数据。
$queryVideos = $this->thereIsASourceDoctor($watchedVideoIds)->unionAll($this->NoSourceDoctor($watchedVideoIds));

return \DB::connection('mingyi_v7')->table(\DB::raw("({$queryVideos->toSql()}) as a"))->mergeBindings(queryVideos->getQuery())
    -> groupBy('id')
    ->get([
        'id',
        \DB::raw("SUM(visit_remain_num) as `visit_remain_num`"),
        \DB::raw("SUM(video_specification) as `video_specification`"),
    ]);