分类 Laravel 下的文章

Carbon 时间类常用方法

需要本地化,修改app/Providers/AppServiceProvider.php文件

public function boot()
{
    //Carbon 本地化
    \Carbon\Carbon::setLocale('zh');
    //添加mysql最大字符串限制
    Schema::defaultStringLength(191);
}

常用方法

$dt = Carbon::create(1975, 12, 25, 14, 15, 16);

var_dump($dt->toDateTimeString() == $dt);          // bool(true) => uses __toString()
echo $dt->toDateString();                          // 1975-12-25
echo $dt->toFormattedDateString();                 // Dec 25, 1975
echo $dt->toTimeString();                          // 14:15:16
echo $dt->toDateTimeString();                      // 1975-12-25 14:15:16
echo $dt->toDayDateTimeString();                   // Thu, Dec 25, 1975 2:15 PM

$dt = Carbon::now();

// $dt->toAtomString() is the same as $dt->format(DateTime::ATOM);
echo $dt->toAtomString();      // 1975-12-25T14:15:16-05:00
echo $dt->toCookieString();    // Thursday, 25-Dec-1975 14:15:16 EST
echo $dt->toIso8601String();   // 1975-12-25T14:15:16-0500
echo $dt->toRfc822String();    // Thu, 25 Dec 75 14:15:16 -0500
echo $dt->toRfc850String();    // Thursday, 25-Dec-75 14:15:16 EST
echo $dt->toRfc1036String();   // Thu, 25 Dec 75 14:15:16 -0500
echo $dt->toRfc1123String();   // Thu, 25 Dec 1975 14:15:16 -0500
echo $dt->toRfc2822String();   // Thu, 25 Dec 1975 14:15:16 -0500
echo $dt->toRfc3339String();   // 1975-12-25T14:15:16-05:00
echo $dt->toRssString();       // Thu, 25 Dec 1975 14:15:16 -0500
echo $dt->toW3cString();       // 1975-12-25T14:15:16-05:00

echo Carbon::now()->tzName;                        // America/Toronto
$first = Carbon::create(2012, 9, 5, 23, 26, 11);
$second = Carbon::create(2012, 9, 5, 20, 26, 11, 'America/Vancouver');

echo $first->toDateTimeString();                   // 2012-09-05 23:26:11
echo $first->tzName;                               // America/Toronto
echo $second->toDateTimeString();                  // 2012-09-05 20:26:11
echo $second->tzName;                              // America/Vancouver

# 可以使用 parse 方法解析任何顺序和类型的日期(结果为 Carbon 类型的日期时间对象):

echo Carbon::parse('2016-10-15')->toDateTimeString(); //2016-10-15 00:00:00
echo Carbon::parse('2016-10-15')->toDateTimeString(); //2016-10-15 00:00:00
echo Carbon::parse('2016-10-15 00:10:25')->toDateTimeString(); //2016-10-15 00:10:25

echo Carbon::parse('today')->toDateTimeString(); //2016-10-15 00:00:00
echo Carbon::parse('yesterday')->toDateTimeString(); //2016-10-14 00:00:00
echo Carbon::parse('tomorrow')->toDateTimeString(); //2016-10-16 00:00:00
echo Carbon::parse('2 days ago')->toDateTimeString(); //2016-10-13 20:49:53
echo Carbon::parse('+3 days')->toDateTimeString(); //2016-10-18 20:49:53
echo Carbon::parse('+2 weeks')->toDateTimeString(); //2016-10-29 20:49:53
echo Carbon::parse('+4 months')->toDateTimeString(); //2017-02-15 20:49:53
echo Carbon::parse('-1 year')->toDateTimeString(); //2015-10-15 20:49:53
echo Carbon::parse('next wednesday')->toDateTimeString(); //2016-10-19 00:00:00
echo Carbon::parse('last friday')->toDateTimeString(); //2016-10-14 00:00:00

// The most typical usage is for comments
// The instance is the date the comment was created and its being compared to default now()
echo Carbon::now()->subDays(5)->diffForHumans();               // 5 days ago

echo Carbon::now()->diffForHumans(Carbon::now()->subYear());   // 1 year after

$dt = Carbon::createFromDate(2011, 8, 1);

echo $dt->diffForHumans($dt->copy()->addMonth());              // 1 month before
echo $dt->diffForHumans($dt->copy()->subMonth());              // 1 month after

echo Carbon::now()->addSeconds(5)->diffForHumans();            // 5 seconds from now

echo Carbon::now()->subDays(24)->diffForHumans();              // 3 weeks ago
echo Carbon::now()->subDays(24)->diffForHumans(null, true);    // 3 weeks

echo Carbon::create(2018, 2, 26, 4, 29, 43)->diffForHumans(Carbon::create(2016, 6, 21, 0, 0, 0), false, false, 6); // 1 year 8 months 5 days 4 hours 29 minutes 43 seconds after

You can also change the locale of the string using Carbon::setLocale('fr') before the diffForHumans() call. See the localization section for more detail.

Laravel 框架中对 Mysql 查询复查语句的时候,有时候会遇到sql在MySQL终端中运行没问题,但是在laravel中出现错误.

  • 举个

查询表中name有重复的数据

$sql = " `name` IN (SELECT `name` FROM clients child GROUP BY child.`name` HAVING COUNT(child.`name`) > 1 ) ORDER BY `name`";

$clients = Client::whereRaw($sql)->paginate();

通过toSql()将sql打出来放到mysql终端中执行是没有问题的,但是在laravel框架中则会出现:

Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause

  • 解决办法

config/database.php中mysql的 strict改为false就可以啦!

直奔主题!

使用技巧

递增和递减

要代替以下实现:

$article = Article::find($article_id);
$article->read_count++;
$article->save();

你可以这样做:

$article = Article::find($article_id);
$article->increment('read_count');

以下这些方法也可以实现:

Article::find($article_id)->increment('read_count');
Article::find($article_id)->increment('read_count', 10); // +10
Product::find($produce_id)->decrement('stock'); // -1

模型的 boot() 方法

在一个 Eloquent 模型中,有个神奇的地方,叫 boot(),在那里,你可以覆盖默认的行为:

class User extends Model
{
    public static function boot()
    {
        parent::boot();
        static::updating(function($model)
        {
            // 写点日志啥的
            // 覆盖一些属性,类似这样 $model->something = transform($something);
        });
    }
}

- 阅读剩余部分 -

访问量较大的站点中,关键数据的展示有时候不是实时更新的,用户在访问这些数据的时候如果每次都从数据库中调取,则会浪费很多不必要的资源!
加上缓存的话,则会让数据的读取更快,同时大大减少了资源的浪费!缓存就这么因运而生了。

首先我们先来看下如何正确的使用缓存!

缓存更新的套路

大多人的思路是在有新数据加入的时候,删除原有缓存,更新数据库,在将新数据放入缓存中去!
然而!这个逻辑是有漏洞的。试想如果两个并发操作同时进来,一个更新操作,一个查询操作,更新操作删除缓存之后,查询操作没有命中缓存,将原有数据查询放入缓存中去,然后更新操作更新了数据库!
这就导致缓存数据是原来的老数据,并且一直会这样下去!

更新缓存

四种Design Pattern:

  1. Cache aside
  2. Read through
  3. Write through
  4. Write behind caching

最常用是是第一种 Cache aside .具体逻辑如下:

  • 失效 先从cache中去数据,没取到则去DB中取出来,在放入cache中去
  • 命中 从cache中取到数据返回
  • 更新 更新DB,更新成功之后再让cache失效

这种pattern其实也是有极小的概率会出现脏数据的。不过外部设置缓存过期时间则会减少这种情况的出现!

其余几种pattern这里不介绍了,详细请看参考链接

laravel 中使用缓存

框架自带了缓存配置,可以在config/cache.php中配置具体的缓存功能

常用的方法

创建缓存

Cache::put('key', 'value', 10);//键名、值、过期时间(分钟)

此外,我们也可以用 remember() 方法自动获取和更新一个缓存值。该方法首先检查 键名 是否存在,如果已经创建则返回结果。否则它会创建新的 键名 ,并用闭包返回结果进行赋值,就象下面:

Cache::remember('articles', 15, function() {
    return Article::all();
});

参数 15 是要缓存的分钟数。这样的话,我们甚至根本不必检查缓存是否过期。Laravel 不仅会替我们打理,而且会获取或重新生成该缓存,不需要我们显式地告诉它如何操作。

检索缓存

在更新或者取回缓存值之前判断这个缓存的key是否存在是很有必要的,使用 has() 方法就可以实现:

if (Cache::has('key')){
    Cache::get('key');
} else {
    Cache::put('key', $values, 10);
}

删除缓存

Cache::forget('key');

#我们也可以检索缓存值并删除它。我喜欢把这个称为一次性缓存:
$articles = Cache::pull('key');

#使用以下命令在缓存过期前就把所有缓存清楚掉:
$ php artisan cache:clear

Controller 中使用缓存

public function index() {
    $articles = Cache::remember('articles', 22*60, function() {
        return Article::all();
    });
    return response()->json($articles);
}

<span id=reference-link>参考链接</span>

  1. 知乎
  2. 酷壳

初学者学习Laravel时分两种,一种是乖乖的将程序填入MVC构架内,导致controller与model异常的肥大,日后一样很难维护;一种是常常不知道程序该写在哪一个class内而犹豫不决,毕竟传统PHP都是一个页面一个档案。本文整理出最适合Laravel的中大型项目构架,兼具容易维护、容易扩充与容易重复使用的特点,并且容易测试。

Controller过于肥大

受RoR的影响,初学者常认为MVC构架就是model,view,controller:

- 阅读剩余部分 -