PHP Kafka 消息队列使用

  1. 安装 Kafka 服务(需要先安装java环境)

直接到 kafka 官网, 下载最新的

wget https://downloads.apache.org/kafka/3.1.0/kafka_2.13-3.1.0.tgz

解压,进入目录

tar -zxvf kafka_2.13-3.1.0.tgz
cd kafka_2.13-3.1.0

a. 启动 Kafka 服务
使用安装包中的脚本启动单节点 Zookeeper 实例

bin/zookeeper-server-start.sh -daemon config/zookeeper.properties

使用 kafka-server-start.sh 启动 kafka 服务

bin/kafka-server-start.sh config/server.properties

创建 topic

bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test

查看 topic 列表,检查是否创建成功

bin/kafka-topics.sh --list --zookeeper localhost:2181
$ test

生产者,发送消息

bin/kafka-console-producer.sh --broker-list 127.0.0.1:9092 --topic test

  1. 安装 PHP 扩展

git clone https://github.com/edenhill/librdkafka.git
cd librdkafka
./configure
make && make install

直接使用yum安装(推荐)

yum install librdkafka-devel

安装 php-rdkafka 扩展

下载地址:http://pecl.php.net/package/rdkafka
wget rdkafka-6.0.1.tgz
cd rdkafka-6.0.1.tgz
/www/server/php/72/bin/phpize ## 这里根据自己的情况填写路径
./configure --with-php-config=/www/server/php/72/bin/php-config ## 这里根据自己的情况填写路径
make && make install
在 php-ini 加上

extension=rdkafka.so
重启,php-fpm,就应该可以看到该扩展。

C语言实现简单php自定义扩展

很久之前因为PHP算法和C语言算出的结果不一样,当时写了两个扩展忘记怎么弄的了。
先记录一下找一下资料后续补充完整
使用C语言编写方法
在编译成.so文件

// 最后需要设置PHP.ini扩展位置
extension=/../crc16_data.so
extension=/../helloworld.so

php实现水仙花数

水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。(例如:1^3 + 3^3+ 5^3 = 153)这篇文章主要介绍了php实现水仙花数的4个示例分享,需要的朋友可以参考下:

示例1:

for($q=1; $q<=9; $q++){
    for($w=0; $w<=9; $w++){
        for($e=0; $e<=9; $e++){
            if($q* $q *$q + $w* $w* $w + $e* $e* $e == 100* $q + 10* $w + $e){
                echo "$q $w $e "."<p>";
            }
        }
    }
}

示例2:

function cube($n)
{
    return $n * $n * $n;
}

function is_narcissistic ( $n )
{
    $hundreds = floor( $n / 100);    //分解出百位
    $tens = floor( $n / 10 ) % 10;    //分解出十位
    $ones = floor( $n % 10 );    //分解出个位
    return (bool)(cube($hundreds)+cube($tens)+cube($ones) == $n);
}


for ($i = 100; $i < 1000; ++ $i )
{
    if ( is_narcissistic($i) )
        echo $i."\n";
}



PHP实现八大算法

计算数组乘积,array_product()

  1. 直接插入排序(Straight Insertion Sort)
  2. 希尔排序(Shells Sort)
  3. 直接选择排序(Straight Selection Sort)
  4. 堆排序(Heap Sort)
  5. 冒泡排序(Bubble Sort)
  6. 快速排序(Quick Sort)
  7. 归并排序(Merge Sort)
  8. 桶排序(Bucket Sort)/基数排序(Radix Sort)
  9. 各种排序算法性能比较

排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。我们这里说的八大排序算法均为内部排序。
1.直接插入算法

// 第一种
function insert_sort($arr){
    for ($i = 0; $i < count($arr)-1; $i++){
        for($j = $i+1; $j > 0; $j--){
            if($arr[$j] > $arr[$j-1]){
                $temp = $arr[$j];
                $arr[$j] = $arr[$j-1];
                $arr[$j-1] = $temp;
            }
        }
    }
    return $arr;
}

$insert_sort = insert_sort([19, 22, 20, 12, 13, 15, 25, 26]);
var_dump($insert_sort);

// 第二种
function insert_sort($arr){
    for ($i = 0; $i < count($arr)-1; $i++){
        $j = $i + 1;
        while($j > 0){
            if($arr[$j] > $arr[$j-1]){
                $temp = $arr[$j];
                $arr[$j] = $arr[$j-1];
                $arr[$j-1] = $temp;
            }
            $j--;
        }
    }
    return $arr;
}

// 第三种
function insertSort($arr)
{
    $len=count($arr);
    for($i=1; $i<$len; $i++) {
        // 获得当前需要比较的元素值。
        $tmp = $arr[$i];
        // 内层循环控制 比较 并 插入
        for($j=$i-1; $j>=0; $j--) {
            // $arr[$i]; 需要插入的元素; $arr[$j]; 需要比较的元素
            if($tmp < $arr[$j]) {
                // 发现插入的元素要小,交换位置
                // 将后边的元素与前面的元素互换
                $arr[$j+1] = $arr[$j];
                // 将前面的数设置为 当前需要交换的数
                $arr[$j] = $tmp;
            } else {
                // 如果碰到不需要移动的元素
                // 由于是已经排序好是数组,则前面的就不需要再次比较了。
                break;
            }
        }
    }
    // 将这个元素 插入到已经排序好的序列内。
    return $arr;
}

2.希尔排序
3.直接选择排序

function selectSort($arr)
{
    $len=count($arr);
    for ($i = 0; $i < $len-1; $i++){
        // 先假设最小的值的位置
        $p = $i;
        for ($j = $i+1; $j < $len; $j++){
            // $arr[$p]是当前已知的最小值
            if ($arr[$p] > $arr[$j]){
                // 发现更小的记录一下次使用
                $p = $j;
            }
        }
        if ($p != $i){
            $tmp = $arr[$p];
            $arr[$p] = $arr[$i];
            $arr[$i] = $tmp;
        }
    }
    return $arr;
}

4.堆排序
5.冒泡排序法的基本思想是:对待排序记录关键字从后往前(逆序)进行多遍扫描,当发现相邻两个关键字的次序与排序要求的规则不符时,就将这两个记录进行交换。这样,关键字较小的记录将逐渐从后面向前面移动,就象气泡在水中向上浮一样,所以该算法也称为气泡排序法。

// 冒泡排序
function bubbleSort($arr)
{
    $len = count($arr);
    // 该层循环控制 需要冒泡的轮数
    for ($i=1; $i<$len; $i++) {
        // 该层循环用来控制每轮 冒出一个数 需要比较的次数
        for ($j=0; $j<$len-$i; $j++) {
            if($arr[$j] > $arr[$j+1]) {
                $tmp = $arr[$j+1]; // 声明一个临时变量
                $arr[$j+1] = $arr[$j];
                $arr[$j] = $tmp;
            }
        }
    }
    return $arr;
}

6.快速排序算法

function quickSort($arr)
{
    if (!is_array($arr)) return false;
    $len = count($arr);
    if ($len <= 1) return $arr;
    $a = $b = array();
    for ($i = 1; $i < $len; $i++){
        if ($arr[$i] < $arr[0]){
            $a[] = $arr[$i];
        }else{
            $b[] = $arr[$i];
        }
    }
    $a = quickSort($a);
    $b = quickSort($b);
    return array_merge($a, array($arr[0]), $b);
}

7.归并排序算法【注意:数组按值传输】

function merge_sort(&$A, $p, $r)
{
    if($p < $r){
        $q = floor(($p + $r)/2);
        merge_sort($A, $p, $q);
        merge_sort($A, $q+1, $r);
        merge($A, $p, $q, $r);
    }
}
function merge(&$A, $p, $q, $r)
{
    // 哨兵牌法
    $n1 = $q - $p + 1;
    $n2 = $r - $q;
    for($i = 0; $i < $n1; $i++){
        $L[$i] = $A[$p+$i];
    }
    for($j = 0; $j < $n2; $j++){
        $R[$j] = $A[$q+$j+1];
    }
    // 防止越界(哨兵)
    $L[$n1] = $R[$n2] = PHP_INT_MAX;
    $i = $j = 0;
    for($k = $p; $k <= $r; $k++){
        if($L[$i] <= $R[$j]){
            $A[$k] = $L[$i];
            $i++;
        }else{
            $A[$k] = $R[$j];
            $j++;
        }
    }
}

8.基数排序算法

Laravel创建自定义artisan命令

主要是方便快速写入代码,比如后端增删改查CRUD
1.创建命令文件

#php artisan make:command 命令文件名
php artisan make:command Validator

创建命令文件创建命令文件

2.注册命令在/app/Console/Kernel.php中添加一下内容

protected $commands = [
    \App\Console\Commands\Validator::class
];

注册命令注册命令

3.编写命令步骤如下:
先在/app/Console/Commands/validator/下创建validator.stub和default_method.stub文件(目录名称建议命令一致,在自定义多个的情况下方便区分)

目录文件目录文件

validator.stub : 逻辑层的主要内容,包含命名空间和类

<?php

namespace {{namespace}};

# 看个人情况确定是否包含继承文件和导入文件
use Illuminate\Support\Facades\Validator;

class {{class_name}} extends Validator
{
    {{default_method}}
}

default_method.stub : 默认方法模板,根据--resource参数来确认是否写入logic.stub

public function index()
{

}

public function test()
{
    
}

相关Validator.php命令名称,参数和描述

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'make:validator {name} {--resource}';

/**
 * The console command description.
 *
 * @var string
 */
protected $description = 'create validator';

修改Validator.php命令文件中handle方法:列举如下

/**
 * Execute the console command.
 *
 * @return int
 */
public function handle()
{
    // 获取参数
    $args = $this->arguments();

    // 获取可选参数
    $option = $this->option('resource');

    // 处理组合参数
    $args_name = $args['name'];
    if (strstr($args['name'], '/')) {
        $ex = explode('/', $args['name']);
        $args_name = $ex[count($ex)-1];
        $namespace_ext = '/' . substr($args['name'], 0, strrpos($args['name'], '/'));
    }

    $namespace_ext = $namespace_ext ?? '';

    // 类名
    // $class_name = $args_name . 'Validator';
    $class_name = $args_name;

    //文件名
    $file_name = $class_name . '.php';

    // 文件地址
    $logic_file = app_path() . '/Validator' . $namespace_ext . '/' . $file_name;

    // 命名空间
    $namespace = 'App\Validator' . str_replace('/', '\\', $namespace_ext);

    // 目录
    $logic_path = dirname($logic_file);

    // 获取模板,替换变量
    $template = file_get_contents(dirname(__FILE__) . '/stubs/validator.stub');
    $default_method = $option ? file_get_contents(dirname(__FILE__) . '/stubs/default_method.stub') : '';
    $source = str_replace('{{namespace}}', $namespace, $template);
    $source = str_replace('{{class_name}}', $class_name, $source);
    $source = str_replace('{{default_method}}', $default_method, $source);

    // 是否已存在相同文件
    if (file_exists($logic_file)) {
        $this->error('文件已存在');
        exit;
    }

    // 创建
    if (file_exists($logic_path) === false) {
        if (mkdir($logic_path, 0777, true) === false) {
            $this->error('目录' . $logic_path . '没有写入权限');
            exit;
        }
    }

    // 写入
    if (!file_put_contents($logic_file, $source)) {
        $this->error('创建失败!');
        exit;
    }
    $this->info('创建成功!');
}

4.使用自定义命令:

#如果不需要默认方法,去掉--reource参数即可
#php artisan make:validator User --resource
php artisan make:validator User

效果如下效果如下