CrazyCodes

CrazyCodes 查看完整档案

北京编辑北京邮电大学  |  计算机信息技术 编辑蜗行  |  联合创始人 编辑 blog.fastrun.cn 编辑
编辑

https://github.com/CrazyCodes... 我的博客
_
| |__ __ _
| '_ | | | |/ _` |
| |_) | |_| | (_| |
|_.__/ __,_|__, |

         |___/   感谢生命可以让我成为一名程序员

                         CrazyCodes To Author

个人动态

CrazyCodes 赞了文章 · 10月23日

1024 思否有奖征文活动丨我和我的“格子衫”

image

提到程序员大家总会第一时间联想到“格子衫”,价格亲民、休闲百搭、面料舒适的格子衬衫正是 1024 前后秋季程序员的最爱。

但除了格子衫,其实程序员还有很多私藏好物,手感超好的机械键盘、996 都不怕的工学椅、大促时的云主机、all in one 超好用的项目管理工具防脱洗发水甚至程序员内裤……

欢迎参与 SegmentFault 思否 #1024 特别征文活动#,分享一件或几件你钟爱的好物。双十一的前奏,让我们供拟 “ 不踩坑剁手清单 ”,我们也将联合广大合作伙伴,为分享好物的开发者们送上一拨儿真正的“程序员好物”~

1024 思否征文活动丨我和我的”格子衫”

征文主题:#我和我的“格子衫”# 参选时间:2020年10月23日 - 11月11日

活动规则:请以在社区发布文章的形式参与本次征文活动,和大家进行程序员好物分享~

奖项设置:本次奖项分为「人气好物奖」、「效率大师奖」、「生活玩家奖」,「从头开始奖」此外可能还有各种惊喜附加的奖项等着大家,只要作品好,奖品少不了!具体奖品及评选标准如下:

  • 从头开始奖 x 15 名:率先提交作品,并满足征文质量要求的 15 名社区用户,将获得由 Menxlab 时光里赞助的臻享生发套装一份助你“聪明不绝顶”(市场价:358 元/套盒)
  • 人气好物奖 x 5 名:本奖项主要综合考量参选文章的阅读量、互动量等相关数据,奖品为 AWS 赞助的人气公仔 1 个;
  • 效率大师奖 x 5 名:本奖项主要根据推荐的好物为工作、生活所带来的实际效果为参考维度进行评选,奖品为京东智联云赞助的超大鼠标垫 1 个;
  • 生活玩家奖 x 5 名:本奖项将颁发给最会享受生活的生活节奏大师,奖品为 LeanCloud 赞助的「积木塔」 1 座;
  • 意外惊喜奖 x 若干名:只要作品好,奖品少不了,思否小姐姐正为大家四处奔波、搜集福利中……

image

备注:文章需添加 「1024-征文活动」为文章的标签,且在文章末尾超链接注明:

本文参与了 SegmentFault思否征文「1024 征文活动」,欢迎正在阅读的你也加入。

思否小姐姐会把优质文章汇总收录并发出,参与征文活动的优质文章内容,还将:

  • 被推荐到社区首页及技术交流群,分享给更多的开发者;
  • 获选的优质投稿内容,还将有机会获得社区精美礼品;
  • 小姐姐也喜欢穿格子衫,忙完这几天也会推荐一个属于自己的好物,为方便文章被尽快收录,文章发布后欢迎在此帖下面留言

PS:鼓励开脑洞,但禁止盗图或剽窃他人的生活

PSS:感谢本次活动礼品的赞助商:Menxlab时光里、AWS、LeanCloud、京东智联云开发者社区

PSSS:感谢每一个愿意分享生活片段、热爱生活的开发者们,谢谢大家!

如有疑问,可以扫码下方二维码,添加「SF 思否小姐姐」微信,欢迎咨询哦~

参选文章(持续更新中):

1、1024好物分享丨脱单不脱发,就靠它!
2、1024 程序员必备好物推荐 丨我和我的“格子衫”
3、1024 程序员必备好物推荐(vscode 插件) 丨我和我的“格子衫”
4、1024 程序员必备好物推荐 丨我和我的“颈椎按摩仪”
5、“智能手表让我和时间的博弈,略胜一筹”丨1024 征文活动
6、好物分享 | 键盘清洁泥与护眼仪
7、1024 程序员必备好物推荐丨我和我的防蓝光眼镜

查看原文

赞 12 收藏 0 评论 8

CrazyCodes 发布了文章 · 10月23日

电商系统设计之运费模板(下)

clipboard.png

电商大伙每天都在用,类似某猫,某狗等。
电商系统设计看似复杂又很简单,看似简单又很复杂
本章适合初中级工程师细看,大佬请随意

前言

在订单系统中,运费模板是其中一个重要组成部分,看似简单的一个设置,在其内的设计中,要考虑的问题还是很多滴,上一章我们讲了运费的一些规则以及在数据库表中如何设计,本章聊聊如何计算运费

获取

通过上一篇文章我们建立的数据表获取该商品绑定的哪一个运费模版

$templateId = Product::where('id',$product)->value('template_id');
if($template == 0) return [];

指定商品或许会使用多项规则,例如像这样
image.png

  • 是否包邮
  • 指定地区运费
  • 达成某种条件下运费多少或者包邮

那这么多条件,我们要保证所有的规则全部都可以检索到,并且还要提升其计算速度。

在计算前,应当想好有几种可能性,再选择其优先级,就像有

三个不同颜色的球,拼凑的方法有多种一样

我记得这应该是一道小学的数学题。

就近原则

相比大家肯定做过这道面试题

把一份打乱的字符串,进行排序

那按照经典的方式

  • 快速排序
  • 选择排序
  • 插入排序
  • 冒泡排序

当然,我们不讲排序,我们是要通过这类算法去思考如何以快速的方式去查询到我们想要的信息。

排序算法归并与一点核心,就是通过比较的方式进行,无论是从中间开始进行计算,还是从头或者从尾开始,都是通过对字符串本身要呈现方式的一种猜测。

那我们对于运费计算,应该从什么位置开始“排序”呢?

根据业务,首先我们考虑关于是否包邮、指定地区运费、达成指定条件这三种规则,他们的优先级大多是这样的。

达成指定条件 > 指定地区运费 > 是否包邮

一、达成指定条件就不在计算指定地区条件和是否包邮
二、达成指定地区条件就不判断是否包邮

思路是不是清晰了一点呢,那么我们上代码

实战

演示为伪代码,这类计算肯定不能交给前端去计算,会出现很多安全问题,例如数据被篡改等等,偷懒的后端不是一个好后端

当我们获取templateId后,在表product_template_config中查询其关联的规则,这是一个一对多的数据列,意味着会查询出多条,首先我们先查询指定条件。

select count(1) product_template_config where template_id = $templateId and 是否有指定条件

当有指定条件则进行计算,例如

  • 达成指定金额,运费固定
  • 达成指定金额,运费多少

计算就简单了,小学就学过的嘛~

商品数量*商品单价 > 指定金额 = 运费

如果没有指定条件,则去查询指定城市运费,城市我们使用的是json存储,会有多条,免不了for,这样你肯定会说了,那很多个城市不会导致效率低嘛?

做任何功能都要以实际业务出发,除了西藏、新疆及偏远地区,会有商家一个市一个市设置不同运费的嘛😂,那我们就使用二种方式

第一种:死循环法

$list = "select * from `product_template_config` where template_id = $templateId";
$city = [];
for($list){
   if($list->city == "北京市"){
        return price;
   }
}

第二种:模糊查询

select * from `product_template_config` where city like "%北京市%"

like有时会导致索引失效,要特别注意

最后如果以上两种规则都不满足,则就回到最简单都自定义运费和是否包邮,自定义运费的话就计算最终运费,包邮的话,直接return 0就完事喽。

流程图如下

image.png

一些思考

至此,我们运费模版的设计和实战就到此结束了。

当然这仅仅是设计上的思路,使用该方法是承受不住访问冲击的,我仅仅提供思路而已。

最后我给一些思考,你不妨实践下。

1.检索优先级是我们预先设定的,可以每天定时去分析某个商家的设置习惯,例如商家经常都是设置包邮,那我们优先级的计算可以更换下位置。

2.对于并发过大的应用,不妨使用redis试试呢?变化的仅仅是数据结构~

3.根据用户购物习惯,去计算运费,有没有更多的实践呢?

4.考虑如果有免运费卷,或者运费优惠卷,应该加在哪个流程内呢?

任何一个简单的功能,在应用不断迭代中,都会变的不再简单。期待你们的最佳实践。

致谢

感谢你的关注,希望本篇文章可以帮到你,谢谢。

查看原文

赞 5 收藏 3 评论 1

CrazyCodes 收藏了文章 · 10月21日

图解你身边的 SOLID 原则

这篇文章我们来简单介绍一下 SOLID 原则(这五个字母代表了面向对象编程的五个基本原则)

我们用身边的事物来举例,让它们更易于理解和记忆。

好啦,开始吧~

S - 单一职责原则

Single Responsibllity Principle - 即 SRP

一个类只能承担一个职责。通俗点儿说就是一个类只能承担一件事,并且只能有一个潜在的原因去更改这个类,否则就违反了单一职责原则。

1_s.jpg

O - 开闭原则

Open/Closed Principle - 即 OCP

软件实体应该对 扩展 开放,对 修改 关闭。允许扩展行为而无需修改源代码。

2_o.jpg

L - 里氏替换原则

Liskov Substitution Principle - 即 LSP

程序中的对象应该可以被其子类实例替换掉,而不会影响程序的正确性。

3_l.jpg

I - 接口隔离原则

Interface Segregation Principle - 即 ISP

使用多个特定细分的接口比单一的总接口要好,不能强迫用户去依赖他们用不到的接口。

4_i.jpg

D - 依赖倒置原则

Dependency Inversion Principle - DIP

程序要依赖于抽象接口,而不是具体实现。

  • 高层模块不应该依赖于低层模块,二者都应该依赖于抽象
  • 抽象不应该依赖具体实现,具体实现应该依赖抽象

5_d.jpg

插头不应该依赖具体某种电线,它只需要有线并且能导电。

全文完~希望本文对你理解 SOLID 有帮助啦~

参考文章


本文首发于公众号:码力全开(codingonfire)

本文随意转载哈,注明原文链接即可,公号文章转载联系我开白名单就好~

codingonfire.jpg

查看原文

CrazyCodes 赞了文章 · 10月21日

图解你身边的 SOLID 原则

这篇文章我们来简单介绍一下 SOLID 原则(这五个字母代表了面向对象编程的五个基本原则)

我们用身边的事物来举例,让它们更易于理解和记忆。

好啦,开始吧~

S - 单一职责原则

Single Responsibllity Principle - 即 SRP

一个类只能承担一个职责。通俗点儿说就是一个类只能承担一件事,并且只能有一个潜在的原因去更改这个类,否则就违反了单一职责原则。

1_s.jpg

O - 开闭原则

Open/Closed Principle - 即 OCP

软件实体应该对 扩展 开放,对 修改 关闭。允许扩展行为而无需修改源代码。

2_o.jpg

L - 里氏替换原则

Liskov Substitution Principle - 即 LSP

程序中的对象应该可以被其子类实例替换掉,而不会影响程序的正确性。

3_l.jpg

I - 接口隔离原则

Interface Segregation Principle - 即 ISP

使用多个特定细分的接口比单一的总接口要好,不能强迫用户去依赖他们用不到的接口。

4_i.jpg

D - 依赖倒置原则

Dependency Inversion Principle - DIP

程序要依赖于抽象接口,而不是具体实现。

  • 高层模块不应该依赖于低层模块,二者都应该依赖于抽象
  • 抽象不应该依赖具体实现,具体实现应该依赖抽象

5_d.jpg

插头不应该依赖具体某种电线,它只需要有线并且能导电。

全文完~希望本文对你理解 SOLID 有帮助啦~

参考文章


本文首发于公众号:码力全开(codingonfire)

本文随意转载哈,注明原文链接即可,公号文章转载联系我开白名单就好~

codingonfire.jpg

查看原文

赞 17 收藏 11 评论 3

CrazyCodes 赞了问题 · 10月21日

php设计模式之适配器模式学习总结

一、什么是适配器模式

适配器模式是指通过适配器将原本不兼容的两个东西变得互相兼容

二、应用场景

当两个系统数据和行为都一样,但是接口不符合时,我们应该考虑使用适配器,适配器模式主要应用于希望复用现有的类,但是新的类又和原有的类不一致的情况其常见场景为:短信发送,聚合系统,支付系统

三、实例应用

1. 使用适配器(Adapter)实现短信发送实际案例
案例地址
Github地址: https://github.com/liuzhongsheng/SuperSms
实现目标:
多平台快速对接
多平台快速无缝切换
技术优势:
把每个短信平台看成一个适配器,新增短信平台时可快速添加,无需修改其他文件
运行流程:

image
以上为个人学习总结,如果有不对麻烦各位大佬多多指教,谢谢

关注 3 回答 1

CrazyCodes 回答了问题 · 10月21日

如何在不同服务中共用一套model层

承邀:
使用grpc,swoole建立微服务,将model层放入微服务中。例如 @风中有php做的云 给到你的答案。我没有这样做过,不过可以给你一些思路。

1.新建一个仅有Eloquent ORM的项目。
2.将所有model放入这个项目。这是我们的model微服务,composer+复制粘贴即可完成
3.在你原有的项目中需要实现model本身的方法,ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
4.最后,使用tcp或者http去通信你的微服务
5.微服务返回model实体
6.这样就无侵入的完成了model统一的需求

这仅仅是我的思路,未经过实践,建议不要使用在生产环境中。

关注 4 回答 3

CrazyCodes 赞了文章 · 10月20日

Hyperf 发布 v2.0.15 版本,企业级的 PHP 微服务云原生协程框架

更新内容

本周主要新增了部分特性,并修复了一些组件的 🐛Bug,继续提升 Hyperf 的稳定性,发布于 2.0.15 版。

建议用户使用以下命令更新此版本。

composer update "hyperf/*" -o

直接访问 官网 hyperf.io 或 文档 hyperf.wiki 查看更新内容

新增

  • #2654 新增方法 Hyperf\Utils\Resource::from,可以方便的将 string 转化为 resource

修复

  • #2634#2640 修复 snowflake 组件中,元数据生成器 RedisSecondMetaGenerator 会产生相同元数据的问题。
  • #2639 修复 json-rpc 组件中,异常无法正常被序列化的问题。
  • #2643 修复 scout:flush 执行失败的问题。

优化

  • #2656 优化了 json-rpc 组件,参数解析失败后,也可以返回对应的错误信息。

关于 Hyperf

Hyperf 是基于 Swoole 4.5+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 可替换可复用 的。

框架组件库除了常见的协程版的 MySQL 客户端Redis 客户端,还为您准备了协程版的 Eloquent ORMWebSocket 服务端及客户端JSON RPC 服务端及客户端GRPC 服务端及客户端OpenTracing(Zipkin, Jaeger) 客户端Guzzle HTTP 客户端Elasticsearch 客户端Consul、Nacos 服务中心ETCD 客户端AMQP 组件Nats 组件Apollo、ETCD、Zookeeper、Nacos 和阿里云 ACM 的配置中心基于令牌桶算法的限流器通用连接池熔断器Swagger 文档生成Swoole TrackerBlade、Smarty、Twig、Plates 和 ThinkTemplate 视图引擎Snowflake 全局ID生成器Prometheus 服务监控 等组件,省去了自己实现对应协程版本的麻烦。

Hyperf 还提供了 基于 PSR-11 的依赖注入容器注解AOP 面向切面编程基于 PSR-15 的中间件自定义进程基于 PSR-14 的事件管理器Redis/RabbitMQ 消息队列自动模型缓存基于 PSR-16 的缓存Crontab 秒级定时任务Sessioni18n 国际化Validation 表单验证 等非常便捷的功能,满足丰富的技术场景和业务场景,开箱即用。

框架初衷

尽管现在基于 PHP 语言开发的框架处于一个百花争鸣的时代,但仍旧未能看到一个优雅的设计与超高性能的共存的完美框架,亦没有看到一个真正为 PHP 微服务铺路的框架,此为 Hyperf 及其团队成员的初衷,我们将持续投入并为此付出努力,也欢迎你加入我们参与开源建设。

设计理念

Hyperspeed + Flexibility = Hyperf,从名字上我们就将 超高速灵活性 作为 Hyperf 的基因。

  • 对于超高速,我们基于 Swoole 协程并在框架设计上进行大量的优化以确保超高性能的输出。
  • 对于灵活性,我们基于 Hyperf 强大的依赖注入组件,组件均基于 PSR 标准 的契约和由 Hyperf 定义的契约实现,达到框架内的绝大部分的组件或类都是可替换的。

基于以上的特点,Hyperf 将存在丰富的可能性,如实现 单体 Web 服务,API 服务,网关服务,分布式中间件,微服务架构,游戏服务器,物联网(IOT)等。

文档齐全

我们投入了大量的时间用于文档的建设以提供高质量的文档体验,以解决各种因为文档缺失所带来的问题,文档上也提供了大量的示例,对新手同样友好。
Hyperf 官方开发文档

生产可用

我们为组件进行了大量的单元测试以保证逻辑的正确,目前存在 1551 个单测共 4813 个断言条件,Hyperf 是一款经历过严酷的生产环境考验的一个项目,目前已有很多的大型互联网企业都已将 Hyperf 部署到了自己的生产环境上并稳定运行。

官网及交流

Github 👈👈👈👈👈 点 Star 支持我们
Gitee 码云 👈👈👈👈👈 点 Star 支持我们
Hyperf 官网
Hyperf 文档
Hyperf 交流群(已满): 862099724
Hyperf 交流 2 群: 811414891

查看原文

赞 3 收藏 0 评论 0

CrazyCodes 发布了文章 · 10月20日

鼠标垫上的Git知识库

image.png

前言

Hello,大家好,我是CrazyCodes,之前在极客时间上买过一个git鼠标垫,感觉其知识点展示的非常干练,现手敲分享给大家,文末有购买链接。

Git最小配置

某账号下所有的Git仓库都有效

git config --global user.name '您的名称'
git config --global user.email '您的Email'

只对当前Git仓库有效

git config --local user.name '您的名称'
git config --local user.email '您的Email'

查看Git的配置

查看global类型的配置项

git config --global --list

查看只作用于当前仓库的配置项

git config --local --list

清除Git的配置

清除global类型的配置项

git config --unset --global 某个配置项

清除某个仓库的配置项

git config --unset --local 某个配置项

本地基本操作

查看变更情况

git status

查看当前工作在哪个分支上

git branch -v

切换到指定分支

git checkout 指定分支

把当前目录及其目录下所有变更都加入到暂存区

git add .

把仓库内所有变更都加入暂存区

git add -A

把指定文件添加到暂存区

git add 文件1 文件2 文件3

创建正式的commit

git commit 

比较某文件工作区和暂存区的差异

git diff 某文件

比较某文件暂存区和HEAD的差异

git diff HEAD 某文件

比较工作区和暂存区的所有差异

git diff --cached

把工作区指定文件恢复成和暂存区一样

git checkout 文件1 文件2 文件3

把暂存区指定文件恢复成和HEAD一样

git reset 文件1 文件2 文件3

把暂存区和工作区所有文件恢复成和HEAD一样

git reset --hard

用difftool比较任意两个commit的差异

git difftoll 提交A 提交B

查看哪些文件没被Git管控

git is-files --others

加塞临时任务的处理

把未处理完的变更先保存到stash中

git stash

临时任务处理完后继续之前未完的工作

git stash pop
或者
git stash apply

pop不保留stash,apply保留stash

查看所有的stash

git stash list

取回某次stash的变更

git stash pop stash@{数字n}

修改个人分支的历史

修改最后一次commit

  1. 在工作区修改文件
  2. git add .
  3. git commit --amend

修改中间的commit(代号x)

  1. git rebase -i X前面一个commit的id
  2. 在工作区修改文件
  3. git add .
  4. git rebase --continue

后续可能需要处理冲突,直到rebase结束

查看变更历史

当前分支各个commit用一行显示

git log --oneline

显示就近的n个commit

git log -n

用图示显示所有分支的历史

git log --oneline --graph --all

查看涉及到某文件变更的所有commit

git log 某文件

某文件各行最后修改对应的commit 以及作者

git blame 某文件

分支与标签

基于当前分支创建新分支

git branch 新分支

基于指定分支创建新分支

git branch 新分支 已有分支

基于某个commit创建分支

git branch 新分支 某个commit的id

创建分支并切换到该分支

git checkout -b 新分支

列出本地分支

git branch -v

列出本地和远端分支

git branch -av

列出远端所有分支

git branch -rv

列出名称符合某样式的远端分支

git branch -rv -l '某样式'

安全删除本地某分支

git branch -d 拟删除分支

强行删除本地某分支

git branch -D 拟删除分支

删除已合并到master分支的所有本地分支

git branch --merged master | grep -v '^\*\| master' | xargs -n 1 git branch -d

删除远端origin 已不存在的所有本地分支

git remote prune origin

给commit打上标签

git tag 标签名 commit的id

两分支之间的集成

把A分支合入到当前分支,且为merge创建commit

git merge A分支

把A分支合入到B分支,且为merge创建commet

git merge A分支 B分支

把当前分支基于B分支做rebase,以便把B分支合入到当前分支

git rebase B分支

把A分支基于B分支做rebase,以便把B分支合入到A分支

git rebase B分支 A分支

用mergetool解决冲突

git mergetool

和远端的交互

列出所有remote

git remote -v

增加remote

git remote add url地址

删除remote

git remote remove remote的名称

改变remote的name

git remote rename 旧名称 新名称

把远端所有分支和标签的变更都拉到本地

git fetch remote

把远端分支的变更拉到本地,且merge到本地分支

git pull remote 名称 分支名

把本地分支push到远端

git push remote 名称 分支名

删除远端分支

git push remote --delete 远端分支名
或者
git push remote 远端分支名

向远端提交指定标签

git push remote 标签名

向远端提交所有标签

git push remote --tags

致谢

感谢你看到这里,希望本篇文章可以帮到你,谢谢。

鼠标垫内容作者:苏玲 购买链接

查看原文

赞 14 收藏 9 评论 2

CrazyCodes 发布了文章 · 10月19日

PHP8.x 你必须知道的这些新特性

前言

Hello 大家好,我是CrazyCodes,距离上次发文已经过去4个月的时间,今年是悲惨的一年,也是奋发的一年,我会发布一些更好更实用的文章与大家分享,谢谢大家一直以来的支持。

本篇是我参加《2020 PHP开发者峰会》 Nikita分享内了解到的一些知识与大家分享

Nikita 是PHP8的核心开发者。
PHP8的版本会在今年11月26日与各位开发者见面,敬请期待

JIT

值得被提起的则是JIT新的特性,它会将PHP代码转换为传统的机器码,而并非通过zend虚拟机来运行,这样大大的增加了运行速度,但并不向下兼容,这意味着你不能通过像PHP5升级到PHP7那样获得该特性。

JIT可以通过php.ini去设置,例如这样

opcache.jit=on // on 代表打开,则off代表关闭

注解

PHP8版本彻底把注解扶正,当然在这之前像 Symfony,hyperf通过php-parser加入注解的使用方法,但这毕竟不属于PHP8内核真正的部分,在PHP8的版本中,但依旧需要反射

new ReflecationProperty(User::class,"id");

去获取到注解部分,看来注解在PHP的历史长河中还是需要继续不断完善的。

类中的成员变量

小的知识点

在PHP8之前,我们一般会这样定义一个类,首先要设置成员变量,然后在构造或者某一个方法为它赋值。

class User{
    public $username;
    public $phone;
    public $sex;
    
    public function __contruct(
        $username,$phone,$sex
    ){
        $this->username = $username;
        $this->phone = $phone;
        $this->sex = $sex;
    }
}

但在PHP8上,我们可以这样做

class User{
    public function __contruct(
        public string $username = "zhangsan",
        public string $phone = "110110";
        public string $sex = "男"
    ){}
}

命名参数

当我们创建一个函数时,例如

function roule($name,$controller,$model){
    // ... code
}

在调用这个函数时,我们需要顺序输入参数

roule("user/login","UserController","login");

但在PHP8中,我们可以这样做

roule(name:"user/login",controller:"UserController",model:"login");

因为可以需要输入参数名来区分传入的字段,那么在一些函数中,类比中间某项这段需要默认值,那我们就可以跳过这个字段

function roule($name,$controller="UserController",$model){
    // ... code
}
roule(name:"user/login",model:"login");

当然也可以以传统方式与其相结合

roule("user/login",model:"login");

联合类型

在PHP7中,我们在强制函数返回类型时是这样做的

function create() : bool

那么在PHP8中你可以使用多种预测类型

function create() : bool|string

当然在传参时也可以这样做

function create(bool|string $userId)

并且也可以设置类型NULL和TRUE,FALSE了。

总结

以上是PHP8主要的一些特性,所有表达和案例都是在Nikita的基础上描述的,并没有直接照搬,当然Nikita的演讲并不仅仅只有这些,为了保持对峰会主办方的尊重,还请各位移步至
https://www.itdks.com/Home/Ac...
观看Nikita的完整演讲。

致谢

感谢你看到这里,希望本篇文章对你的技术生涯多一分动力,谢谢!

查看原文

赞 16 收藏 7 评论 4

CrazyCodes 赞了回答 · 9月18日

php设计模式之适配器模式学习总结

比如你后面说的 新增短信平台时可快速添加,无需修改其他文件,而其实这一部分就涉及到 模板模式 的内容,又比如你说的 单平台多通道、多平台多通道、通道快速无缝切换 ,其实这一部分又涉及到了 策略模式 的内容,设计模式是一种面向对象开发的概念,在开发过程中无意间都会用到各种设计模式,甚至都没有可以的去使用它。

关于设计模式学习,可以找到很多文章介绍, 但是大部分都是过于干燥,推荐下面这个网站,通过一些现实栗子和代码的结合来详细介绍每一个设计模式,让其可以深入的理解到每一个设计模式。

当然,不要忘了,面向对象设计的 S.O.L.I.D 原则

关注 3 回答 1

CrazyCodes 回答了问题 · 9月17日

解决讨论讨论短信发送多平台多通道的方案可行性

成熟的方案,就选择上面大佬的回答,想自己锻炼锻炼就写适配器,写策略。但如果投入生产环境,还请不要过度自信呦o( ̄︶ ̄)o

关注 4 回答 3

CrazyCodes 赞了回答 · 9月17日

解决讨论讨论短信发送多平台多通道的方案可行性

已经有这样的方案了,之前在项目中页做过这样的方案,还是比较常见的。

参考下面这个包

关注 4 回答 3

CrazyCodes 赞了文章 · 9月16日

[扩展推荐] laravel-download-link —— 生成下载链接

Laravel

转载自 Laravel 论坛:https://learnku.com/laravel/t...

这个扩展包允许你生成文件的下载链接。

安装后,你可以执行以下操作:

$link = DownloadLink::disk('public')->filePath('uploads/test.txt')->generate();
// zkTu70fieUFZLGMoEP95l1RQfFj5zCOqHlM0XBTnc6ZaZTtm4GY5xPXGGLzLEAVe

配置文件中的默认下载路由为「download」,所以如果你的域名是「example.com」,则应使用此链接:

example.com/download/{link}

// 例如
example.com/download/zkTu70fieUFZLGMoEP95l1RQfFj5zCOqHlM0XBTnc6ZaZTtm4GY5xPXGGLzLEAVe

注意: 你需要将 {link} 替换成生成的链接。

你可以使用以下命令发布配置文件:

php artisan vendor:publish --provider="Armancodes\DownloadLink\DownloadLinkServiceProvider" --tag="config"

这是已发布的配置文件的内容:

return [
    /*
    |--------------------------------------------------------------------------
    | Download Route
    |--------------------------------------------------------------------------
    |
    | Download route will be added to your app URL for using download links.
    | E.g. if your app URL is "example.com", then if your set the download route to
    | "download" it will be "example.com/download/{link}".
    |
    */
    'download_route' => 'download',
];

使用

你可以使用给定名称显式设置要保存和下载的文件名:

$link = DownloadLink::disk('public')->filePath('uploads/test.txt')->fileName('new-text.txt')->generate();

还可以添加过期时间,以便仅在链接过期之前可用:

$link = DownloadLink::disk('public')->filePath('uploads/test.txt')->expire(now()->addDay())->generate();

你还可以指定是否只有经过身份验证的用户或游客才能使用该链接:

// 仅通过身份验证的用户
$link = DownloadLink::disk('public')->filePath('uploads/test.txt')->auth()->generate();

// 仅游客
$link = DownloadLink::disk('public')->filePath('uploads/test.txt')->guest()->generate();

你可以将一个或多个IP地址放入黑名单(下载链接不适用于这些IP地址):

$link = DownloadLink::disk('public')->filePath('uploads/test.txt')->limitIp('127.0.0.1')->generate();

$link = DownloadLink::disk('public')->filePath('uploads/test.txt')->limitIp(['127.0.0.1', '127.0.0.2', '127.0.0.3'])->generate();

或者,您可以将一个或多个IP地址放入白名单(下载链接仅适用于这些IP地址):

$link = DownloadLink::disk('public')->filePath('uploads/test.txt')->allowIp('127.0.0.1')->generate();

$link = DownloadLink::disk('public')->filePath('uploads/test.txt')->allowIp(['127.0.0.1', '127.0.0.2', '127.0.0.3'])->generate();

配置文件中的默认下载路由为「download」,所以如果你的域名是「example.com」,则应使用此链接:

example.com/download/{link}

// 例如
example.com/download/zkTu70fieUFZLGMoEP95l1RQfFj5zCOqHlM0XBTnc6ZaZTtm4GY5xPXGGLzLEAVe

注意: 你需要将 {link} 替换成生成的链接。

你可以这样删除一个链接:

DownloadLink::delete('link');

// For example
DownloadLink::delete('zkTu70fieUFZLGMoEP95l1RQfFj5zCOqHlM0XBTnc6ZaZTtm4GY5xPXGGLzLEAVe');

你可以使用以下命令删除数据库中的过期链接:

php artisan download-links:remove-expired
讨论请前往专业的 Laravel 论坛:https://learnku.com/laravel/t...
查看原文

赞 5 收藏 3 评论 0

CrazyCodes 赞了文章 · 9月1日

Nginx 对访问量的控制

目的

了解 Nginx 的 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 模块,对请求访问量进行控制。

Nginx 模块化

nginx 的内部结构是由核心模块和一系列的功能模块所组成。模块化架构使得每个模块的功能相对简单,实现高内聚,同时也便于对 Nginx 进行功能扩展。
针对 web 请求,Nginx 所有开启的模块会组成一条链,类似于闯关游戏中的一道道关卡,每个模块负责特定的功能,例如实现压缩的 ngx_http_gzip_module 模块,实现验证的 ngx_http_auth_basic_module 模块和实现代理的 ngx_http_proxy_module 模块等。连接到服务器的请求,会依次经过Nginx各个模块的处理,只有通过这些模块处理之后的请求才会真正的传递给后台程序代码进行处理。

Nginx 并发访问控制

对于 web 服务器而言,当遇到网络爬虫,或者恶意大流量攻击访问时,会造成服务器内存和 CPU 爆满,带宽也会跑满,所以作为成熟的服务器代理软件,需要可以对这些情况进行控制。
Nginx 控制并发的方法有两种,一种是通过IP或者其他参数控制其并发量;另外一种是控制单位时间内总的请求处理量。即对并发和并行的控制,这两个功能分别由 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 模块负责实现。

ngx_http_limit_conn_module 模块

说明

该模块主要用于对请求并发量进行控制。

参数配置

  • limit_conn_zone
指令配置 limit_conn_zone key zone=name:size
配置的上下文:http
说明:key 是 Nginx 中的变量,通常为 $binary_remote_addr | $server_name;name 为共享内存的名称,size 为该共享内存的大小;此配置会申请一块共享内存空间 name,并且保存 key 的访问情况
  • limit_conn_log_level
语法:limit_conn_log_level info|notice|warn|error
默认值:error
配置上下文:http,server,location
说明:当访问达到最大限制之后,会将访问情况记录在日志中
  • limit_conn
语法:limit_conn zone_name number
配置上下文:http,server,location
说明:使用 zone_name 进行访问并发控制,当超过 number 时返回对应的错误码
  • limit_conn_status
语法:limit_conn_status code
默认值:503
配置上下文:http,server,location
说明:当访问超过限制 number 时,给客户端返回的错误码,此错误码可以配合 error_page 等参数,在访问超量时给客户返回友好的错误页面
  • limit_rate
语法:limit_rate rate
默认值:0
配置上下文:http,server,location
说明:对每个链接的速率进行限制,rate 表示每秒的下载速度;
  • limit_rate_after
语法:limit_rate_after size
配置上下文:http,server,location
说明:此命令和 limit_rate 配合,当流量超过 size 之后,limit_rate 才开始生效

简单配置示例

limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
    listen       80;
    server_name  www.domain.com;
    root   /path/;
    index  index.html index.htm;
    location /ip {
      limit_conn_status 503; # 超限制后返回的状态码;
      limit_conn_log_level warn; # 日志记录级别
      limit_rate 50; # 带宽限制
      limit_conn addr 1; # 控制并发访问
    }
    # 当超过并发访问限制时,返回503错误页面
    error_page 503  /503.html;
}

ngx_http_limit_req_module 模块

说明

该模块主要控制单位时间内的请求数。使用 “leaky bucket” (漏斗)算法进行过滤,在设置好限制 rate 之后,当单位时间内请求数超过 rate 时,模块会检测 burst 值,如果值为0,则请求会依据 delay|nodelay 配置返回错误或者进行等待;如果 burst 大于0时,当请求数大于 rate 但小于 burst 时,请求进入等待队列进行处理。

参数配置

  • limit_req_zone
语法:limit_req_zone key zone=name:size rate=rate
配置上下文:http
说明:key 是 Nginx 中的变量,通常为 $binary_remote_addr | $server_name;name 为共享内存的名称,size 为该共享内存的大小;rate 为访问频率,单位为 r/s 、r/m 。此配置会申请一块共享内存空间 name,并且保存 $key 的访问情况;
  • limit_req
语法: limit_rate zone=name [burst=number] [nodelay|delay=number]
配置上下文:http,server,location
说明:开启限制,burst设置最多容量,nodelay决定当请求超量是,是等待处理还是返回错误码;
  • limit_req_log_level 和 limit_req_status 配置参数左右与ngx_http_limit_conn_module模块一致;

简单配置示例

limit_req_zone $binary_remote_addr zone=req:10m rate=2r/m;
server {
    listen       80;
    server_name  www.domain.com;
    root   /path/;
    index  index.html index.htm;
    location /limit {
      limit_req zone=req burst=3 nodelay;
    }
    # 当超过并发访问限制时,返回503错误页面
    error_page 503  /503.html;
}

注意

这两种访问控制都需要申请内存空间,既然有内存空间,当然会存在内存耗尽的情况,这时新的请求都会被返回错误,所以当开启访问量限制时,需要通过监控防止此类情况发生。

小结

通过对 Nginx 模块化架构的简单介绍,重点了解 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 模块的功能和配置参数,实现 Nginx 对请求的并发控制。如有不对,还请指教

查看原文

赞 3 收藏 2 评论 0

CrazyCodes 赞了文章 · 7月12日

ThinkPHP(四)

前言

这一周的学习就是在迷惑中度过了,学完后的感觉就是:我还想再多看看(手动滑稽)。目前的编程能力还是很差。感觉自己在看教程的时候,思考的方式有了一丝丝改变,以前遇到问题都会想这个是为什么,这个过程中的具体原理,但是这个教程很多的地方就是那么的莫名其妙。

我正在进行复习,并且整理自己关于ThinkPHP的知识点,应该下周能够全部完工,接下来是这一周学习过程中的一些总结

关于MCA

这是一个我们开始就学到的知识点,为什么现在还要提起来呢,越到后面就越发现,这个是一切的基础,核心的核心。

编程的时候

  1. 我们在ThinkPHP下面编程的思路就是MCA,即模块-控制器-触发器,MCA进行工作的原理是ThinkPHP规定好的,就是这个样子,我们要做的是在这个框架之下,把用户需求,代码结构不断组建完美
  2. 当遇到问题的时候,排错的思路也和MCA分不开,当然这指的是那些大的,结构性的错误

URL

  1. 虽然MCA的URL方式对于客户并不友好,但是在开发的过程中却很方便,我们可以通过MCA方式的URL来准确定位我们需要看到的问题,这也是一种启示,把写出来的东西变得直观、简单是我们高效完成任务的法宝。
  2. 在更改URL,定制路由的时候,要细心,要命的是一些小错误

重构的时候

  1. 写完代码之后就是重构的过程,精雕细琢的过程,第一次写出来的代码,我们无可避免的会重复造很多的轮子,重构的过程就是在MCA中进行观察总结的过程。

关于模板引擎

  1. 当我在html文档中写入的php语言出错的时候,我惊奇的发现,报错的文件是一个我没见过的php文件,这个文件有着和我写的html文档相同的html语言,并且php的标签被翻译成了php语言插入到了文件当中
  2. 这涉及到了一个东西叫做模板引擎,我们在ThinkPHP中写出来的嵌入PHP标签的html代码都属于动态的东西,这个模板引擎的作用就是把这些动态的东西转换成静态的html代码来展示给客户端,因为客户端需要的是一个静态的页面,
  3. 模板引擎将html中的php代码转换完成之后,会在runtime文件夹下生成一个文件名为一对乱码(可能有规律,只不过我不知道)的html文件
  4. 寻找该文件可以采用以下方法:1.在html中写入特定的语言,然后再runtime中搜索;2.直接搜索相应的文件名ctrl+p
  5. 一个小规律:我们通过验证发现在我们插入php语句的时候,格式应该为{:php语句},系统会自动加上末尾的分号

获取器

  1. 很多遇到的问题Thinkphp都已经为我们想好了,我么需要的就是了解+使用
  2. 获取器的作用是在获取数据的字段值后自动进行处理
  3. 我们获取数据库中的信息到达前端显示的时候,需要把它变成我们希望显示的信息格式,这有两种方法,一是在html文档中进行处理,二是在后端的M层加上获取器,我们在开发的时候,第二种方法更直白,获取器就是为了这种需求而生的。

其他的小问题

  1. 本周在写代码的时候遇到的问题大多数都是语法问题,自己解决不了的也能通过与泽龙的交流得到有效解决
  2. 教程的后半部分有些地方的结构老师都一笔带过了需要自己对照前面的方式自己去写,这个过程很简单,也很有收获,就是跟之前的相比,缺啥写啥
  3. 使用其他的类,要提前use其他的类
  4. 我们想到的,ThinkPHP早就为我们想到了
  5. 有些功能,是继承而来的,并不需要我们去写

缺点与不足

  1. 最大的缺点就是编程能力,现在的感觉就是虽然自己跟着教程走了一遍,但是对于php的编程能力还远远没有达到要求
  2. 接下来的重点目标是写代码,编程编程再编程,把之前的代码再写一写,完成重构,要善于发现问题,解决问题

其他的话

这周走了三个小伙伴,人各有志,总能找到结伴而行的人,对于未来的方向,自己也不是很确定,路在脚下,我更倾向于浪漫主义的想法,跟着心努力的走下去,无问西东。

本文作者:河北工业大学梦云智开发团队 温宇航

查看原文

赞 10 收藏 1 评论 1

CrazyCodes 赞了文章 · 7月7日

新书《Go语言编程之旅:一起用Go做项目》出版啦!

最早从我在 Segmentfault 开始写技术文章起,不知不觉近三年过去了,咨询和催我出书和读者逐年递增,在 2019 年算是达到一个高峰。当然,综合考虑下我也是一直拒绝的,觉得火候还不够。

直至 2019.09 月,polaris 主动找到了我,说有事情想找我商量,本着 “如果你在纠结一件事情做还是不做,不如先做了看看结果,至少不会后悔” 的想法,更何况是长期被 Ping,因此我一口答应下来,故事自此开始了。

image

本书定位

本书不直接介绍 Go 语言的语法基础,内容将面向项目实践,同时会针对核心细节进行分析。而在实际项目迭代中,常常会出现或多或少的事故,因此本书也针对 Go 语言的大杀器(分析工具)以及常见问题进行了全面讲解。

本书适合已经大致学习了 Go 语言的基础语法后,想要跨越到下一个阶段的开发人员,可以填补该阶段的空白和进一步拓展你的思维方向。

读者定位

  • 基本了解 Go 语言的语法和使用方式的开发人员。
  • 想要进行 Go 相关项目实践和进一步摸索的开发人员。
  • 希望熟悉 Go 常用分析工具的开发人员。

本书大纲

本书针对常见的项目类型,主要细分为 5 + 1 板块,分别是命令行、HTTP、RPC、Websocket 应用、进程内缓存以及 Go 中的大杀器。

同时我们在项目开发、细节分析、运行时分析等方方面面都进行了较深入的介绍和说明,能够为 Go 语言开发者提供相对完整的项目实践经验,而如果深入阅读第六章的章节,更能够为未来各类问题出现时的问题排查提供一份强大的知识板块。

如下为本书的思维导图概览:

image

如何阅读这本书

常规的列目录未免太无趣。我想不如说说从我个人的角度,所看到读者们在近 3 年来是如何阅读/实践我的实践系列文章的,其面向的读者群体是完全一致的。希望能够从另外一个角度告诉你,应当如何阅读这本书,尽可能的效益最大化。

首先,图书,买来要读,而与实战结合的图书,势必需要实践,实践最常见又分为脑内思考和上机实践:

image

而在持续的交流中,可以发现至少会延伸出以下几类深入层次的不同:

image

  • 第一层:只阅读,留有印象,需要时再唤醒,也行。
  • 第二层:阅读并实践,实打实的完成项目实践,收获丰满。
  • 第三层:实践的过程中,一定会遇到或大或小的问题,有的人会放弃,这就是分叉点。但有的读者会持续排查,其提升了个人能力(排错能力很重要)。
  • 第四层:实践完毕后,有自己的想法,认为某某地方还可以这样,也可以再实现更多的功能,举一反三,进一步拓展,并对项目提 issues 或进行 pr。
  • 第五层:完成整体项目后,抽离业务代码,标准化框架,实现框架的应用脚手架,并有的读者会进一步开源。
  • 第六层:形成脚手架后,在自己业务组开始落地,实际在项目中使用,由业务学习转化为企业实践。
  • 第七层:在内部落地实践稳妥后,开始在其它业务组开始推广该框架脚手架,进一步标准化,拓展思路。

通过上图中 “七层金字塔” 的理解,我们不难发现其对于实践项目的理解和应用已经不再是单单这个项目,而是有了更深远的意义,抽象一下,对照着著名的 “学习效率金字塔” 来看:

image

在单纯的 “阅读” 时,其基本处于 “被动学习” 的阶段,而单进入阅读并实践时,已经转为了 “主动学习”,且绝大部分的读者做完实践后,表示 “嗯,实践完,挺好的,有所得”。

这时候就会进入到一个新的阶段(分叉点),绝大部分读者在做完后,会纠结 ”接下来要做什么“:

image

有部分读者会停滞,也有部分读者会转入 “转教别人/立即应用” 的阶段,也就是普遍的在企业内部进行标准化的使用,又或是开源项目,据此得到更一步的深入实践和提高,更大的吸收差距也在于此。

当然,这一切都要基于前面的 “1”,你得先买了书,读了书,接着就是你的选择和创建机遇的能力了,不同的路线效益自然不一样。

广告时间

在《Go语言编程之旅:一起用Go做项目》写作中后期,作为 2020 年的煎鱼,我回顾了 2018、2019 年的煎鱼所写的文章,在现在看来发现多多少少都有些瑕疵。再对比本书,在同类主题下,写出的内容更具知识结构化和实战意义,且能做出更优的选题抉择,确实变化了。

因此我也在这里正式向你推荐本书,希望能够给所有 Go 语言爱好者带来更大的技术价值和切切实实的项目实践经验。

后续有任何问题或建议也欢迎随时来交流。

image

关于写书

有关注我的小伙伴应该会发现,我之前突然退了很多个微信群,并且停止了博客的更新,也较少在社区里冒泡了。其实本质上是为了给写书让路,希望尽可能的把业余时间都聚焦在写书上。

这时候又会有另外一个问题,那就是写书,是一件非常长耗时的事情,没有任何的外界反馈,因此我严格做了一系列的 todolist 和时间节点的管理,围绕着自己的生活作息设置了一系列闹钟作为信号量提醒自己。

基本是吃饭、睡前构思结构、想灵感,下班回到家一坐下就开始写内容。当然,我也经常走火入魔一想到好的灵感就激动的掏出手机记在工具上,免得第二天大脑重置后丢失了数据,那就很可惜。

最终在长期的坚持下自然而然也就完成了这本书的写作。

感谢你们

非常感谢 polaris,在艰难的情况下依旧完成了本书的编写。感谢博文视点的编辑安娜,基本从不催更。感谢曹大、无闻、杨文、傲飞、大彬、晓东的推荐词或 Review.

我还记得当时曹大的书出版时,因为种种原因,我还立下过 ”绝不写书” 的 flag,和晓东在深圳湾一号吃自助餐时立过 “绝对不会放弃,一定会写完” 的 flag,果然计划赶不上变化,flag 该折折。

当然,最该感谢的还是我司的研发负责人,当年把我从个小角落里筛了出来,否则也不会有这一切的开端了。

查看原文

赞 23 收藏 1 评论 11

CrazyCodes 发布了文章 · 4月27日

电商系统设计之运费模板(上)

clipboard.png

电商大伙每天都在用,类似某猫,某狗等。
电商系统设计看似复杂又很简单,看似简单又很复杂
本章适合初中级工程师细看,大佬请随意

前言

在订单系统中,运费模板是其中一个重要组成部分,看似简单的一个设置,在其内的设计中,要考虑的问题还是很多滴,开始进入正题

运费模板

1587983386971.jpg

运费模板由

  • 模板名称
  • 是否包邮
  • 默认运费
  • 特定地区运费

四部分组成,所谓模板则就是设置这样一个框架,由多个商品多对一调用一个模板,通过模板设置的规则来计算配送费用,看似简单的功能,由我来拆解开跟各位聊聊。

运费规则

无论是默认运费还是特定地区运费,无非设置如下
image.png
默认几件内多少元,每增加几件运费增加多少元
特定地区则多几步设置
image.png
image.png
特定地区的运费规则可设置多个,对某个偏远地区,如西藏、新疆设置独立的配送费用

设计原则

在运费模板的设计上,应当遵循一个通用原则,难在新增易在查询,一个应用程序使用查询语句的次数要比插入多多了。当然也应该尽可能的做到增删改查都比较简单才是最佳。

首页整理下,运费模板使用的位置

  • 后台的运费模板管理(增删改查)
  • 前端实时计算运费
  • 后端接收订单后进行的运费计算
  • 后续的退款(如未发货,则应退运费)

在数据库设计中,尤其是电商相关的数据表设计,竟然会使用冗余的方法处理相关数据,意在永久保存用户在下单的时候产生的关联数据,这些数据不会因其他字表修改而变化。

数据表设计

本次对运费模板上的设计,采用一主表一子表的方式来做。
主表则是由简单的模板名称,是否包邮,创建时间构成,表结构如下

CREATE TABLE `product_template` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '模板名称',
  `type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '类型 0 自定义运费 1 包邮',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

而子表为运费规则表,也是运费模板的核心灵魂,直接决定了是否会简化增删改查的复杂度。我以一对多的方式来设计规则表。将默认运费与指定运费合并在一个表内,表结构如下

CREATE TABLE `product_template_rule` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `template_id` int(11) NOT NULL COMMENT '模板编码',
  `city` text COLLATE utf8mb4_unicode_ci COMMENT '城市',
  `default_number` int(11) NOT NULL DEFAULT '0' COMMENT '默认数量',
  `default_price` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '默认运费',
  `create_number` int(11) NOT NULL DEFAULT '0' COMMENT '新增数量',
  `create_price` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '新增运费',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

通过template_id查询指定运费模板内包含的所有规则,因为默认运费是不需要选择城市的。所以则为 (Laravel 代码)

ProductTemplateRule::where([
        ['template_id', '=', $templateId],
    ])
        ->where('city', '=', '[]')
        ->first();

而指定城市批量查询出来则使用

ProductTemplateRule::where([
        ['template_id', '=', $templateId],
    ])
        ->where('city', '!=', '[]')
        ->first();

规则查询就这样简单的完成了。查询如此简单,插入其实也并不是太难,代码如下,前端通过JSON方式将已设置好的模板规则发送到后端,如果是默认运费模板则城市为空JSON,JSON格式如下

[
    {
        'city'=>[],
        'default_number'=>1,
        'default_price'=>1.00,
        'create_number'=>1,
        'create_price'=>1.00
    },
    {
        'city'=>['北京市','上海市'],
        'default_number'=>1,
        'default_price'=>1.00,
        'create_number'=>1,
        'create_price'=>1.00
    }
]

最终的创建运费模板的代码如下

public function create(Request $request)
{
    $template        = new ProductTemplate();
    $template->title = $request->title;
    $template->type  = $request->type;
    $result          = $template->save();

    if (!$result) {
        throw new \Exception('创建失败');
    }

    $config = json_decode($request->config);
    foreach ($config as $item) {
        $rule                 = new ProductTemplateRule();
        $rule->template_id    = $template->id;
        $rule->city           = json_encode($item->city);
        $rule->default_number = $item->default_number;
        $rule->default_price  = $item->default_price;
        $rule->create_number  = $item->create_number;
        $rule->create_price   = $item->create_price;
        $rule->save();
    }

}

本章对设计表和如何创建做了详细讲解,下章说说应当如何计算运费效率最高~

致谢

感谢你看到这里,希望本篇文章可以帮助到你,谢谢。

查看原文

赞 20 收藏 14 评论 5

CrazyCodes 发布了文章 · 3月14日

用MAC还安装集成环境可就OUT喽

image.png

前言

大家好,我是CrazyCodes,今天聊聊为什么在MAC上,我不安装类似XAMPP或者Laravel的Homestead的集成开发环境

对比

我也是卸载了这些环境不到一年的时间,为何要去卸载他呢,原因其实很简单,扩展性差,这里这个扩展性指的不是集成环境这个软件本身的扩展性,当初安装的目的其实不就是省事嘛~,也不会过多的查看文档,而是在需要扩展的时候,学习成本会逐渐提高,这里的扩展性=学习成本。

开始

MAC自带了Apache和PHP的版本,这时候直接安装一个MySQL其实就可以进入开发了。可以选择使用brew安装

brew install mysql

当然如果希望使用其他版本的PHP或者是将Apache替换为Nginx也是很简单的时候,只要部署过单机服务器,其实在Mac上的步骤是差不多的。

php

首先还是使用brew安装一个你心仪的PHP版本,可以通过

brew search php7

来搜索下现有的php7+都有哪些版本,这里在php@7.3上打了✔️,意思是我已经安装了这个版本,现在使用7.4版本做一些讲解。
image.png

brew install php@7.4

image.png
经过一顿猛如虎的操作后,正常状况下会看到下面这样
image.png
多么人性化的提示,还告诉了咱们如何配置。当然这不是主要的,看要最下面这段

The php.ini and php-fpm.ini file can be found in:
    /usr/local/etc/php/7.4/

To have launchd start php now and restart at login:
  brew services start php
Or, if you don't want/need a background service you can just run:
  php-fpm

安装完成后,他会说明php安装到什么位置了,可以使用命令brew services start php或者php-fpm去启动和重启PHP,这个时候就可以在指定目录下看到熟知的php相关文件
image.png

nginx

依旧是使用brew安装一个你心仪的nginx版本
image.png
这里我已经安装过nginx了。就不截图演示了。具体操作如下

brew install nginx

一顿操作猛如虎后,与PHP安装完成后的提示一样,会告诉我们安装到哪个目录下了,一般默认为

/usr/local/etc/nginx

image.png
依旧也是我们熟知的NGINX相关的目录以及配置文件,servers目录是我新建的,用于存放server配置

mysql

依旧依旧是使用brew安装一个你心仪的mysql版本,通过使用命令

brew search mysql

image.png
这时要看清楚,有些并不是mysql本体,可能会是一些链接库。要脑子清楚的选择安装,mysql8我已经安装,以5.6为例

brew install mysql@5.6

一顿操作猛如虎后,mysql也如期安装完成,正常情况下不会报错的

补充

全部完成后,按照正常步骤

1.启动Nginx
2.启动PHP
3.启动MySQL

访问链接 http://localhost
会看到nginx友爱的欢迎界面。

nginx server配置与单机配置是一致的。如果感觉配置host每次都很麻烦,可以使用一个ihost去统一管理
image.png

image.png

所有源码都与源码包安装一致,相信你一定会按需安装需要的扩展了把~

致谢

感谢你看到这里,希望本篇文章可以帮到你。

查看原文

赞 5 收藏 2 评论 0

CrazyCodes 赞了文章 · 1月20日

那些年我在开发中使用的编程字体们

1.前言

可能有的同学已经放假在家了,我也快了。最近不想聊具体的技术了,过年了聊点轻松的东西。但是又不想偏离编程太远,所以我今天聊聊我们常用的一些编程字体。在阅读代码的时候眼睛需要以不同寻常的方式移动(垂直和水平方向),这与书籍类阅读有很大的不同(通常沿着同一方向的文本而滑动)。所以字体也是生产力的组成部分。接下来介绍我一些常用的字体。

2. Consolas

Consolas 我用了挺久的,那时候我还在用 eclipse 。这是一套等宽字体,属无衬线字体,由丹麦设计师 Lucas de Groot 设计,这套字型使用了微软的 ClearType 字型平滑技术。
使用 Microsoft Windows 作为开发 OS 环境感觉更加明显。现在我已经不太使用这种字体了。

3. Source Code Pro

时间长了,审美疲劳了,我又切换到了另一款字体 Source Code Pro 。它是这样的:

它由大名鼎鼎的 Adobe 公司发布的一款开源且完全免费的等宽编程字体,从名字上你就知道它是干啥的。在 MacOSWindows 上的阅读感都不错。

4. Inconsolata

码农太容易“喜新厌旧”了,Inconsolata 是同事那里 copy 来的:

我不知道它跟 Consolas 之间是什么关系,但是这个比 Consolas 细腻了不少。宽度恰好是半角,搭配中文不会把汉字压扁。

5. Fira Code

换了 MacBook Pro 进行开发的一段时间我用喜欢上了下面这种字体:

Fira CodeMozilla 提供的字体,它基于 Fira Mono 等宽字体的一个扩展,主要特点是加入了编程连字特性,注意上图中的 -> 符号。如果感觉不明显来看看我们常用的几个:

是不是很有意思呢?你可以尝试一下。

6. Droid Sans Mono

这个是 Intellij Idea 某次更新提及的字体,我试用了一下还不错,这是为 Android 设计的一种字体,很漂亮,但是 0O 并没有区分,这个是最大的缺陷,相信很多同学会因为这个而放弃它,希望后续能出一个魔改版。

7. JetBrains Mono

从 2019.3 版本的 Intellij Idea 开始 JetBrains 开始提供他们专为开发人员而设计的 Mono 新字体。我确实被惊艳到了,所以到目前为止我还在使用它:

是不是 JetBrains 的设计能力需要再吹一波了?

8. Losevka

这个是我刚刚看到的很多人推崇的一个字体 —— Losevka 。据说跟中文搭配非常好,不用担心出现对齐问题了。

9. 总结

一千个观众眼中有一千个哈姆雷特。

所以上面的可能符合一些同学的口味,也可能不符合另一些同学的口味,所以我这里还有一个黑科技网站 编程字体。你可以从中挑选其它适合你的字体。你可以把你喜欢的字体也通过公众号:Felordcn 留言告诉大家。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

查看原文

赞 8 收藏 5 评论 1

CrazyCodes 发布了文章 · 1月15日

2020 PHP程序员修炼秘籍

a4f63d04e243b1230c7ca9d02f57c95b_37806.png

前言

大家好,我是CrazyCodes,一名正在创业路上的程序员,今天我为各位整理2020年PHP程序员修炼秘籍,希望可以帮到你。

语言

2019年是不安分的一年,身为程序员的我们也是恐慌不已,大厂各种裁员,整的程序员界人心惶惶。就算是这样,依旧有很多喷子攻击我大PHP阵营

张三喷子:“php已经不行了”,马上要被什么什么替代了。
李四喷子:“php这个技术不如这门语言了,不如那门语言了”
王五喷子:“身边朋友都去学某某语言了,php不行了”

其实吧,作为多年php圈子里面的混混,我想说两句

首先,奉上最新的世界开发语言排行榜

image.png

至今为止,其实PHP没有跑出前十名,其实会不会跑出前十名这并不重要。JavaScript在PHP前面,也并不会代表什么。

发表下个人意见吧

  1. 开发语言的存在即合理
  2. PHP算是一门老语言,在互联网发展长河里,PHP语言承担着历史上的重要
  3. 无论出现什么形式的新开发语言,都无法代替PHP本身在界内的影响力

开发框架

2019年并没有出现特别火爆的新开发框架。
位于榜首的依旧是万能脚手架 - Laravel

Laravel

在过去的一年,我见过太多太多PHP的项目在重构过程中慢慢引进Laravel,并将Laravel作为项目首选开发框架。

当然我也是如此,作为Laravel框架的早期使用者,我由衷的感觉Laravel在近些年内的地位还是很稳定的。

有些人要说了,Laravel框架太重、运行速度太慢、blblblbl的各种原因,我只能说,羊毛出在羊身上,Laravel是组件化开发早期框架,感觉哪个慢就不加载哪个呗,哪个重就删掉不就行了,一天天不找解决方案,只会抛出问题,难道Laravel框架的开发者会按照小众个人意愿去改嘛😆

其他的框架我很少了解,在这里就着重讲解下Laravel

框架本身没什么好说的,讲些Laravel社区生态相关的事。

文档

首先说的是完整的框架中文相关文档,这里必须提到一个大佬Summer,是这位大佬建立起Laravel中文社区,让所有Laravel框架使用者不再对英文发愁
https://learnku.com/laravel
image.png

开发

让开发者更快速的构建属于自己的PHP程序,Laravel做了很多。例如一键启动PHP程序

php artisan serve

这让PHP程序员在任意的一台电脑上都可以轻松编写PHP代码并直接运行

当然还有专属于Laravel的开发环境 Homestead

扩展

最后是各种第三方扩展不断丰富着Laravel社区,例如

Horizon,它为Laravel提供了队列可视化的仪表盘,为什么列出Horizon呢,是因为对于程序员来说,看不到或者无法断言的任何事情,会让程序员没有安全感,而恰恰Horizon让你看到所有你想看到的事件

还需要强调的一个Telescope,我现在的项目内也使用了Telescope

它会检测框架内所有的请求,并列出相关信息,当程序出现问题的时候,你会发现Telescope简直是救命神器

还有很多很多的工具等待你的使用

image.png

当然选择什么框架,用什么方式来去做PHP语言的相关开发,还是要根据需求和个人喜好去选择。都是PHP大营的产品,这里不做太多描述。(怕被自己人打😆)

Swoole


Swoole算是重新托起了PHP在开发语言中的地位。将以往无法实现或者实现困难的问题几乎全部解决。

Swoole已经众所周知,本篇就不过多描述了。
https://www.swoole.com/

工具

众所周知,在开发过程中,仅仅熟练使用自己的本命语言是完全不够的。还要依托一些三方工具,去不断提升开发效率和编码质量。

Sequel Pro

image.png

Sequel Pro 是一款数据库管理软件,在使用过不会因数据量过大而卡死,UI精美小巧。是我这些年来一直使用数据库管理软件。

VLC

image.png
这是一款测试推拉流的工具,至今是没有找到比它更好的软件代替

PhpStorm

每位程序员都有自己钟爱的开发工具,PhpStorm则是我的首选。可能本身体积略大,耗费内存也比较高,对电脑本身是有一些要求的。
image.png
但当你真正熟练使用它的时候,会发现开发速度不是一般的快。

ShadowsocksX

image.png
这个少说为好,如果是一名真正的程序员,我相信翻qiao对TA来说比媳妇还重要

PostMan

image.png
在移动互联网时代,每位PHP程序员都必须要开发接口。而PostMan在开发过程中作为调试神奇,是每位程序员装机必备之佳品

有道云笔记

image.png
其实吧,这个也属于程序员必备。人生漫漫,在从事开发事业的过程中,要记录的东西还是很多的吧。

Alfred

image.png
Mac必备神器,当用了它后,我感觉生活水平都提高了😆

GitKraken

image.png

GitKraken是我迄今为止见过ui做的最美的git客户端

还有很多很多工具有待发现,当然一把趁手的刀才是好刀,各位朋友按需选择

前端

简单聊一下前端,近些年来,前端发展迅速,我认为作为一名程序,无论是做前端、后端、服务端还是PC端开发的。都应去了解其“火”的原因,去了解,去实践,不要被时代抛弃。

前端技术我的建议是:还是需要去学习的,要不要深学要看个人需求

最后

当我发出思否2019年总结文章的时候,相信大家已经知道我不再是公司员工了。

对于创业,我只想说,提升自己全方面的能力,不仅仅是技术大拿那么简单的事情了。创业是另外一种生活方式,如要选择,便是不归路。

各位准备创业的程序员朋友,请三思而后行。

顺便宣传下我创业的产品,是一款习惯养成的APP,多年来我都是严格要求自己,去年我做了这款产品,希望可以让更多的人自律起来。真正的自由,是自律带给你的选择权

image.png

致谢

感谢你看到这里,希望本篇文章可以帮助到你,谢谢。

查看原文

赞 72 收藏 36 评论 21