Wake Me Up When September Ends.

A wanderer capable of grasping the beauty of the grass, with a heart full of ancient charm, and a fondness for playful wit. Those who understand my words are knowledgeable individuals; those who decipher my code truly comprehend the essence. I am a wandering code swordsman, carrying my skills and riding freely through the digital world.

最近在项目中遇到依赖http扩展,出现一些问题,这边小计这些问题解决办法!我的环境是基于docker所以如下命令均在docker容器里面执行!

有关错误集锦

以下我遇到错误解决办法

  1. checking whether libcurl version >= 7.18.2… configure: error: no

这个类似这样错误需要确认libcurl,curl-dev是否正确安装,基于不同发行版docker可能包名不一致,需要根据实际情况区别!以下是基于alpine docker 安装命令

apk  add libcurl curl-dev

libcurl curl-dev 是linux下curl开发一系列依赖库和文件。http扩展需要curl,所以需要安装相关依赖!

  1. please install and enable pecl/raphf

这个问题需要确认pecl/raphf扩展是否安装,如果没有需要执行:

pecl install pecl/raphf

# 安装完毕之后启用它

docker-php-ext-enable raphf

raphf 用于提供高级的哈希函数和消息认证码(MAC),提供一些加密算法,用来保护数据安全性!

安装验证

pecl install pecl_http 

看看是否还会报错?

策略模式是一种行为设计模式, 它能让你定义一组算法和策略, 并将每种算法分别放入独立的类中, 根据不同场景使用不同算法和策略。

需求的场景

假设以需要一个服务或模块来实现消息通知功能,一开始只需要邮件通知,你实现发送邮件通知功能😀。。。。

然后几天后需求方提出能不能增加短信通知,你加班加点实现短信通知功能 😵。。。

一段时间之后需求方还想提供站内信通知功能 🫤 。。。

不久之后需求方问你能不能提供类似webstock即时消息通知 😂 。。。

如果一开始代码都写在一起,每种消息通知方式不同整体数据结构也大相径庭,那么后期维护可想而知 💔 。。。

如何解决

将每种通知方式设为一种通知策略,因此在整体模块或服务设计时候,应该做好如下几点:

  1. 定义好策略统一入口
  2. 定义好策略调度规则
  3. 约定好策略算法接口

实现

这边使用PHP语言实现,其他具有oop编程语言逻辑类似

  1. 👆定义策略算法接口
interface StrategyInterface
{
    public function handle(ContextInterface $content): mixed;
}

接口StrategyInterface handle 依赖Context上下文对象。Context在这个需求中可以封装为需要发送消息对象实现依赖。如短信,邮件:

class Sms implements StrategyInterface
{
    public function handle(ContextInterface $content):mixed
    {
        // code 
    }
}

class Email implements StrategyInterface
{
    public function handle(ContextInterface $content):mixed
    {
        // code 
    }
}
  1. 👉定义好策略调度规则&统一入口
class DispatchStrategy
{

    public function __contract(public StrategyInterface $strategy, public ContextInterface $content )

    public  function dispatch()
    {
        $this->strategy->handle($this->content);
    }
}
  1. 🫰运行调用
  //Context 根据不同策略实现不同的消息上下文依赖
(new DispatchStrategy(new Email(), new Context()))->dispatch(); //邮件

(new DispatchStrategy(new Sms(), new Context()))->dispatch(); //短信

规则Rule

PHPDoc

  1. 变量以及属性的辅助注解.方便IDE跳转和追踪
 <?php
/** @var int $foo */
 $foo = 2 + 2;


 final class Foo
 {
     /**
      * @var int
      */
     public $bar;

     /**
      * @type float
      */
     public $baz;
 }
  1. 变量以及属性多态类型优先级
# 修正前: 

/**
 * @param null|string|int|\Foo $bar
 */
# 修正后:
/**
 * @param \Foo|int|null|string $bar
 */
  1. 注释对齐(居中非依左或不对齐)
/**
 
# 修改前
 * @param  EngineInterface $templating
 * @param string      $format
 * @param  int  $code       an HTTP response status code
 * @param    bool         $debug
 * @param  mixed    &$reference     a parameter passed by reference

 
# 修改后
 * @param EngineInterface $templating
 * @param string          $format
 * @param int             $code       an HTTP response status code
 * @param bool            $debug
 * @param mixed           &$reference a parameter passed by reference
  1. 未确定类型使用mixed声明,默认值带为null需要用?修饰符
/**
  * @param string|null   $foo 
  * @param int           $bar
  * @param mixed         $baz
  *
  * @return void
  */
 function foo(?string = null $foo, int $bar, $baz) {}
  1. 数组key以及类属性对齐
# 修改前
class Foo
{
    public  $a = 0;

    public $b = 0;
    public $c = 0;

        public$d = 0;
}
# 修改后
class Foo
{
    public $a = 0;

    public $b = 0;

    public $c = 0;

    public $d = 0;
}
# 修改前
$arr = [
    'a'=>'tom',
    'c' =>  'sevne',
    'd'=>  'mazda',
    'b'  =>'cross m78 unm',
]
# 修改后
$arr = [
    'a' => 'tom',
    'c' => 'sevne',
    'd' => 'mazda',
    'b' => 'cross m78 unm',
]

代码约束

  1. declare_strict 严格声明。主要解决程序在处理类型时候避免隐性转换
declare(strict_types=1);
//code ....
  1. 使用常量PHP_EOL替代 "\n" 换行符号

echo  "some thing \n";
echo  "some thing PHP_EOL";
  1. 声明函数必须使用function_exists包裹判断,避免函数重复声明
if (!function_exists('dd')) {
    /**
     * dd 调试
     *
     * @param ...$vars
     *
     * @return void
     */
    function dd(...$vars)
    {
        foreach ($vars as $v) {
            VarDumper::dump($v);
        }
        exit(1);
    }
}
  1. 函数或类的方法没有返回类型需要声明void类型
function foo(string $a): void {}


class Foo
{
    public function handle(): void;
    {
        //code ...
    }
}
  1. 命名空间导入,导入或完全限定全局类/函数/常量
<?php

# 修改前
$d = new \DateTimeImmutable();
# 修改后
$d = new DateTimeImmutable();
  1. 使用::class替换完整类名使用,以及替代get_class函数
# 修改前
$className = 'Foo\Bar\Baz';
# 修改后
$className = Baz::class;
  1. 多次调用转换成单次调用
# 修改前
$a = isset($a) && isset($b);
# 修改后
$a = isset($a, $b)  ;

# 修改前
unset($a);
unset($b);
# 修改后
unset($a, $b);
  1. 使用语法糖简化调用
# 修改前
$boo = isset($foo) ? $foo : null;
# 修改后
$boo = $foo ?? null; 
//或
$foo ??= null;

# 修改前
$boo = $foo ? $foo : '';
# 修改后
$boo = $foo ?:'';


# 修改前
list($a, $b) = $foos;
# 修改后
[$a, $b] = $foos;
  1. 变量占位符由${ 转换{$) php的高版本已经抛弃${用法
$name = 'World';
# 修改前
echo "Hello ${name}!";
# 修改后
echo "Hello {$name}!";
  1. PHP常量true、false和null须使用小写
# 修改前
$a = FALSE;
$b = True;
$c = NULL;
# 修改后
$a = false;
$b = true;
$c = null;
  1. 使用动态属性或方法,属性需要实现__get__set,方法需要_call()__callStatic以及在class 头部声明,便于ide识别以及查阅
/**
 * Class Foo
 * 
 * @property string $attr  
 * @method Foo handleA(string $arg) 
 */
class Foo
{
    public function __set($name, $value)
    {
        //code 
    }

    
    public function __get($name)
    {
        //code 
    }


    public function __call($method, $args)
    {
        //code 
    }

    public static function __callStatic($method, $args)
    {
        //code 
    }
}

耦合优化

  1. 使用依赖对象处理多参数方法或函数,避免后面迭代出现超级函数
# 修改前
function  foo(string $argv, int $argc, array $arg, \Closure $argz) :void
{
    //code 
}
# 修改后

Class Boo
{
    public string $argv;

    public string $argc;

    public string $argg;

    public function argz() : Closure
    {
        return  function (){ };
    }
}

function  foo(Boo $boo) :void
{
    //code 
}

解决

在日常使用mysqldump进行数据备份时,会出现如下的问题:

mysqldump -h ***  -u root -p --skip-lock-tables mig_test > /var/log/mysql/bak.sql
Enter password:
#输入密码之后报如下错误:
mysqldump: Couldn't execute 'SELECT COLUMN_NAME, 
    JSON_EXTRACT(HISTOGRAM, '$."number-of-buckets-specified"')  
    FROM information_schema.COLUMN_STATISTICS                
    WHERE SCHEMA_NAME = 'mig_test' AND TABLE_NAME = 'migrations';':

Unknown table 'COLUMN_STATISTICS' in information_schema (1109)

经查阅相关资料得知,需要添加--column-statistics=0即可。我猜测的原因可能是备份数据时候在读取相关表结构没有相关权限,所以报此错误。通过添加--column-statistics=0进行关闭,以免报错。

column-statistics解释

--column-statistics 是一个用于输出列统计信息的选项。这个选项可以让 mysqldump 在备份数据时,输出每个表的列名、数据类型、长度、默认值、是否为 null 等信息,同时还输出了每个列的统计信息,包括平均长度、总长度、字符集、数字类型的比例等信息。

列统计信息对于优化备份文件的大小和速度非常有用。例如,如果你知道某个列中大多数数据都是 NULL,那么你可以减少备份该列的数据,从而减少备份文件的大小。另外,如果你知道某个列的数据类型和长度,你可以更好地规划备份文件的大小和格式,以最大化备份效率。