实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 对微信退款回调的加密数据进行解密
*
* @param string $encryptData 原始加密数据
* @param string $key 商户 key
*
* @return string 解密后的 xml 数据
*/
public function decryptData( $encryptData, $key = '' )
{
//1. base64_decode
$encryptData = base64_decode($encryptData);

//2. md5 original key
$md5LowerKey = strtolower(md5($key));

//3. decrypt AES ECB
$decrypted = openssl_decrypt($encryptData, 'AES-256-ECB', $md5LowerKey, OPENSSL_RAW_DATA);

return $decrypted;
}

遇到的坑

  • openssl_decrypt 第四个参数一定要使用 OPENSSL_RAW_DATA

PHP 中的 Exception, Error, Throwable

  • PHP 中将代码自身异常(一般是环境或者语法非法所致)称作错误 Error,将运行中出现的逻辑错误称为异常 Exception
  • 错误是没法通过代码处理的,而异常则可以通过 try/catch 来处理
  • PHP7 中出现了 Throwable 接口,该接口由 ErrorException 实现,用户不能直接实现 Throwable 接口,而只能通过继承 Exception 来实现接口

PHP7 异常处理机制

过去的 PHP,处理致命错误几乎是不可能的。致命错误不会调用由 set_error_handler() 设置的处理方式,而是简单的停止脚本的执行。

在 PHP7 中,当致命错误和可捕获的错误(E_ERRORE_RECOVERABLE_ERROR)发生时会抛出异常,而不是直接停止脚本的运行。对于某些情况,比如内存溢出,致命错误则仍然像之前一样直接停止脚本执行。在 PHP7 中,一个未捕获的异常也会是一个致命错误。这意味着在 PHP5.x 中致命错误抛出的异常未捕获,在 PHP7 中也是致命错误。

注意:其他级别的错误如 warningnotice,和之前一样不会抛出异常,只有 fatalrecoverable 级别的错误会抛出异常。

阅读全文 »

容器,字面上理解就是装东西的东西。常见的变量、对象属性等都可以算是容器。一个容器能够装什么,全部取决于你对该容器的定义。当然,有这样一种容器,它存放的不是文本、数值,而是对象、对象的描述(类、接口)或者是提供对象的回调,通过这种容器,我们得以实现许多高级的功能,其中最常提到的,就是 “解耦” 、“依赖注入(DI)”。本文就从这里开始。

Version

Laravel Framework version 5.1.41 (LTS)

IoC 容器, laravel 的核心

Laravel 的核心就是一个 IoC 容器,根据文档,称其为“服务容器”,顾名思义,该容器提供了整个框架中需要的一系列服务。作为初学者,很多人会在这一个概念上犯难,因此,我打算从一些基础的内容开始讲解,通过理解面向对象开发中依赖的产生和解决方法,来逐渐揭开“依赖注入”的面纱,逐渐理解这一神奇的设计理念。

本文一大半内容都是通过举例来让读者去理解什么是 IoC(控制反转)DI(依赖注入),通过理解这些概念,来更加深入。更多关于 laravel 服务容器的用法建议阅读文档即可。

IoC 容器诞生的故事

讲解 IoC 容器有很多的文章,我之前也写过。但现在我打算利用当下的灵感重新来过,那么开始吧。

阅读全文 »

将 markdown 转化为 html 的转化器叫做 markdown 渲染器。

在 Hexo 中默认的 markdown 渲染器是 hexo-renderer-marked ,这个渲染器是不支持 emoji 表情的。

在 NexT 的 issue 上有推荐使用 hexo-tag-emojis 这个插件来支持 emoji 表情,但可惜的是这个插件已经不再维护,已经不支持 Hexo v3+ 了。还好在 Hexo 的 plugins 页,我们找到了另外一个 emoji 插件 hexo-filter-github-emojis

下面我们就来实现 Hexo NexT 对 emoji 的支持。

Version

Hexo 3.3.9
NexT 5.1.2

安装

1
$ npm install hexo-filter-github-emojis --save

配置

打开 站点配置文件,添加以下内容:

1
2
3
4
5
6
githubEmojis:
enable: true
className: github-emoji
unicode: false
styles:
localEmojis:

具体的每个配置项含义可以看插件的文档

阅读全文 »

我们在计算金额时,难免存在保留位数有限,计算结果需要取舍的情况。往往在电商、银行系统中,金额是以整数形式保存,单位为货币最小单位,例如分。但是在结算时额外的参数如折扣、利率、税率等存在着大量的浮点数,计算结果则需要转换为整数。

简单处理一般是四舍五入,但是这样存在很明显的问题,就是 “入” 的概率大于 “舍”,明显的,遇到 1、2、3、4 舍,遇到 5、6、7、8、9 入,粗看这种就可以发现问题。如果想要两边平衡,则 “四舍六入” 才是合理的,但是,5 怎么办?

有趣的推理

转自知乎用户给出的一个例子(知乎答案地址

某实数 r = 0.4445。也就是说,比九分之四稍微大一点点。(构造其他小数也可以,有限小数还是无限小数、纯小数还是带小数都没关系)

好了,根据四舍五入算法 f,直接把这个 r 保留到整数。那么,明显,结果是 0,小数点后第一位是 4 么。

这时,请开放一下脑洞。有一群科学家拿到了这个数字。然后……

科学家 s3 把 r 保留到小数点后第 3 位,得 r3 = 0.445。第 4 位是 5 么,按四舍五入的精神,把这个 1 进到第 3 位,使之变成 5。

阅读全文 »

Version

Hexo 3.3.8

传统建立文章方式

一般我们都会使用 hexo new <title> 来建立文章,这种建立方法会将新文章建立在 source/_posts 目录下,当使用 hexo generate 编译 markdown 文件时,会将其 HTML 结果编译在 public 目录下,之后 hexo deploy 将会把 public 目录下所有文章部署到 GitHub,这是我们熟悉的 Hexo 流程。

这种建立文章方式的缺点是:若我们同时编辑多篇文章,只要其中一篇文章尚未编辑完成,也会随着 hexo deploy 一起部署到 GitHub,也就是 GitHub 可能会看到我们尚未完成的文章。

建立文章草稿

1
$ hexo new draft <title>

Hexo 另外提供 draft 机制,它的原理是新文章将建立在 source/_drafts 目录下,因此 hexo generate 并不会将其编译到 public 目录下,所以 hexo deploy 也不会将其部署到 GitHub。

阅读全文 »

单一入口

单一入口的概念其实很好理解,我们可以把整个应用想象为一个黑色的盒子,整个盒子只有一个入口,这个入口由一个文件把守,它要求所有的请求必须通过这个入口文件检验才能进入。

在聊单一入口的应用之前,我们先来看一看传统应用的多入口模式,这里我们参考一下 ECSHOP 的网站根目录的部分目录结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- article.php 文章内容
- article_cat.php 文章分类
- auction.php 拍卖前台文件
- brand.php 品牌列表
- captcha.php 生成验证码
- catalog.php 列出所以分类及品牌
- category.php 商品分类
- comment.php 提交用户评论
- compare.php 商品比较程序
- cycle_image.php 轮播图片程序
- feed.php RSS Feed 生成程序
- flow.php 购物流程
- gallery.php 商品相册
- goods.php 商品详情
- goods_script.php 生成商品列表
- group_buy.php 团购商品前台文件
- index.php 首页文件
- myship.php 支付配送DEMO
- pick_out.php 选购中心
- receive.php 处理收回确认的页面
- index.php 首页文件

你可以看到上述目录就是网站的根目录,这个目录下存放着相应页面的响应代码,如果我们想要访问首页,我们就在网址中访问 index.php,如果我们想要访问商品页,那么我们就需要访问 goods.php 文件,这就是传统应用的多入口模式,我们可以通过不同的文件入口来得到应用响应。

阅读全文 »

快捷键

控制光标位置

  • ctrl + m 将光标定位到文件中心
  • alt + j 多列模式进行选中,只会选择相同的单词
  • alt + shift + j 取消多列模式
  • home, end 移动到行首或行末
  • ctrl + shift + m 匹配括号的位置,会将光标移动到对应正括号和反括号位置
  • ctrl + [ 或 ] 具有相似功能
  • ctrl + shift + [ 或 ] 可已选中对应的括号区域
  • ctrl + pageup 将光标移动到页面顶头
  • ctrl + pagedown 将光标移动到页面底部
  • ctrl + g 输入:行号:列号快速定位文件位置

编辑文档

删除

  • ctrl + y 删除一行
  • ctrl + delete 删除光标后内容
  • ctrl + backspace 删除光标前一个字的内容
  • ctrl + enter 在行首会在该行前创建新行,行末会在改行后创建新行

复制

  • ctrl + d 复制选中块,若没有则只是复制当前行
  • ctrl + shift + v 粘贴文档时可以选择行数,多选时按住 shift,也可以显示剪切板历史
阅读全文 »

在 CentOS7.x 之前的版本都是通过修改 /etc/inittab 文件来设置启动顺序,具体可参考这里
但是此种方法并不适应于 CentOS7.x 版本,在该版本中,我们查看 /etc/inittab 文件可得

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[centos@localhost ~]$ vim /etc/inittab
# inittab is no longer used when using systemd.
#
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
#
# systemd uses 'targets' instead of runlevels. By default, there are two main targets:
#
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
#
# To view current default target, run:
# systemctl get-default
#
# To set a default target, run:
# systemctl set-default TARGET.target

该文件中已经详细说明了,不再使用 inittab 文件而是使用 systemd 代替,并且还指出,现在只有 multi-user 相当于运行级别是 3,graphical 相当于运行级别是 5,
现在可以使用如下命令设置默认启动级别了,注意要以 root 用户,或者是使用 sudo 权限。

如果用户没有 sudo 权限,参考这里进行设置。

1
2
3
[centos@localhost ~]$ sudo systemctl set-default multi-user.target
rm '/etc/systemd/system/default.target'
ln -s '/usr/lib/systemd/system/multi-user.target' '/etc/systemd/system/default.target'

设置成功之后 reboot 一下,即可顺利进入命令行界面了。
如果想要再次进入图形界面,在命令行中运行

1
[centos@localhost ~]$ sudo systemctl set-default graphical.target

当 PHP 引擎试图实例化未知类的操作时,就会调用 __autoload() ,并将类名当做字符串传递给它。但 __autoload() 有个缺点,就是 一个进程中只能定义一次。它是全局唯一的,如果框架占了这个名字,便会导致框架的用户用不了其它的 __autoload() 了,包括用户自定义的和其它类库带的。这时候就可以使用 spl_autoload_register() 函数。它可以把函数注册到 __autoload 队列中。

Version

Composer version 1.5.1

原理

以 Laravel 项目为例,composer.json 文件:

1
2
3
4
5
6
7
8
{
"autoload": {
"classmap" : [
"app/controllers",
"app/models"
]
}
}
阅读全文 »
0%