当前位置: 首页 > news >正文

PHP那些事儿

1、封禁策略为一个自然分钟内请求签到接口500次则封禁该IP10分钟,如何操作?

<?php
    //设置两个redis key来支撑此问题
    function getUserState($ip = ''){
        if (empty($ip)) {
            return true;
        }
        
        //获取封禁key
        $bannedKey = 'redis_cache_' . $ip;
        if ($redis->get($bannedKey)) {
            return true;
        }
        
        //获取次数key
        $ipNumKey = 'redis_cache_num_'. $ip
        $ipNum = $redis->incr($ipNumKey); 
        if ($ipNum >= 500) {
            $redis->setex($bannedKey,600);
            return false;
        }
        
        return true;
    }
?>

2、只提供10M内存,现在要做一个活动,参与活动的用户userId为1~10000000,请问如何设计?

可考虑用redis的setbit和getbit命令来实现此需求,对其userId进行占位,并且8各userId的占位才占有1B的空间,所有10M空间足足有余

3、下面代码的输出值为?

<?php
    $nums = [1,2,3];
    foreach ($nums as &$num) {
        //null
    }
    echo $nums[0].'-'.$num[1].'-'.$nums[2];//1-2-3
    
    foreach ($nums as $num) {
        //null
    }
    echo $nums[0].'-'.$num[1].'-'.$nums[2];//1-2-2
?>

如果不明白,则有直达地址:PHP引用那些事儿

4、实现一个base62_encode()和base62_decode()方法,要求base62_encode(1)=1,base62_encode(61)=z,base62_decode('z')=61;语言不限

<?php
//如果有经验的RD,一眼就知道62个字符是0-9A-Za-z,并且在微博推出的短链服务就知道,这是一道通向短链设计的一个必经之路,具体短链服务不懂怎么设计的自行google,这里不做过多解释
class Base62
{
    
    private $string = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    
    public function base62_encode($str)
    {
        $out = '';
        for ($t = floor(log10($str) / log10(62)); $t >= 0; $t--) {
            $a = floor($str / pow(62, $t));
            $out = $out . substr($this->string, $a, 1);
            $str = $str - ($a * pow(62, $t));
        }
        return $out;
    }
    
    public function base62_decode($str)
    {
        $out = 0;
        $len = strlen($str) - 1;
        for ($t = 0; $t <= $len; $t++) {
            $out = $out + strpos($this->string, substr($str, $t, 1)) * pow(62, $len - $t);
        }
        return substr(sprintf("%f", $out) , 0, -7);
    }
}

$object = new Base62();
echo $object->base62_encode(1) . "<br/>";
echo $object->base62_encode(61) . "<br/>";
echo $object->base62_decode('z') . "<br/>";
    
?>

5、PHP实现KMP算法

如果只知道PHP是拍簧片技术,而不懂看毛片算法,就low爆了,KMP算法讲解

<?php

function KMP($str)
{
    $K = [0];
    $M = 0;
    for ($i = 1; $i < strlen($str); $i++) {
        if ($str[$i] == $str[$M]) {
            $K[$i] = $K[$i - 1] + 1;
            $M++;
        } else {
            $M = 0;
            $K[$i] = $K[$M];
        }
    }
    return $K;
}
// KMP查找
function KMPMatch($src, $par, $debug = false)
{
    $K = KMP($par);
    for ($i = 0, $j = 0; $i < strlen($src);) {
        if ($j == strlen($par)) return $i - $j;
        
        echo $i, "  ", $j, " ", $src[$i], $par[$j], "<BR>";
        if ($par[$j] === $src[$i]) {
            $j++;
            $i++;
        } else {
            if ($j === 0 && $par[$j] != $src[$i]) {
                $i++;
            }
            $j = $K[$j - 1 >= 0 ? $j - 1 : 0];
        }
    }
    return false;
}

//测试数据
$src = 'BBC ABCDAB ABCDABCDABDE';
$par = 'ABCDABD';

// 匹配值
echo "匹配值:", implode(" ", KMP($par)), "<BR>";

// 在给定的字符串中查找特定字符(串)
echo  KMPMatch($src, $par, true), "<BR>";

6、实现中英文字符串翻转的操作

<?php

function mb_strrev($str)
{
    //判断输入的是不是utf8类型的字符,否则退出
    if (!is_string($str) || !mb_check_encoding($str, 'UTF-8')) {
        exit("输入类型不是UTF8类型的字符串");
    }
    $array = array();
    //将字符串存入数组
    $l = mb_strlen($str, 'UTF-8');
    for ($i = 0; $i < $l; $i++) {
        $array[] = mb_substr($str, $i, 1, 'UTF-8');
    }
    //反转字符串
    krsort($array);
    //拼接字符串
    $string = implode($array);
    return $string;
}
$str1 = "我是一个中国人Chinese";
echo $str1 . "->" . mb_strrev($str1) . "<br>";

7、PHP实现相关查找算法

<?php

/**
 * 二分查找算法
 * 初始数组为排好序的
 * binary()非递归
 * binaryRecursive() 递归
**/
$arr = [1, 3, 9, 23, 54];
function binary($arr, $low, $top, $target)
{
    while ($low <= $top) {
        $mid = floor(($low + $top) / 2);
        if ($arr[$mid] == $target) {
            return $mid;
        } elseif ($arr[$mid] < $target) {
            $low = $mid + 1;
        } else {
            $top = $mid - 1;
        }
    }
    return -1;
}

function binaryRecursive($arr, $low, $top, $target)
{
    if ($low <= $top) {
        $mid = floor(($low + $top) / 2);
        if ($arr[$mid] == $target) {
            return $mid;
        } elseif ($arr[$mid] < $target) {
            return binaryRecursive($arr, $mid + 1, $top, $target);
        } else {
            return binaryRecursive($arr, $low, $mid - 1, $target);
        }
    } else {
        return -1;
    }
}

echo binary($arr, 0, count($arr) , 9);//2
echo binaryRecursive($arr, 0, count($arr) , 9);//2

/**
 * 顺序查找
**/
$arr = [1, 2, 3, 4];
function query_search($val)
{
    global $arr;
    foreach ($arr as $k => $v) {
        if ($v == $val) {
            echo '顺序查找成功,KEY=>' . $k;
            exit(0);
        }
    }
    echo '顺序查找失败!';
}

echo query_search(3);
//顺序查找成功,KEY=>2

/**
 * 插入查找
 * 数组数据需要有序
**/
$i = 0;
function insertsearch($arr, $num)
{
    $count = count($arr);
    $lower = 0;
    $high = $count - 1;
    global $i;
    while ($lower <= $high) {
        $i++; //计数器
        if ($arr[$lower] == $num) {
            return $lower;
        }
        if ($arr[$high] == $num) {
            return $high;
        }
        
        $middle = intval($lower + ($num - $arr[$lower]) / ($arr[$high] - $arr[$lower]) * ($high - $lower));
        if ($num < $arr[$middle]) {
            $high = $middle - 1;
        } else if ($num > $arr[$middle]) {
            $lower = $middle + 1;
        } else {
            return $middle;
        }
    }
    
    return -1;
}

$arr = [0, 1, 16, 24, 35, 47, 59, 62, 73, 88, 99];
$pos = insertsearch($arr, 62);
echo $pos;//7
echo $i;//2 如果是折半查找的话i=3;

8、PHP实现相关排序算法

<?php

/**
 * 快速排序算法
**/
$arr = [6, 3, 8, 6, 4, 2, 9, 5, 1];
//函数实现快速排序
function quick_sort($arr)
{
    if (!is_array($arr)) {
        return false;
    }

    $length = count($arr);
    if ($length <= 1) {
        return $arr;
    }

    $left = $right = [];

    for ($i = 1; $i < $length; $i++) {
        //判断当前元素的大小
        if ($arr[$i] < $arr[0]) {
            $left[] = $arr[$i];
        } else {
            $right[] = $arr[$i];
        }
    }
    //递归调用
    $left = quick_sort($left);
    $left[] = $arr[0];
    $right = quick_sort($right);
    //将所有的结果合并
    return array_merge($left, $right);
}

print_r(quick_sort($arr));
//Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 6 [7] => 8 [8] => 9 )

9、PHP实现数独求解问题

<?php
/**
 * 规则每行每列每宫的数字都是1-9个数字组成,不能重复
**/
class ShuDu
{
    public $matrix;
    
    public function __construct($arr = null)
    {
        if ($arr == null) {
            $this->clear();
        } else {
            $this->matrix = $arr;
        }
    }
    
    public function clear()
    {
        for ($i = 0; $i < 9; $i++) {
            for ($j = 0; $j < 9; $j++) {
                $this->matrix[$i][$j] = [];
                for ($k = 1; $k <= 9; $k++) {
                    $this->matrix[$i][$j][$k] = $k;
                }
            }
        }
    }
    
    public function setCell($row, $col, $value)
    {
        $this->matrix[$row][$col] = [$value => $value];
        //row
        for ($i = 0; $i < 9; $i++) {
            if ($i != $col) {
                if (!$this->removeValue($row, $i, $value)) {
                    return false;
                }
            }
        }
        //col
        for ($i = 0; $i < 9; $i++) {
            if ($i != $row) {
                if (!$this->removeValue($i, $col, $value)) {
                    return false;
                }
            }
        }
        //square
        $rs = intval($row / 3) * 3;
        $cs = intval($col / 3) * 3;
        for ($i = $rs; $i < $rs + 3; $i++) {
            for ($j = $cs; $j < $cs + 3; $j++) {
                if ($i != $row && $j != $col) {
                    if (!$this->removeValue($i, $j, $value)) return false;
                }
            }
        }
        return true;
    }
    
    public function removeValue($row, $col, $value)
    {
        $count = count($this->matrix[$row][$col]);
        if ($count == 1) {
            $ret = !isset($this->matrix[$row][$col][$value]);
            return $ret;
        }
        if (isset($this->matrix[$row][$col][$value])) {
            unset($this->matrix[$row][$col][$value]);
            if ($count - 1 == 1) {
                return $this->setCell($row, $col, current($this->matrix[$row][$col]));
            }
        }
        return true;
    }
    
    public function set($arr)
    {
        for ($i = 0; $i < 9; $i++) {
            for ($j = 0; $j < 9; $j++) {
                if ($arr[$i][$j] > 0) {
                    $this->setCell($i, $j, $arr[$i][$j]);
                }
            }
        }
    }
    
    public function dump()
    {
        for ($i = 0; $i < 9; $i++) {
            for ($j = 0; $j < 9; $j++) {
                $c = count($this->matrix[$i][$j]);
                if ($c == 1) {
                    echo " " . current($this->matrix[$i][$j]) . " ";
                } else {
                    echo "(" . $c . ")";
                }
            }
            echo "<br/>";
        }
        echo "<br/>";
    }
    
    public function dumpAll()
    {
        for ($i = 0; $i < 9; $i++) {
            for ($j = 0; $j < 9; $j++) {
                echo implode('', $this->matrix[$i][$j]) , "\t";
            }
            echo "<br/>";
        }
        echo "<br/>";
    }
    
    public function calc($data)
    {
        $this->clear();
        $this->set($data);
        $this->_calc();
        $this->dump();
    }
    
    public function _calc()
    {
        for ($i = 0; $i < 9; $i++) {
            for ($j = 0; $j < 9; $j++) {
                if (count($this->matrix[$i][$j]) == 1) {
                    continue;
                }
                foreach ($this->matrix[$i][$j] as $v) {
                    $flag = false;
                    $t = new Sudoku($this->matrix);
                    if (!$t->setCell($i, $j, $v)) {
                        continue;
                    }
                    if (!$t->_calc()) {
                        continue;
                    }
                    $this->matrix = $t->matrix;
                    return true;
                }
                return false;
            }
        }
        return true;
    }
}
$sd = new ShuDu();
$sd->calc([
[0, 5, 0, 0, 0, 6, 0, 9, 0], 
[0, 4, 7, 0, 8, 2, 6, 0, 0], 
[0, 8, 0, 0, 0, 7, 0, 5, 2], 
[7, 0, 1, 0, 3, 4, 0, 0, 6], 
[0, 3, 0, 0, 2, 0, 0, 8, 0], 
[2, 0, 0, 0, 0, 1, 9, 0, 4], 
[4, 7, 0, 1, 0, 0, 0, 6, 0], 
[0, 0, 9, 4, 6, 0, 3, 7, 0], 
[0, 1, 0, 2, 0, 0, 0, 4, 0], 
]);

10、PHP中的Trait特性

PHP是单继承的语言,在PHP 5.4 Traits出现之前,PHP的类无法同时从两个基类继承属性或方法。php的Traits和Go语言的组合功能类似,通过在类中使用use关键字声明要组合的Trait名称,而具体某个Trait的声明使用trait关键词,Trait不能直接实例化,下面有篇文章比较详细的介绍了此功能,PHP-Trait特性详解

11、深刻理解PHP中的浅复制和深复制

<?php
/**
 * 深复制的原理是A的改变不会影响B的改变
 * 浅复制的原理是A的改变会影响B的改变
**/
class ObjA
{
    public $num = 0;
    public $objB; //包含的对象
    function __construct()
    {
        $this->objB = new ObjB();
    }
    //只有实现了下面方法聚合类 才能实现深复制
    /*function __clone() {
        $this->objB = clone $this->objB; 
    }*/
}

class ObjB
{
    public $num2 = 0;
}
//原型对象
$objA = new ObjA();
//复制对象(=复制引用)
$objA2 = $objA;
$objA2->num = 2;
//随着$objA2->num的变化 $objA->num也变化了
print_r($objA->num . '<br/>'); //结果为2
print_r($objA2->num . '<br/>'); //结果为2

//复制对象(‘clone’关键字克隆)
$objA3 = clone $objA;
$objA3->num = 4;
//随着$objA3->num的变化 $objA->num没有变化
print_r($objA->num . '<br/>'); //结果为2
print_r($objA3->num . '<br/>'); //结果为4
//但是clone的对象(是聚合类)中包含其他对象时所包含的对象(objB)复制的是引用
$objA3->objB->num2 = 7;
print_r($objA3->objB->num2 . '<br/>'); //结果是7
print_r($objA->objB->num2 . '<br/>'); //结果是7

相关文章:

  • FarmCraft[POI2014]
  • Google知道你多少秘密
  • 《Java语言导学(原书第6版)》一一1.1 关于Java技术
  • 机器学习系列(8)_读《Nature》论文,看AlphaGo养成
  • TCP负载均衡地址转换
  • 新Tegra将问世:8核ARM再配CUDA GPU
  • Intent的使用
  • 《设计原本—计算机科学巨匠Frederick P. Brooks的反思》一一2.3 理性模型有哪些长处...
  • 沟通在一个运维服务项目中的重要性
  • 一个APP从启动到主页面显示经历了哪些过程?
  • 超级简单:如何更快的将数据导入Excel
  • springboot同mybatis整合
  • 博达路由器常见功能教学1
  • 阿特斯副总裁邢国强:2017年底光伏组件成本2元以下
  • python实战===使用随机的163账号发送邮件
  • 2017届校招提前批面试回顾
  • 5、React组件事件详解
  • Akka系列(七):Actor持久化之Akka persistence
  • Angular 2 DI - IoC DI - 1
  • CentOS 7 修改主机名
  • CSS相对定位
  • hadoop集群管理系统搭建规划说明
  • in typeof instanceof ===这些运算符有什么作用
  • MySQL的数据类型
  • node和express搭建代理服务器(源码)
  • PhantomJS 安装
  • Python - 闭包Closure
  • Terraform入门 - 3. 变更基础设施
  • 从零开始学习部署
  • 如何选择开源的机器学习框架?
  • 微服务入门【系列视频课程】
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 小程序01:wepy框架整合iview webapp UI
  • 责任链模式的两种实现
  • ​香农与信息论三大定律
  • $.ajax()参数及用法
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (简单) HDU 2612 Find a way,BFS。
  • (十六)串口UART
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转) 深度模型优化性能 调参
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)Linux下编译安装log4cxx
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .NetCore实践篇:分布式监控Zipkin持久化之殇
  • .net开发时的诡异问题,button的onclick事件无效
  • .NET企业级应用架构设计系列之开场白
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • ?.的用法
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [20180224]expdp query 写法问题.txt
  • [AAuto]给百宝箱增加娱乐功能