0%

前言

最近很久没有更新 Blog 了,上班之后确实回家已经是瘫软状态,没办法搬砖要负责任,有奇葩需求要让奇葩需求不奇葩。

作为一个现代的 PHP 程序员很少有不接触 Laravel 的吧,接触了 Laravel 或多或少要接触 Collection 类,接触了 Collection 类肯定会接触到 Closure。

Collection 类是一个很好的工具类,用起来各种优雅,这里我们先卖个关子后面再源码解析 Collection 类。今天我们讲的是 Closure 闭包类的使用。

Closure 闭包类

Closure 类是用于代表匿名函数的类,匿名函数会产生这个类型的对象,Closure 类摘要如下:

1
2
3
4
5
6
7
8
9
Closure {
/* 方法 */
__construct ( void )
public static Closure bind(
Closure $closure ,
object $newthis [, mixed $newscope = 'static']
): Closure
public Closure bindTo(object $newthis [, mixed $newscope = 'static'] ): Closure
}

方法说明:

  • Closure::__construct 用于禁止实例化的构造函数

  • Closure::bind 复制一个闭包,绑定指定的 $this 对象和类作用域

  • Closure::bindTo 复制当前闭包对象,绑定指定的 $this 对象和类作用域

Closure::bindClosure::bindTo 的静态版本,其说明如下:

1
2
3
4
public static Closure bind(
Closure $closure ,
object $newthis [, mixed $newscope = 'static']
): Closure

参数说明:

  • $closure 表示需要绑定的闭包对象
  • $newthis 表示需要绑定到闭包对象的对象,或者 NULL 创建未绑定的闭包
  • $newscope 表示想要绑定给闭包的类作用域,可以传入类名或类的实例,默认值是’static’,表示不改变。
1
public Closure bindTo(object $newthis [, mixed $newscope = 'static'] ): Closure

参数说明:

  • $newthis 表示需要绑定到闭包对象的对象,或者 NULL 创建未绑定的闭包
  • $newscope 表示想要绑定给闭包的类作用域,可以传入类名或类的实例,默认值是’static’,表示不改变。
阅读全文 »

前言

都 2020 年了,PHP 版本都出到了 7.4.6。可是服务器上的 PHP 还是 7.1。对于我这个喜欢最新版本的人来说简直是不能忍受。怎么办?干!

安装 PHP 相关

公司环境有专门的运维,编译安装无可厚非。我们自己就没有必要折腾自己,又没啥特殊的服务要求,整那么多幺蛾子也没必要。直接添加源搞起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ondrej/php
# 安装
sudo apt-get install php7.4 php7.4-fpm php7.4-mysql php7.4-gd php7.4-mbstring php7.4-bcmath php7.4-sqlite3 php7.4-cli php7.4-soap
# 启动
sudo service php7.4-fpm start
# 重启
sudo service php7.4-fpm restart
# 停止
sudo service php7.4-fpm stop

# 进行默认的版本选择
update-alternatives --config php

基本这样就完事儿了。剩下就是调整 nginxu 对应的 fastcgi_pass 参数,让 PHP 处理对应的请求就好了。

总结

别和我说什么不是编译安装不高级,特么的技术为的是解决问题,我的需求是快速搭建,没有什么特殊的管理需要,点到为止。而且现在服务器多数都是用 Docker 了。这种直接安装的无非就是一些老项目要迁移版本升级而已。简单实用快速就是王道。

前言

娘希匹的~ 懒得装环境直接 Docker 了一个 MySQL 最新版,版本是 8 来着。结果我用 Navicat 连接成功,满心欢喜的以为 OJBK 了。结果换 Laravel 去 migrate 时结果肯定时不行吖。

为什么不行?

标题有点开车的感觉,真实的刺激哈哈哈。因为 MySQL8 的密码加密方式换成了 caching_sha2_password 而我们的 PDO 貌似还不支持这种方式。所以只能是使用下面的命令进行降级了。将 caching_sha2_password 降级成为 mysql_native_password

1
2
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '{此处替换新的密码}';
FLUSH PRIVILEGES;

为什么是 PDO 问题呢?我在使用 Golang 的数据库时候并不会出现这个问题,而 PHP PDO 连接的时候就哎。

总结

谁让你 PHP 是世界上最好的语言呢?这么多新语言,我还是爱你的 PHP。

前言

最近看Hyperf有个Docker安装环境,直接运行了。按照官方的教材运行起来是没有问题,可是光一个服务端没啥用啊,PHP 没有搭配 MySQL 就太没有灵魂了。既然是开发环境,我要怎么才能让已经运行的Hyperf容器连接到新建的MySQL容器呢?

运行 Docker Hyperf

Hyperf 是基于 swoole 的,但是 swoole 在 window 上运行不了,只能借助 Docker 了。

1
docker run --name myhyperf -v $pwd/skeleten:/hyperf-skeleton -p 9501:9501 -dit --entrypoint /bin/sh hyperf/hyperf:7.4-alpine-v3.9-cli-v4.5.2
2
3
# 镜像容器运行后,在容器内安装 Composer
4
wget https://github.com/composer/composer/releases/download/1.10.6/composer.phar
5
chmod u+x composer.phar
6
mv composer.phar /usr/local/bin/composer
7
# 将 Composer 镜像设置为阿里云镜像,加速国内下载速度
8
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer
9
10
# 通过 Composer 安装 hyperf/hyperf-skeleton 项目
11
composer create-project hyperf/hyperf-skeleton
12
13
# 进入安装好的 Hyperf 项目目录
14
cd hyperf-skeleton
15
# 启动 Hyperf
16
php bin/hyperf.php start

浏览器访问:http://127.0.0.1:9501 OJBK ~

到这里我们要解决的问题才正真开始,我们需要有MySQL去配合Hyperf。我们需要怎么做呢?

开始解决这个问题

创建网络:

1
docker network create hyperfdb_network

创建使用这个网络创建MySQL:

1
docker run --name mydb --net=hyperfdb_network -p 3306:3306 -it -v $pwd/data/mysql:/var/lib/mysql:rw -v $pwd/data/mysql:/var/lib/mysql-logs:rw -v $pwd/config/mysql/conf.d:/etc/mysql/conf.d:ro -e MYSQL_ROOT_PASSWORD=123456 --restart=always -d mysql:8.0.20

将已存在的容器连接到mydb相同的网络

1
# hyperfdb_network 是刚才创建的网络名称
2
# myhyperf 是hyperf容器的名称
3
docker network connect hyperfdb_network myhyperf

我们进入我们 myhyperf 容器:

1
docker exec -it myhyperf sh
2
3
ping mydb

我们发现已经通了。

测试

我们虽然是ping通了网络,但是MySQL使用不知道是否准确。

1
<?php
2
$dsn = "mysql:dbname=test;host=mydb";
3
$db_user = 'root';
4
$db_pass = '123456';
5
try {
6
    $pdo = new PDO($dsn, $db_user, $db_pass);
7
    echo '连接成功' . PHP_EOL;
8
} catch (PDOException $e) {
9
    echo '数据库连接失败' . $e->getMessage();
10
}

总结

Docker做开发环境还是挺舒服的。快速搭建就开始学习写代码了。

前言

最近决定研究下 Golang,借助王垠大神的说法就是学习一门语言优先从他的特性入手,我们的 Golang 的特性就是 goroutine。这个 goroutine 是一个什么东西呢?就像是漩涡鸣人的影分身。

Goroutine 最简单的例子

我们要在 Golang 中使用协程最简单的方法就是在对应函数前面使用 go 关键字。

1
package main
2
3
import (
4
    "fmt"
5
)
6
7
func hello() {
8
    fmt.Println("Hello Goroutine")
9
}
10
11
func main() {
12
    go hello()
13
}
阅读全文 »

前言

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。是前面简单工厂模式和工厂方法模式的升级,该超级工厂又成为其他工厂的工厂。这种类型的设计模式属于创建型类型,它提供一种创建对象的最佳方式。

为什么说是工厂的工厂,在工厂方法模式中具体的工厂负责生产具体的产品,每个具体工厂对应一种具体的类。

阅读全文 »

前言

简单工厂模式(静态方法工厂)存在着一系列问题:

  • 工厂类集中了所有的实例(产品)的创建逻辑,一旦这个类进行修改不能正常工作,整个系统都会受到影响
  • 违背“开放-关闭原则”,一旦添加新产品就不得不去修改工厂类的逻辑,这样就会造成工厂逻辑臃肿切过于复杂
  • 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的登记结构

我们为了解决上面的问题,我们需要使用一个新的设计模式:工厂方法模式

阅读全文 »

前言

简单工厂模式(静态工厂模式),最为一个出镜率比较高的设计模式,相对来说比较简单,大家可以很快上手,我觉得还是举例子给大家会比较好理解也记忆。

我们首先看看它的优缺点:

  • 优点是比较好理解,简单易操作
  • 缺点是违反了设计模式的 OCP 原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码或者尽量少修改代码

理想小镇的聪明面包达人

我们想象一下,一个理想小镇上有个面包达人,他教会了好几个徒弟,徒弟们也准守传承按照指定的配方去做面包,每当想到一个新的做法面包达人都要挨个徒弟的教会他们。

阅读全文 »

前言

懒汉模式虽然起到了延迟加载的,但是总的来说这个东西还不是很靠谱,我们只能继续探寻下去。今天我们来看看剩下的三种:双重检查、静态内部类、枚举方式。

单例模式(双重检查)

双重检查,主要是使用 volatile 关键字,声明我们的类中的静态属性

1
package com.yubulang.type06;
2
3
public class Singleton {
4
    private Singleton() {
5
    }
6
7
    private static volatile Singleton instance;
8
9
    // 提供一个静态的公有方法,加入双重检查代码,解决线程安全问题,同时解决懒加载问题
10
    // 同时保证了效率,推荐使用
11
    public static Singleton getInstance() {
12
        if (instance == null) {
13
            synchronized (Singleton.class) {
14
                if (instance == null) {
15
                    instance = new Singleton();
16
                }
17
            }
18
        }
19
20
        return instance;
21
    }
22
}
阅读全文 »

前言

前面我们介绍了单例模式的饿汉模式,其实饿汉式很好理解,形象的记忆就是不管怎么样,先把内存吃掉再说。本着贪多嚼不烂的原则,我们今天来看看懒汉式,这个懒汉式就有三种不同的形式。当然还是理解为主。

懒汉式(线程不安全)

在同一个线程中运行,这个方法没有问题。我们先看代码,后面再来看看这个懒汉式的优缺点。

1
package com.yubulang.type03;
2
3
public class Singleton {
4
    private Singleton() {
5
    }
6
7
    private static Singleton instance;
8
9
    // 提供一个静态的公有方法,当使用到该方法时,才去创建instance
10
    // 懒汉式1 这个因为懒,懒得线程都不安全了
11
    public static Singleton getInstance() {
12
        if (instance == null) {
13
            instance = new Singleton();
14
        }
15
16
        return instance;
17
    }
18
}
阅读全文 »