fastcgi_finish_request 一个另类的异步函数

最近看thinkphp5.1 源码的时候无意中发现了一个没有见过的函数fastcgi_finish_request 。

上网查了下,是一个基于fastcgi模式下的一个函数。是为了解决阻塞操作的函数。

例子:

<?php
echo '请求成功!';
fastcgi_finish_request(); //在这里就完成了,以下操作客户端不会运行
// 1. 初始化
for($i=0;$i<10;$i++){
        $ch = curl_init();
        // 2. 设置选项,包括URL
        curl_setopt($ch,CURLOPT_URL,"http://baidu.com");
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch,CURLOPT_HEADER,0);
        // 3. 执行并获取HTML文档内容
        $output = curl_exec($ch);
        if($output === FALSE ){
                echo "CURL Error:".curl_error($ch);
        }else{
                file_put_contents('log.txt','ok-'.$i, FILE_APPEND | LOCK_EX);
        }
        // 4. 释放curl句柄
        curl_close($ch);
}

运行下:

cat log.txt

php无限级分类引用模式

今天去面试,面试官问我,不用递归如何无限分类,然后面试官跟我说引用可以,接着我去网上搜了下。代码如下:

<?php
$array = array(
    array('id' => 1, 'pid' => 0, 'name' => '安徽省'),
    array('id' => 2, 'pid' => 0, 'name' => '浙江省'),
    array('id' => 3, 'pid' => 1, 'name' => '合肥市'),
    array('id' => 4, 'pid' => 3, 'name' => '长丰县'),
    array('id' => 5, 'pid' => 1, 'name' => '安庆市'),
    array('id' => 6, 'pid' => 4, 'name' => 'ddd'),
);

function generateTree($array)
{
    $items = array();
    foreach ($array as $value) {
        $items[$value['id']] = $value;
    }
    $tree = array();
    foreach ($items as $key => $value) {
        if (isset($items[$value['pid']])) {
            $items[$value['pid']]['childen'][] = &$items[$key];
        } else {
            $tree[] = &$items[$key];
        }
    }
    return $tree;

}

$tree = generateTree($array);
print_r($tree);

这段代码我已经测试过了,没问题的。

PHP反射类ReflectionClass 简单使用

详细接口请看:https://www.cnblogs.com/youyoui/p/7300340.html

例子:

这里有个需求,根据传过来的type,来判断是使用手机发送验证码还是邮箱发送验证码。

如果是以前的话,是这样做的:

首先新建一个email类:

<?php
class Email
{
  public function send(string $email)
  {
    var_dump("发送邮箱:".$email);
  }
}

phone类:

<?php
class Phone
{
  public function send(string $phone=null)
  {
    var_dump("发送电话:".$phone);
  }
}

index.php文件

<?php

function loadFun($className)
{
  require_once($className.'.php');
}

spl_autoload_register('loadFun');//自动加载函数

$type = "phone";

if($type=="phone")
{
  $phone = new Phone();
  $phone->send("11111");
}else{
  $email = new Email();
  $email->send("11111@qq.com");
}

这是旧的方法。

反射机制,把index改一下:

<?php

function loadFun($className)
{
  require_once($className.'.php');
}

spl_autoload_register('loadFun');

$type = "Phone";

$class = new ReflectionClass($type);
$name = $class->newInstance();
$name->send("13123");

只需要把type传递进来就可以实现了,不用再写这么多if语句去判断了。

php 神奇的trait

今天发现某些框架 直接use 一个类,就可以实现单例模式。我发现他们都是用了trait这个特性。

接着我自己写了一个 trait试了下

trait Single
{
    protected static $instance = null;

    private function __construct()
    {

    }

    public static function getInstance()
    {
        if(is_null(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }
}

接着我找了之前的单例发送手机类

class SmsCode
{
    use Single;

    public function send()
    {
        var_dump("发送手机号码哦!");
    }
}

直接就可以应用了。

SmsCode::getInstance()->send()

ubuntu和window交叉编译

安装:sudo apt-get install mingw-w64

新建一个c文件test.c

内容:

#include <stdio.h>

int main()
{
        printf("dd");
        return 0;
}

保存退出

运行:x86_64-w64-mingw32-gcc test.c -o test.exe

在window下运行test.exe

koa-router post请求数据验证类处理

最近自己写项目的时候发现每一次请求都要做判断,判断多了代码就很乱。

然后,我写php使用tp5框架的时候,它是可以继承一个验证类来实现验证的,我利用午休事件,大概写了一下。

我首先编写了一个验证类的工具类:

class VerifierUtils{
  //邮箱验证
  static email(str)
  {
    if (str.search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1)
    {
      return true;
    }else{
      return false;
    }
  }

  //手机验证
  static phone(str)
  {
    if (!(/^1[3456789]\d{9}$/.test(str)))
    {
      return false;
    }else{
      return true;
    }
  }

}
module.exports = VerifierUtils

接着编写 验证类

const utlis = require('./verifierUtils')
class Verifier {
  check(data) {
    for (let list in this.rules) {
      //验证是否为空
      if (!data[list] && this.rules[list]['require'] == true) {
        return `${list}不能为空!`
        break
      }

      //验证是否有邮箱
      if (data[list] && this.rules[list]['email'] == true) {
        if (!utlis.email(data[list])) {
          return `邮箱格式不正确!`
          break
        }
      }

      //验证最小长度
      if (data[list] && this.rules[list]['min']) {
        if (data[list].length < this.rules[list]['min']) {
          return `${list}不能小于${this.rules[list]['min']}位数!`
          break
        }
      }

      //验证最大长度
      if (data[list] && this.rules[list]['max']) {
        if (data[list].length > this.rules[list]['max']) {
          return `${list}不能大于${this.rules[list]['max']}位数!`
          break
        }
      }

      //验证是否相等
      if (data[list] && this.rules[list]['rePassword']) {
        if (data[this.rules[list]['rePassword']]) {

          if (data[this.rules[list]['rePassword']] != data[list]) {
            return `两次输入不一致!`
            break
          }

        } else {
          return `两次输入不一致!`
          break
        }
      }

    }
    return false
  }
}

module.exports = Verifier

接着我们就可以写类来继承它

比方说:注册类

const Verifier = require('./Verifier')
class Register extends Verifier{
  constructor()
  {
    super()
    this.rules={
      "username":{"require":true,"email":true},
      "password":{"require":true,"min":6,"max":16,"rePassword":"rePassword"},
      "code":{"require":true}
    }
  }
}
module.exports = Register

然后我们就可以在外面使用

router.post("/register",async (ctx,next)=>{
  let req = ctx.request.body
  
  let username = req.username
  let password = req.password
  let rePassword = req.rePassword
  let code = req.code

  let data = {
    username,
    password,
    rePassword,
    code
  }

  let check = (new Reg()).check(data)
  if(check)
  {
    ctx.body={
      code:-1,
      msg:check
    }
    return
  }

}

这样我们如果要验证post数据的话,就直接建一个类来继承Verifier 这个类,来编写规则了。