人的血液7年会全部替换一遍,鱼的记忆只有7秒。
在以前, 开发者需要为每一个需要调度的任务编写一个 Cron 条目, 这是很让人头疼的事. 你的任务调度不在源码控制中, 你必须使用 SSH 登录到服务器然后添加这些 Cron 条目. Laravel 命令调度器允许你平滑而又富有表现力地在 Laravel 中定义命令调度, 并且服务器上只需要一个 Cron 条目即可, 任务调度又是我们俗称的 “计划任务”。任务调度定义在app/Console/Kernel.php文件的schedule方法中,该方法中已经包含了一个示例。你可以自由地添加你需要的调度任务到Schedule对象开启调度//在linux环境中执行 * * * * * root php /var/www/laravel/artisan schedule:run/var/www/laravel为你的项目目录该 Cron 将会每分钟调用Laravel命令调度,然后,Laravel评估你的调度任务并运行到期的任务。定义调度在 项目根目录 下创建定时任务所需要进行的操作创建命令(Laravel 5.1):php artisan make:console Stat_Test创建命令(Laravel 5.3):php artisan make:command Stat_Test该操作会在app/Console/Commands下生成一个Stat_Test.php下面打开该文件 给大家展示一个简单而又完整的代码例子 <?php namespace App\Console\Commands; use Illuminate\Console\Command; class Stat_Test extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'stat:test'; /** * The console command description. * * @var string */ protected $description = 'stat:test'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $this->addData(); } // 例子 public function addData() { $time = time(); $rand = rand(1, 1000); $id = \DB::table('data_test')->insertGetId(['uuid' => $time, 'uuid' => $rand]); if ($id) { \Log::info('定时/数据插入成功', $id); } else { \Log::error('定时/数据插入失败', $time); } } }值得注意的是 这个文件中的 $signature = 'stat:test' 这个签名在 Kernel.php 中也要相应用到, 下面是附上 Kernel.php 的完整代码<?php namespace App\Console; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel { /** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ \App\Console\Commands\Inspire::class, '\App\Console\Commands\Stat_Test', ]; /** * Define the application's command schedule. * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) { // 为测试方便 每分钟执行一次 $schedule->command('stat:test')->everyMinute(); } }再强调一次 $schedule->command('stat:test') 里面的 stat:test 必须和上面的签名 $signature = 'stat:test' 对应上protected $commands = [ \App\Console\Commands\Inspire::class, '\App\Console\Commands\Stat_Test', ];也要把引入你的调度文件// 每周星期六11:00运行一次... $schedule->command('stat:test')->weekly()->saturdays()->at('11:00'); // 每周星期一:00运行一次... $schedule->command('stat:test')->weekly()->->mondays()->at('01:00');调度常用选项当然,你可以分配多种调度到任务->cron('* * * * *'); 在自定义 Cron 调度上运行任务 ->everyMinute(); 每分钟运行一次任务 ->everyFiveMinutes(); 每五分钟运行一次任务 ->everyTenMinutes(); 每十分钟运行一次任务 ->everyThirtyMinutes(); 每三十分钟运行一次任务 ->hourly(); 每小时运行一次任务 ->daily(); 每天凌晨零点运行任务 ->dailyAt('13:00'); 每天 13:00运行任务 ->twiceDaily(1, 13); 每天 1:00 & 13:00 运行任务 ->weekly(); 每周运行一次任务 ->monthly(); 每月运行一次任务下面是额外的调度约束列表:->weekdays(); 只在工作日运行任务 ->sundays(); 每个星期天运行任务 ->mondays(); 每个星期一运行任务 ->tuesdays(); 每个星期二运行任务 ->wednesdays(); 每个星期三运行任务 ->thursdays(); 每个星期四运行任务 ->fridays(); 每个星期五运行任务 ->saturdays(); 每个星期六运行任务 ->when(Closure); 基于特定测试运行任务原文出处: https://www.jianshu.com/p/91bbdf9ddbf5
查看详情在后端开发中,关于锁的问题,也是经常能遇到的。为了防止程序并行所导致的数据破坏,或者系统故障,在开发中合理的运用锁,可以带来更好的效果。Cache::lock用法:if (Cache::lock('foo', 10)->get()) { // 锁住这个key 10秒的时间 // 然后我们可以接着自己实际项目中的相关操作 Cache::lock('foo')->release();//一定要在结尾处释放锁,不然会导致别的并行或后续请求一直无法获取锁而停滞 }例如最常见我们在处理用户余额的时候需要用到锁utils工具中封装方法: /** * 获取一个原子锁 * @param string $name * @param int $seconds * @return Lock */ public static function acquireLock(string $name, int $seconds = 60): Lock { return Cache::lock($name, $seconds); } /** * 释放一个原子锁 * @param Lock $lock * @return void */ public static function releaseLock(Lock $lock): void { $released = optional($lock)->release(); if (!$released) { optional($lock)->forceRelease(); } }调用:/** * 增加用户余额 * @param int $userId * @param int $amountInCents * @param int $changeType * @param string $description * @return UserAccountBalance|null */ public function increaseUserBalance( int $userId, int $amountInCents, int $changeType, string $description = '', ): ?UserAccountBalance { $lock = Utils::acquireLock('user_balance_' . $userId); try { $lock->block(10); $balance = $this->getBalance($userId); if (empty($balance)) { $balance = $this->createBalance([ 'user_id' => $userId, 'total_balance_in_cents' => 0, 'withdrawn_balance_in_cents' => 0, 'remaining_balance_in_cents' => 0, ]); } if (empty($balance)) { throw new Exception('创建用户余额失败'); } if ($amountInCents == 0) { return $balance; } $change = $this->createBalanceChange([ 'user_id' => $userId, 'changed_amount_in_cents' => $amountInCents, 'change_type' => $changeType, 'change_detail' => ['description' => $description], ]); if (empty($change)) { throw new Exception('余额变更记录保存失败'); } $this->updateBalance($balance, [ 'total_balance_in_cents' => $balance->total_balance_in_cents + $amountInCents, 'remaining_balance_in_cents' => $balance->remaining_balance_in_cents + $amountInCents, ]); return $balance; } catch (Exception $error) { Log::error('用户余额更新失败', [ 'userId' => $userId, 'amount_in_cents' => $amountInCents, 'code' => $error->getCode(), 'message' => $error->getMessage(), 'file' => $error->getFile(), 'line' => $error->getLine(), ]); return null; } finally { Utils::releaseLock($lock); } }
查看详情1、不要着急,最好的总会在最不经意的时候出现。Don’t try so hard, the best things come when you least expect them to. 2、拾一片光阴,诉与你听。 Pick up a piece of time to tell you. 3、初听不知曲中意,再听已是曲终人。 I didn't know what I wanted to hear at the beginning, but I was the end of the song.4、好想,好想你!如果清风有情,请带去我对你的思念,这一生都为你牵挂;如果白云有意,请带去我对你的爱恋,生生世世都愿和你共缠绵! Oh, How much I miss you! If the passionate refreshing breeze knows my heart, it can tell you that I miss you and care you for my life’s time. If graceful white cloud knows my heart, it can tell you I love you and would be together with you forever.5、你知道么,有个人时时想念着你,惦记你,你含笑的眼睛,象星光闪闪,缀在我的心幕上,夜夜亮晶晶。 Do you know there is someone thinking of you and caring you all the time ? Your smiling eyes are just like the sparkling stars hanging on the curtain of my heart. 6、那些承诺,你动了嘴巴,我动了真心。Those promises, you moved your mouth, I moved my heart.7、纵使举案齐眉,到底意难平。Even if the case is raised in unison, it is difficult to get even.8、任何限制,都是从自己的内心开始的。Any restriction starts from your heart.9、不怕别人看不起,就怕自己不努力。Dont be afraid of being looked down upon by others, just afraid of not working hard.10、你的眼睛,是我永生不会再遇的海。Your eyes are the sea I will never meet again.11、谁苍白了我的等待,讽刺了我的执着。Who pale my waiting, satirized my persistence.12、把日子过成诗,简单而精致。Make life a poem, simple and delicate.13、向每个人学习,但不要模仿任何人。Learn from everyone, but dont imitate anyone.14、千山万水,一帘烟雨,迷离了眼眸。Thousands of mountains and rivers, a curtain of rain, blurred eyes.15、每个人,都有一个世界,安静而孤独。Everyone has a world, quiet and lonely.16、爱自己是终生浪漫的开始。Love yourself is the beginning of a lifetime of romance.17、小舟从此逝,江海寄余生。The boat is gone, and the river and the sea send the rest of their lives.18、心若一动,泪就千行。If you move your heart, tears will flow.19、我想遇见你,我在找你。I want to meet you. Im looking for you.120、一生,一条路,一个人走,一个人悟。Life, a way, a person to walk, a person to understand.
查看详情知道一个用户名密码时,修改用户密码,各个版本下都是通用的;重置密码的时候,版本不同,可能操作的地方不一样了;但凡知道一个用户的密码,那就好办。(普通用户登录的情况下,也可以修改root用户的密码。);在不知道账户和密码的情况下比较复杂了,以后有时间再写;linux各系统的命令有部分不同,根据不同系统来。1、知道root用户密码时root用户登录时,运行passwd 命令,可以设置或修改任何用户的密码语法格式:# passwd 用户名2、修改root用户密码在root用户登录的情况下,执行以下指令,进入密码修改界面# passwdpasswd命令后不加用户名,表示修改当前用户的密码输入新密码即可,无需重启Linux系统。3、修改普通用户密码(普通用户账号密码登录时,只能修改自己的密码)# more /etc/passwd 查看当前所有用户,自己创建的用户,在最后# passwd es 更改用户 es 的密码输入新的密码4、知道一个普通用户的账号密码在普通用户登录的情况下,修改root用户密码$ sudo passwd root会要求输入普通用户的密码输入后,会显示“enter new Unix password”这就是修改root用户密码,输入并确认密码后,即成功修改root用户密码修改普通用户自己的密码$ passwd // 进入修改密码界面,输入新密码即可
查看详情首先什么是Flex呢?Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。相较于Flex布局,就是传统的盒模型布局了。我们常用的盒模型布局有,display布局,float浮动布局,position定位布局,传统盒模型布局和弹性布局都能解决我们前端开发中的常见布局问题,但是盒模型在处理某些布局就显得特别不方便了。比如,垂直居中问题。Flex:display:flex;首先所有的HTML元素都适用于弹性布局,元素设为弹性布局之后,子元素的float、clear和vertical-align属性将失效。容器和项目容器:采用Flex布局的元素,称为Flex容器(flex container),简称”容器”;项目:“容器”的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”;容器默认存在两根轴:水平的主轴(main axis 从左至右)和垂直的交叉轴(cross axis 从上至下)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。弹性盒Flex容器属性,即父元素上的属性首先父元素启用弹性盒布局:display:flex;flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-content1、flex-directionflex-direction:设置主轴的方向。row: (默认值)主轴为水平方向,起点在左端,从左至右排列; row-reverse:主轴为水平方向,起点在右端,从右至左排列; column:主轴为垂直方向,起点在上沿,从上至下排列; column-reverse:主轴为垂直方向,起点在下沿,从下至上排列。nowrap:(默认值)不换行; wrap:换行,第一行在上方; wrap-reverse:换行,第一行在下方。3、flex-flow是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap4、justify-contentjustify-content:设置主轴上的子元素对齐方式。它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右:flex-start:(默认值),左对齐(沿着主轴开始位置至末尾位置对齐); flex-end:右对齐(沿着主轴末尾位置至开始位置对齐); center:居中对齐; space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍; space-between: 两端对齐,项目之间的间隔都相等。 5、align-items定义项目在交叉轴上如何对齐。flex-start:交叉轴的起点对齐; flex-end:交叉轴的终点对齐; center:交叉轴的中点对齐(可以理解为垂直居中); baseline:项目的第一行文字的基线对齐; stretch:(默认值),如果项目未设置高度或设为auto,将占满整个容器的高度。6、align-content上面提到过align-items适用于子元素在单行中使用,这个align-content则就是为了子元素多行的时候设置交叉轴的子元素的排列方式。flex-start:与交叉轴的起点对齐; flex-end:与交叉轴的终点对齐; center:与交叉轴的中点对齐; space-around:根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍; space-between:与交叉轴两端对齐,轴线之间的间隔平均分布; stretch:(默认值),占满整个交叉轴。 项目上的元素属性(即子元素)orderflex-growflex-shrinkflex-basisflexalign-self1、orderorder属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。2、flex-growflex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。.box div { flex-grow: 1 }: 值都为1,则它们将等分剩余空间3、flex-shrinkflex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。4、flex-basisflex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间flex-basis: auto | 350px;5、flexflex属性是flex-grow, flex-shrink 和 flex-basis的合写,默认值为0 1 auto。后两个属性可选。6、align-selfalign-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。align-self: auto | flex-start | flex-end | center | baseline | stretch;举例:多行布局<style> *{ padding:0; margin: 0; } html,body{ width: 100%; height: 100%; } .box{ width: 640px; background: rgb(243, 171, 171); height: 640px; display: flex; flex-wrap: wrap; align-content: space-between; justify-content: space-between; } .boxSon{ background: yellow; width: 200px; height: 200px; } </style> <body> <div class="box"> <div class="boxSon">1</div> <div class="boxSon">2</div> <div class="boxSon">3</div> <div class="boxSon">4</div> <div class="boxSon">5</div> <div class="boxSon">6</div> <div class="boxSon">7</div> <div class="boxSon">8</div> <div class="boxSon">9</div> </div> </body>差不多就到这儿了。
查看详情今天在新公司,需要安装Linux系统进行开发项目。以前是外包出去的项目,不知道为啥必须用Linux系统,也不知道有多少坑。 一步一来呗。首先,我们先安装虚拟机,我用的是VirtualBox,其他虚拟机同样的道理。然后安装Linux环境,我用的是centos系统,有兴趣的同学用其他系统也一样的。最后简简单单用宝塔部署了一个环境。简单的来。1、安装VirtualBox虚拟机VirtualBox官网地址: https://www.virtualbox.org/然后傻瓜式安装,直接下一步到头。安装完成之后如图:2、开始安装Centos系统首先下载centos系统,随便哪里下载都行,我这里用的是: https://www.centos.org/download/选择的是阿里云好,这里然后就开始安装系统然后一步一步进行操作,安装完成后,网络选择桥接好了,安装完成。接下来,我们用xshell链接虚拟机进行操作。这个地方要先查虚拟机IPifconfig如果提示没有这个命令需要安装工具1、新安装centos需要启动网卡,运行nmcli dev status查看设备状态2、查看网卡为ens33 ,执行命令nmcli con up ens333、开启启动网络 切换到网络配置目录 cd /etc/sysconfig/network-scripts/ 编辑 vi ifcfg-ens33首先找到ONBOOT=no修改为ONBOOT=yes然后保存退出 执行systemctl start network 或service network restart #重启网络服务 4、运行ifconfig,查看ip(最小安装会出现没有ifconfig命令需要安装,执行yum install net-tools -y)nmcli dev status nmcli con up ens33 cd /etc/sysconfig/network-scripts/ vi ifcfg-ens33 ONBOOT=yes 执行systemctl start network 或service network restart #重启网络服务 yum install net-tools -y5、查找到ip,后台运行虚拟机,使用xshell或phpstorm里带的ssh链接centosOK,xshell链接成功了接下来就安装宝塔 https://www.bt.cn/new/download.html 到这里所有的东西都准备好了,接下来就是部署站点了。
查看详情在我们日常前端开发中,经常会遇到列表或者首页文本只显示几行等问题。一般我们通过css 就可以解决。代码:/*一行文本超出显示省略号*/ .one-line { overflow: hidden; white-space: nowrap; display: block; -o-text-overflow: ellipsis; text-overflow: ellipsis; } /*多行文本超出显示省略号*/ .two-line { overflow: hidden; -o-text-overflow: ellipsis; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; /* 可以显示的行数,超出部分用...表示*/ -webkit-box-orient: vertical; }但是在IE中有兼容问题,虽然现在很少再兼容IE了。有兴趣的同学可以了解下。兼容IE // 处理多行文本超出部分隐藏 function wordLimit(cName, wordLength) { var cName = document.getElementsByClassName(cName); for (var i = 0; i < cName.length; i++) { var nowHtml = cName[i].innerHTML; var nowLength = cName[i].innerHTML.length; if ( nowLength > wordLength) { cName[i].innerHTML = nowHtml.substr(0, wordLength) + '…'; } } };
查看详情分享这个话题,不是一时心血来潮,也不是看不起这样喝酒的人,只是自己看到的这一幕有感而发。只是感叹!!这个时代真的不光是表面的光彩,绝大一部分的人都在为了生计努力打拼,努力挣钱努力让生活过得更好。有一首歌和这个短视频确实很戳心,就是《用力活着》我们都在用力的活着酸甜苦辣里醒过也醉过也曾倔强脆弱依然执着相信花开以后会结果我们都在用力的活着爱恨成败里赢过也输过也曾灿烂失落无悔选择相信磨难历尽是收获成长的路上有几程曲折这首歌触动了太多的人,道出了太多的辛酸,很多人成功了,但是他们背后流的汗水,竭尽全力的付出,都是其他人看不到的。当然了,回归正题。成功的人毕竟只是少数,都说这个世界上的财富是掌握在20%的人手中,那么剩下的80%人呢,他们一天的生活是什么样的,他们在经历什么样的人生。不可而知,但是我知道,他们肯定在这个社会上努力着,默默为了家庭,为了亲人和自己挥洒汗水。甚至有一部分人曾经走到了绝望。照片上的时间在晚上2点多,我没有睡着,准确的说还没有睡。我听到下面有人在说话声音比较大,习惯性的想看看发生了什么事情。我看到他趟在草坪上说着什么,像诉说着什么也像哭,不久就在草坪上睡着了。我不知道他发生了什么,或许是事业失败了,或许是感情收到了挫折,又或许生活的压力太大 。就他一个人,不知道他的家人在哪里,不知道他一个人怎么到的这儿。通过后面救护车和医生的沟通,我知道他是喝醉了。神志不清晰,不知道家在哪里也没有联系方式,手机密码解不开。总之怎么说呢,一个可怜人。这个社会有很多这样的人。说真的,分享这个话题不是看不起他,相反对这个事情,我表示同情。没有亲人照顾,也没有爱人陪伴,也没有朋友知道他在这里。是经历了什么绝望的事情,让他喝成这样,我猜想可能是因为应酬,最后一想不太可能。如果是生意上的事情,喝酒之后肯定有朋友问候或者送他回家。多半是因为生活、工作、感情上的压力导致。有谁能说自己没有喝成这样或者以后会喝成这样。酒不醉人人自醉,多是人到伤情时。当自己到了这个时候,会不会比他更不堪,受打击之后会不会更极端。有多少人因为生活的压力,在绝望的时候,选择结束自己的生命,这样的例子太多了。坚强的人,会重新站起来,脆弱的人,也要努力让自己站起来!怎么说呢,只能说,当我们经历选择的时候多考虑一点,多往好的地方想想,适当的放纵的自己可以,过后生活得照样过起走。生活中,还是多给一些关心,一些理解。生活中,多坚持,努力一点,保持学习!希望他没事!
查看详情在我们日常前端开发或者工作中,经常会遇到HTML页面提交表单,弹出手机键盘出现各种各样的兼容性问题。android终端还是ios终端弹出异常等。下面总结了基础的处理弹出键盘的兼容性问题,以供参考。//判断是android终端还是ios终端 $("document").ready(function () { var m = navigator.userAgent; var isAndroid = m.indexOf('Android') > -1 || m.indexOf('Adr') > -1; //android终端 var isIos = !!m.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 var timer; if (isIos) { // ios 弹出与收起软键盘执行事件 document.body.addEventListener('focusin', () => { //软键盘弹起事件 $(".footer").css('position', 'relative'); $('.mask').css({'height':'200%','top':'-50%'}); window.addEventListener("touchmove", () => { $("input").blur(); }); }) document.body.addEventListener('focusout', () => { //软键盘关闭事件 $(".footer").css('position', 'fixed'); $('.mask').css('height','100%'); // 解決ios端用微信打开页面,收起软键盘后,底部出现空白问题 setTimeout(() => { const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0; window.scrollTo(0, Math.max(scrollHeight - 1, 0)); }, 100); }) } if (isAndroid) { // android 弹出与收起软键盘执行事件 const innerHeight = window.innerHeight; window.addEventListener('resize', () => { const newInnerHeight = window.innerHeight; if (innerHeight > newInnerHeight) { // 键盘弹出事件处理 $(".footer").hide(); } else { // 键盘收起事件处理 $(".footer").show(); } }); } });
查看详情上一篇 go-zero 数字图形验证码功能 之后,接下来我们要开发一个发送邮件的功能。框架还是go-zero,好吧,我们开始撸!1、引包:我们用到的是这个包(github.com/jordan-wright/email)github.com/jordan-wright/email2、新建一个邮件发送的工具:新建一个utils文件加,然后创建mail.go文件直接撸代码:我用的是163邮箱,开干之前。需要在邮箱进行配置。具体步骤百度一下或者联系我沟通。package utils import ( "crypto/tls" "fmt" "net/smtp" "strings" "github.com/jordan-wright/email" ) func Email(To, subject string, body string) error { to := strings.Split(To, ",") return send(to, subject, body) } func send(to []string, subject string, body string) error { from := "这里是发件人邮箱地址,需要自己配置" nickname := "这里是名称" secret := "秘钥" host := "smtp.163.com" port := 465 isSSL := true auth := smtp.PlainAuth("", from, secret, host) e := email.NewEmail() if nickname != "" { e.From = fmt.Sprintf("%s <%s>", nickname, from) } else { e.From = from } e.To = to e.Subject = subject e.HTML = []byte(body) var err error hostAddr := fmt.Sprintf("%s:%d", host, port) if isSSL { err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host}) } else { err = e.Send(hostAddr, auth) } return err } OK,工具方法已经好了。我们开始引用:utils.Email(in.Email, "xxx", "您好,欢迎加入xxxxx!邮箱已发送,祝您使用愉快!")
查看详情