模型

模型重载

refresh 方法使用数据库中的新数据重新赋值现有模型。
此外,已经加载的关系会被重新加载$model->refresh();

模型复制

$newModel= Model::first()->replicate();
$newModel->save(); // 记得save(),replicate()创建出来是一个new Model的数据

无级分类及展示

用于筛选的数据展示

public static function getTreeForApi()
{
    return self::treeValues(self::getTree());
}

private static function treeValues($lists, $id = null)
{
    $data = [
        [
            'id' => $id,
            'value' => '全部',
            'children' => null
        ]
    ];
    foreach ($lists as $key => $list) {
        $data[] = [
            'id' => $list['id'],
            'value' => $list['value'],
            'child' => count($list['child']) > 0 ? self::treeValues($list['child'], $list['id']) : null
        ];
    }
    return $data;
}

无级分类核心代码 可用于非Laravel

public static function getTree()
{
    $lists = Model::select(['id', 'value', 'parent_id'])
        ->orderBy('parent_id')
        ->orderBy('sort')
        ->get()
        ->keyBy('id')
        ->toArray();
    foreach ($lists as $list) {
        !isset($lists[$list['id']]['child']) && $lists[$list['id']]['child'] = [];
        $lists[$list['parent_id']]['child'][$list['id']] = &$lists[$list['id']];
    }
    return isset($lists[0]['child']) ? $lists[0]['child'] : [];
}

A(一)对B(多)下以B为排序主体的sql分页查询

$lists = A::leftJoin(DB::raw('(' . B::groupBy('where_id')->toSql() . ') as ' . config('database.connections.mysql.prefix') . 'b_name'),
    'a.where_id',
    '=',
    'b_name.where_id')
    ->orderBy('b_name.sort')
    ->paginate(request('per_page'));

实例化云图片

app('filesystem.cloud')

Laravel Excel 导入的时间问题

遇到导入的值是双精度double(类似于43976.590393519)类型的时候需要函数来处理
代码综合来自https://github.com/Maatwebsite/Laravel-Excel/issues/1832

/**
     * @param $value
     * @param string $format
     * @return Carbon\Carbon|string
     * @throws Exception
     */
    function format_date_excel($value, $format = 'Y-m-d H:i:s')
    {
        try {
            if (gettype($value) === 'double') {
                $time = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
                return $time->format($format);
            }
            return \Carbon\Carbon::createFromFormat($format, $value)->format($format);
        } catch (\ErrorException $e) {
            return \Carbon\Carbon::createFromFormat($format, $value)->format($format);
        }
    }

Laravel Excel 导入的时间问题

场景是在使用guzzle(curl)函数后,Carbon所有的函数时间都是错误的,后来查到是我请求的服务器的时间是GMT,数据返回后Carbon的时间函数就错误了,至于为什么会这样的,没有深入研究。在网上查到Carbon是使用date_default_timezone_set()来设置时区的链接
解决方案很简单

date_default_timezone_set(config('app.timezone'));

这段代码放在最合理放在哪里没有具体研究我放在guzzle请求之前的话是生效的

递归笛卡尔积函数

原始方法代码(不带键)
    public $products = [];

    public function carteSian(array $params, array $temporary = [])
    {
        foreach (array_shift($params) as $param) {
            array_push($temporary, $param);
            $params ? $this->carteSian($params, $temporary) : array_push($this->products, $temporary);
            array_pop($temporary);
        }
    }
function 方法改造(带数组键)
function cartesian(array $allParams, array $temporary = [], &$products = [])
    {
        $k = array_key_first($allParams);
        $params = $allParams[$k];
        unset($allParams[$k]);
        foreach ($params as $param) {
            Arr::set($temporary, $k, $param);
            $allParams ? cartesian($allParams, $temporary, $products) : array_push($products, $temporary);
            array_pop($temporary);
        }
        return $products;
    }

PHP创造一个空对象

new stdClass()

Laravel模型调用save的时候触发的方法

新创建的对象,save 依次触发 saving->creating->created->saved
已存在的对象,save 依次触发 saving->updating->updated->saved

PHP无极分类

  • 第一种
    foreach ($lists as $list) {
        !isset($lists[$list['id']]['child']) && $lists[$list['id']]['child'] = [];
        $lists[$list['parent_id']]['child'][$list['id']] = &$lists[$list['id']];
    }
    return isset($lists[0]['child']) ? $lists[0]['child'] : [];
  • 第二种
    $return = []; // 索引目录
    $parent = []; // 根目录
    // 数组预处理,这里的$v['id']一定要唯一,不然可能会出现被覆盖的情况
    foreach ($list as $v) {
        $return[$v['id']] = $v;
        $return[$v['id']]['children'] = [];
    }
    // 将每个目录与父目录进行拼接,并找到根目录
    foreach ($return as $k => $v) {
        if ($v['parent_id'] > 0) {
            // 找到父路径,这里没有判断 $return[$v['parent_id']]['children']是否存在
            $return[$v['parent_id']]['children'][] = &$return[$k];
        } else {
            // 找到根目录
            $parent[] = &$return[$k];
        }
    }
    return $parent;
  • 第二种效率比第一种高

Laravel跨数据库whereHas()

跨数据库whereHas() 兼容扩展包 https://github.com/hoyvoy/laravel-cross-database-subqueries

Laravel多字段模型关联

多字段模型关联 兼容扩展包 https://github.com/topclaudy/compoships

Laravel数据库事务回滚

多数据库连接一下需要指定一下那个数据库进行事务回滚的操作

$transactionConnectionName = 'xxxxx';
DB::connection($transactionConnectionName)->beginTransaction();
DB::connection($transactionConnectionName)->commit();
DB::connection($transactionConnectionName)->rollBack();

Laravel 在 Windows (开发)环境下解决 Redis 扩展问题

laravel 提示“Please make sure the PHP Redis extension is installed and enabled.”

本人使用的是Laragonlearnku相关介绍)开发环境,访问http://pecl.php.net/package/redis,然后点开最新版本号(强迫症)后面的Windows图标的DLL超链接(当前最新是5.3.1,点击直达),选择对应的版本下载。

解压后把php_redis.dll放入\ext目录下(我的laragon目录路径D:\laragon\bin\php\php-7.3.19-nts-Win32-VC15-x64\ext),然后在编辑\php.ini文件(我的laragon目录路径D:\laragon\bin\php\php-7.3.19-nts-Win32-VC15-x64\php.ini),加入一行extension=php_redis,重启环境即可。

Laravel 遇到 fopen(): Filename cannot be empty

php.ini中修改临时缓存的路径

upload_tmp_dir = C:\Windows\Temp

json_encode 保留中文

json_encode($post_data, JSON_UNESCAPED_UNICODE);
json_encode($post_data, 256);

JSON_UNESCAPED_UNICODE等同256

laravel stream txt 文件导出

$cards = Card::get();
$filename = now()->format('YmdHis') . '_' . rand(1000, 9999) . '.txt';
$headers = [
    'Content-Encoding' => 'UTF-8',
    'Content-Type' => 'text/csv;charset=UTF-8',
    'Content-Disposition' => "attachment; filename=\"$filename\"",
];
return response()->stream(function () use ($cards) {
    $handle = fopen('php://output', 'w');
    foreach ($cards as $card) {
        fputs($handle, "{$card->name}|{$card->type}|{$card->time}" . "\n");
    }
}, 200, $headers)->send();

正则匹配(中文和符号语句)

$pattern = '/[\x{4e00}-\x{9fff}()《》—;,。“”<>!]+/u';
preg_match_all($pattern, $result, $messages);
dd($messages);

Laravel Builder 复用

$type = request()->input('type');
$modelBuilder = Model::when($type, function (Builder $builder) use ($type) {
    switch ($type) {
        case 1:
            $builder->where('type', 1);
            break;
        case 2:
            $builder->where('type', 2);
            break;
    }
});
$count1 = (clone $modelBuilder)->where('status', 1)
    ->count();
$count2 = (clone $modelBuilder)->where('status', 2)
    ->count();
$count3 = (clone $modelBuilder)->where('status', 3)
    ->count();

修改数据库默认字符集排序规则相关

网址:https://dev.mysql.com/doc/refman/8.0/en/alter-table.html
页面搜索 Changing the Character Set

修改数据库默认字符集于排序规则

ALTER DATABASE `数据库名` CHARACTER set 'utf8mb4' collate 'utf8mb4_general_ci';

改变表的默认字符集,并且将表所有字符集列(char,varchar,text)设置为新的字符集

ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

仅修改表默认字符集

alter table 表名 default character set utf8mb4 collate=ut8mb4_general_ci;

从历史记录表里拿出指定最新的一组数据

Laravel实现

$tableName = (new Model())->getTable();
$historiesGroup = DB::table($tableName)
    ->select('detail_id', DB::raw('max(created_at) as max_created_at'))
    ->groupBy('detail_id');
$histories = DB::table($historiesGroup, 'g')
    ->select(['l.id', 'l.detail_id', 'l.detail_price', 'l.created_at'])
    ->leftJoin($tableName . ' as l', function (Builder $join) {
        $join->whereColumn('l.detail_id', '=', 'g.detail_id')
            ->whereColumn('l.created_at', '=', 'g.max_created_at');
    })
    ->get();

Sql实现

select `l`.* from (select `price_detail_id`, max(created_at) as max_created_at from `price_detail_histories` group by `price_detail_id`) as `g` left join `price_detail_histories` as `l` on `l`.`price_detail_id` = `g`.`price_detail_id` and `l`.`created_at` = `g`.`max_created_at`;

Laravel JWT坑

Last modification:February 2nd, 2021 at 02:49 pm
如果觉得我的文章对你有用,请随意赞赏