php备忘录

php开启Gzip压缩


if (extension_loaded('zlib')){
    ob_end_clean();
    ob_start('ob_gzhandler');
    
}

php版本比较


version_compare(PHP_VERSION,'5.5.0','<')

php .env文件转数组


parse_ini_file( '.env', true)

php .env文件转数组


putenv() getenv() 设置以及获取环境变量

php 判断是否是ajax请求


$_SERVER['HTTP_X_REQUEST_WITH']== 'XMLHttpRequest'

mysql导出全部表结构


SELECT
  COLUMN_NAME 列名,
  COLUMN_TYPE 数据类型,
    DATA_TYPE 字段类型,
  CHARACTER_MAXIMUM_LENGTH 长度,
  IS_NULLABLE 是否为空,
  COLUMN_DEFAULT 默认值,
  COLUMN_COMMENT 备注 
FROM
 INFORMATION_SCHEMA.COLUMNS
where
-- developerclub为数据库名称,到时候只需要修改成你要导出表结构的数据库即可
table_schema ='developerclub'
AND
-- article为表名,到时候换成你要导出的表的名称
-- 如果不写的话,默认会查询出所有表中的数据,这样可能就分不清到底哪些字段是哪张表中的了,所以还是建议写上要导出的名名称
table_name  = 'article'

php getter和setter

方法一:直接箭头->调用属性(最常用),不管有没有声明这个属性,都可以使用,但会报Notice级别的错误
方法二:添加setter和getter方法,类似于Java
class Dog
{
	private $name="";
	public function setName($value)
	{
		$this->name=$value;
	}
	public function getName()
	{
		return $this->name;
	}
}
方法三:魔术方法 __set,__get,__isset,__unset当访问类中不可达参数或未定义参数时,则会调用魔术方法。
class Dog1
{
    private $_name = '';
    function __set($property, $value) {
        if ($property === 'name') $this->_name = $value;
    }
    function __get($property) {
        if ($property === 'name') return $this->_name;
    }
}

在这里插入图片描述

php

new static()和new self();
XX::class;

consul:一个服务网格(微服务间的 TCP/IP,负责服务之间的网络调用、限流、熔断和监控)解决方案,它是一个一个分布式的,高度可用的系统,而且开发使用都很简便。它提供了一个功能齐全的控制平面,主要特点是:服务发现、健康检查、键值存储、安全服务通信、多数据中心。

number_format()

number_format(12345.66);   //12,346
number_format(12345.44);   //12,345
number_format(12345.44,1); //12,345.4

验证邮箱

filter_var($email,FILTER_VALIDATE_EMAIL);
preg_match('/^[0-9a-zA-Z]+@[0-9a-zA-Z]+(\.[0-9a-zA-Z]+){1,3}$/',$email);

双向队列

array_unshift与array_shift,array_push与array_pop

对二维数组根据某个key值排序

usort($arr,function ($a,$b) use ($var){
            return strnatcmp($a[$var],$b[$var]);
        });

多维数组首字母大写

array_walk_recursive($arr,function (&$value,$key){
            $value=ucfirst($value);
        });

秒杀系统

要点是分布锁的使用,使库存不被错误操作。

网络攻击

sql注入
如 name=“1;‘delete from table’;”;
使用pdo预处理prepare;使用addslashes进行转义;
xss脚本攻击
如text="*";
使用htmlspecialchars()
csrf
进行token验证

php7新特性

  1. 标量类型声明
  2. 返回值类型声明
  3. null合并运算。$param = $_GET[‘param’] ?? ‘’;??运算符会根据一个值来判断它是否是存在且不为NULL,如果是则返回第一个数,否则返回第二个数。
  4. 组合比较符。<=>
  5. define定义常量数组。
  6. 匿名类。
$class=new class()
{
	public function execute()
	{}
}
  1. 闭包绑定。之前声明一个闭包之后需要为为闭包绑定执行上下文,需要复制闭包然后绑定$this,现在使用call()省去复制步骤,更加方便,性能更好。
PHP7之前

class App
{

    public function execute()
    {
        echo 'App execute';
    }

}

$closure = function() {
    echo $this->execute();
};

$newClosure = Closure::bind($closure, new App());
//或者$newClosure = $closure->bindTo(new App());
$newClosure(); //输出App execute

PHP7

class App
{

    public function execute()
    {
        echo 'App execute Call';
    }

}

$closure = function() {
    echo $this->execute();
};

$closure->call(new App());
//输出App execute Call
  1. unserialize过滤
  2. 命名空间批量导入
//PHP之前
use oopsguy\framwork\core\Controller;
use oopsguy\framework\core\Model;
use oopsguy\framework\core\Config;

use function oopsguy\framework\core\function\func1;
use function oopsguy\framework\core\function\func2;

use const oopsguy\framework\core\constant\CONST_SESSION_KEY;
use const oopsguy\framework\core\constant\CONST_MANAGER_SESSION_KEY;

//PHP7
use oopsguy\framework\core\{Controller, Model, Config};
use function oopsguy\framework\core\function\{func1, func2};
use const oopsguy\framework\core\constant\{CONST_SESSION_KEY, CONST_MANAGER_SESSION_KEY};
新特性使得命名空间的声明语句变得简洁许多,精简了很多代码。
  1. 生成器返回表达器。生成器允许在foreach代码块中写代码来迭代一组数据而不需要在内存中创建一个数据,使你的内存达到上限,或者占据客观的处理时间。迭代的时候才会取值,不会把遍历的数据全部放入内存。php7中添加了getReturn接口,可以获取return返回值。
function getContent()
{
    $handler = @fopen('web.config','rb');
    if(is_resource($handler)){
        while (!feof($handler)){
            yield fgets($handler);
        }
        fclose($handler);
        return "end";
    }
    return "no handler";
}
$content=getContent();
foreach ($content as $val){
    echo $val;
}
echo $content->getReturn();
  1. 生成器委托 yield from
function getAllContent()
{
    yield from getContent('web.config');
    yield from getContent('robots.txt');
}
function getContent($file)
{
    $handler = @fopen($file,'rb');
    if(is_resource($handler)){
        while (!feof($handler)){
            yield fgets($handler);
        }
        fclose($handler);
        return "end";
    }
    return "no handler";
}
$content=getAllContent();
foreach ($content as $val){
    echo $val;
}
echo $content->getReturn();
  1. 整除函数 intdiv
  2. session配置,可以session_start时传入一个数组配置参数来覆盖运行时的php.ini文件的配置。
  3. list解构。list不仅能结构数组,还能结构实现了ArrayAccess接口的对象。
class Config implements ArrayAccess
{
    private $data = [];

    function __construct($file)
    {
        /** @noinspection PhpIncludeInspection */
        $this->data = include $file;
    }

    public function offsetExists($offset)
    {
        return isset($this->data[$offset]);
    }

    public function offsetGet($offset)
    {
        return ($this->offsetExists($offset))
            ? $this->data[$offset]
            : null;
    }

    public function offsetSet($offset, $value)
    {
        $this->data[$offset] = $value;
    }

    public function offsetUnset($offset)
    {
        if ($this->offsetExists($offset))
            unset($this->data[$offset]);
    }
}

$config = new Config('config.php');
echo $config[1] , '<br>';
list($key, $key1) = $config;
echo $key , '<br>';
echo $key1 , '<br>';

php7性能提升原因

1、存储变量的结构体变小,尽量使结构体里成员共用内存空间,减少引用,这样内存占用降低,变量的操作速度得到提升

2、字符串结构体的改变,字符串信息和数据本身原来是分成两个独立内存块存放,php7尽量将它们存入同一块内存,提升了cpu缓存命中率

3、数组结构的改变,数组元素和hash映射表在php5中会存入多个内存块,php7尽量将它们分配在同一块内存里,降低了内存占用、提升了cpu缓存命中率

4、改进了函数的调用机制,通过对参数传递环节的优化,减少一些指令操作,提高了执行效

像访问数组一样访问php类或对象

让类实现php的ArrayAccess(数组式访问)

fastcgi通过端口监听和通过文件监听的区别

fastcgi_pass 127.0.0.1:9200  //TCP连接
fastcgi_pass /tmp/php_cgi.sock  // Unix domain Socket

从数组中查找最小的k个元素

/**
 * 从数组里找出最小的 $k 个数
 * @param $arr array 输入数组
 * @param $k int 输出元素个数
 * @return array 最小元素集合
 */
function getMinK($arr, $k)
{
    $n=count($arr);
    $minArray=[];
    for($i=0;$i<$n;++$i){
        if($i<$k){
            $minArray[$i]=$arr[$i];
        }else{
            if($i==$k){
                $maxPos=getMaxPos($minArray);
                $max=$minArray[$maxPos];
            }
            if($max>$arr[$i]){
                $minArray[$maxPos]=$arr[$i];
                $maxPos=getMaxPos($minArray);
                $max=$minArray[$maxPos];
            }
        }
    }
    return $minArray;
}
/**
 * 从数组中查找最大值的位置
 * @param $arr array 待查找数组
 * @return int 位置
 */
function getMaxPos($arr)
{
    $pos = 0;
    for ($i = 1; $i < count($arr); $i++) {
        if ($arr[$i] > $arr[$pos]) {
            $pos = $i;
        }
    }
    return $pos;
}
$arr = [1, 100, 20, 22, 33, 44, 55, 66, 23, 79, 18, 20, 11, 9, 129, 399, 145, 2469, 58];
$res = getMinK($arr, 5);
// 输出:[1,9,20,11,18]
echo json_encode($res);

取出n以内的质数

/**
 * 1是合数,2是第一个质数,所以从3开始计算,除2外的偶数都不是质数,所以循环的补偿可以为2。
 * n不能够被不大于根号n的任何质数整除,则n是一个质数
 * @param $n
 * @return array
 */
function primeNumber($n)
{
   $prime=array(2);
   for ($i=3;$i<$n;$i+=2){
       $sqrt=intval(sqrt($i));
       for ($j=3;$j<=$sqrt;$j+=2){
           if($i%$j==0){
                break;
           }
       }
       if($j>$sqrt){
           array_push($prime,$i);
       }
   }
   return $prime;
}

数字和字母字符串分割成索引数组

/**
 * preg_split 匹配正则的边界分隔符,
 * @param $str
 * @return array
 */
function split(string $str) :array
{
    $num=preg_split('/[a-zA-Z]+/',$str,-1,PREG_SPLIT_NO_EMPTY);
    $char=preg_split('/\d+/',$str,-1,PREG_SPLIT_NO_EMPTY);
    $count=count($num);
    $array=[];
    for ($i=0;$i<$count;++$i){
        $array[$num[$i]]=$char[$i];
    }
    return $array;
}

php性能优化

  1. 使用php7+
  2. 减少业务复杂度
  3. 使用异步消息队列处理复杂请求
  4. 使用缓存
  5. sql优化

php如何实现并发

  1. curl_multi_get()
  2. swoole
  3. exec

php调试

ini_set("display_error","on");
error_reporting(E_ALL);

php使用和处理异常

try {
    // 执行操作,比如连接数据库、读写文件,这里必须throw exception才可以被捕捉
} catch (MyException $e) {
    // 执行有错误,在这里处理错误(显示、读入log、或显示执行信)
} catch (Exception $e) {
    // 可以分别catch多个异常
} finally {
    // 最后可以返回连接、数据、或其他处理
}

php-fpm有哪些子进程运行方式

主要在php-fpm.conf进行配置,有三种static,dynamic,ondemand

php序列化方法

  1. serialize和unserialize(),序列化保存数据类型,100%能还原;体积大,速度慢;可读性差;php自带,不可跨平台。
  2. json_encode()和json_decode(),反序列化数据类型会有缺失;体积小,速度快;可读性强;跨平台。

php接口和抽象类的区别

  1. 都不能被实例化
  2. 定义接口的关键词是interface,实现是implement,抽象类是abstract class,实现是extends
  3. 接口的每一个方法都是public抽象方法,都只是定义,都必须实现
  4. 抽象类的方法不能是private,可以选择的实现
  5. 接口没有数据成员和构造函数,抽象类可以有

php魔术方法

__contruct():每次new对象的时候会调用
__destruct():每次对象的所有引用被删除时会调用
__call():在对象中调用一个不可访问的方法时调用
__callStatic():在静态上下文中调用一个不可访问访问时调用
__set():在给不可访问属性赋值时调用
__get():在获取不可访问属性时调用
__isset():在对不可访问属性调用isset时调用
__unset()同理__isset()
__sleep和__wakeup:serialize和unserialize时调用
__toString()和__debugInfo():echo和var_dump时调用
__clone():使用clone复制对象时调用

php中this,self,static,parent

this是实例对象的指针;
self是类本身的一个引用,一般用来指向静态变量,取决于定义当前方法所在的类;
static也是对类本身的一个引用,取决于运行时计算的;
parent是对父类的引用;

php传值和传引用的区别

传值,是将值赋值给行参。
传引用,实参和行参指向同一个对象,行参的值改变将影响实参的值。

php大版本改进

php7:性能提升;数据类型定义;匿名类;null合并运算符??;字符比较符<=>,yield from,yield::getReturn
php5.6:运算符定义变长参数函数
php5.5:新增generators,yield关键字
php5.4:trait,cli模式的web server
php5.3:命名空间,闭包

php创建字符串

单引号和newDoc(<<< ‘EOT’),双引号和hereDoc(<<< EOT)

获取文件中的图片并下载

/**
 * 需要先获取到img url路径,再计算本地存储的path
 * @param $url
 * @param null $target_dir
 * @return bool
 */
function downImagesFromTargetUrl($url, $target_dir = null)
{
    if(!filter_var($url, FILTER_VALIDATE_URL)){
        return false;
    }
    if(!$target_dir) {
        $target_dir = './download';
    }
    $root_url = pathinfo($url);
    $html = file_get_contents($url);                                    //主要
    preg_match_all('/<img[^>]*src="([^"]*)"[^>]*>/i',$html, $matchs);   //主要
    $images = $matchs[1];
    foreach ($images as $img) {
        $img_url = parse_url($img);
        if(! array_key_exists('host', $img_url)) {
            $img_url = $root_url['dirname'] . DIRECTORY_SEPARATOR . $img;
        } else {
            $img_url = $img;
        }
        $img_path = array_key_exists('path', parse_url($img_url)) ? parse_url($img_url)['path'] : $img;
        $save = $target_dir . DIRECTORY_SEPARATOR . $img_path;
        $save_path = pathinfo($save);
        if(!is_dir($save_path['dirname'])) {
            mkdir($save_path['dirname'], 0777, true);
        }
        file_put_contents($save,file_get_contents($img_url));           //主要
    }
}

php实现单向链表,判断单向链表有没形成环,环入口在哪

单向链表是链表中的一种,其特点是链表的链接方向是单向的,对链表的访问要顺序通过头部节点开始,又称节点列表,链表是由一个个节点组装起来,head指针指向第一个成为表头节点,而终止于最后一个指向null的指针。

class Node
{
    public $id;
    public $name;
    public $next;

    public function __construct($id,$name,$next=null)
    {
        $this->id=$id;
        $this->name=$name;
        $this->next=$next;
    }
}

class LinkList
{
    public $head;

    public function __construct($id=null,$name=null,$next=null)
    {
        $this->head=new Node($id,$name,$next);
    }

    public function getLinkListLen()
    {
        $i=0;
        $current=$this->head;
        while($current->next!=null){
            $i++;
            $current=$current->next;
        }
        return $i;
    }
    public function addLink($node)
    {
        $current=$this->head;
        while ($current->next!=null){
            if($current->next->id > $node->id){
                break;
            }
            $current=$current->next;
        }
        $node->next=$current->next;
        $current->next=$node;
    }
    public function deleteLink($node)
    {
        $current=$this->head;
        $flag =false;
        while($current->next!=null){
            if($current->next->id == $node->id){
                $flag=true;
                break;
            }
            $current=$current->next;
        }
        if($flag){
            $current->next=$current->next->next;
        }else{
            echo "未找到该节点";
        }
    }
    public function getLinkList()
    {
        $current=$this->head;
        if($current->next==null){
            return "空链表";
        }
        while ($current->next!=null){
            echo $current->id."-".$current->name."<br>";
            if($current->next->next==null){
                break;
            }
            $current=$current->next;
        }
    }
}
$lists = new LinkList ();

$lists->addLink ( new Node ( 5, 'eeeeee' ) );

$lists->addLink ( new Node ( 1, 'aaaaaa' ) );

$lists->addLink ( new Node ( 6, 'ffffff' ) );

$lists->addLink ( new Node ( 4, 'dddddd' ) );

$lists->addLink ( new Node ( 3, 'cccccc' ) );

$lists->addLink ( new Node ( 2, 'bbbbbb' ) );

$lists->getLinkList ();


function eatLink(Node $node)
{
    $fast=$slow=$node;

    while(true){
        if ($fast->next==null || $fast->next->next==null){
            return;
        }else{
            $fast=$fast->next->next;
            $slow=$slow->next;
        }
        if($fast==$slow){
            $p1=$node;
            $p2=$fast;
            while($p1!=$p2){
                $p1=$p1->next;
                $p2=$p2->next;
            }
            return $p1;
        }
    }
}

判断长方形

1.四个不同的点,2.算出点与点的长度,判断是否符合勾股定理

function isRectangle($point1, $point2, $point3, $point4){
    if ($point1 == $point2 || $point1 == $point3  || $point1 == $point4 || $point2 == $point3 || $point2 == $point4 || $point3 == $point4) {
        return false;
    }
    $lengthArr = [];
    $lengthArr[] = getLengthSquare($point1, $point2);
    $lengthArr[] = getLengthSquare($point1, $point3);
    $lengthArr[] = getLengthSquare($point1, $point4);
    $lengthArr[] = getLengthSquare($point2, $point3);
    $lengthArr[] = getLengthSquare($point2, $point4);
    $lengthArr[] = getLengthSquare($point3, $point4);
    $lengthArr = array_unique($lengthArr);
    $lengthCount = count($lengthArr);
    if ($lengthCount == 3 || $lengthCount == 2 ) {
        if ($lengthCount == 2) {
            return(max($lengthArr) == 2*min($lengthArr));
        } else {
            $maxLength = max($lengthArr);
            $minLength = min($lengthArr);
            $otherLength = array_diff($lengthArr, [$maxLength, $minLength]);
            return($minLength + $otherLength == $maxLength);
        }
    } else {
        return false;
    }
}
function getLengthSquare($point1, $point2){
    $res = pow($point1[0]-$point2[0], 2)+pow($point1[1]-$point2[1], 2);
    var_dump($res);
    return $res;
}
var_dump(isRectangle([0,0],[0,2],[2,2],[2,0]));

遍历目录

function scanDirs($dir="./")
{
    $data=array();
    if(!is_dir($dir)){
        return;
    }
    $handler=opendir($dir);
    if(is_resource($handler)){
        while ($file=readdir($handler)){
            if($file=="."||$file==".."){

            }elseif (is_dir($dir.DIRECTORY_SEPARATOR.$file)){
                $data[$file]=scanDirs($dir.DIRECTORY_SEPARATOR.$file);
            }else{
                array_push($data,$file);
            }
        }
    }
    return $data;
}

计算相对路径

function getRelativePath($path1, $path2)
{
    $path1Arr=explode('/',$path1);
    $path2Arr=explode('/',$path2);
    $len=count($path1Arr);
    $dismatch=0;
    $left='';
    for($i=0;$i<$len;++$i){
        if($path1Arr[$i]!=$path2Arr[$i]){
            $dismatch=$len-$i;
            $left=array_slice($path1Arr,$i);
            break;
        }
    }
    if ($dismatch){
        echo str_repeat("../",$dismatch).implode('/',$left);
    }
}
$a = '/a/b/c/d/e.php';
$b = '/a/b/12/34/5.php';
echo getRelativePath($a, $b);

遍历二叉树

前序遍历:中左右
中序遍历:左中右
后序遍历:左右中

class Node
{
    public $data = null;
    public $left = null;
    public $right = null;
}
$A = new Node();
$B = clone $A;
$C = clone $A;
$D = clone $A;
$E = clone $A;
$F = clone $A;
$G = clone $A;
$H = clone $A;
$I = clone $A;
$A->data = 'A';
$B->data = 'B';
$C->data = 'C';
$D->data = 'D';
$E->data = 'E';
$F->data = 'F';
$G->data = 'G';
$H->data = 'H';
$I->data = 'I';
$A->left = $B;
$A->right = $C;
$B->left = $D;
$B->right = $E;
$E->left = $G;
$E->right = $H;
$G->right = $I;
$C->right = $F;
/**
 * 前序遍历: 中左右
 * 中序遍历: 左中右
 * 后序遍历: 左右中
 */
function eatBtree($node)
{
    if($node && $node->data){
        if($node->data){
            echo $node->data;
        }
        if($node->left){
            eatBtree($node->left);
        }
        if($node->right){
            eatBtree($node->right);
        }
    }
}
eatBtree($A);

字符串翻转

function reverseString($str)
{
    $output = '';
    $i = 0;
    while (isset($str[$i]) && $str[$i] != null) {
        $output = $str[$i++] . $output;
    }
    return $output;
}
// 测试代码,输出:9876543210
echo reverseString('0123456789');

括号闭合问题

主要左括号进栈,右括号出栈左括号,成一对。

function checkClose($str)
{
    $stack=[];

    for ($i=0;$i<strlen($str);++$i){
        if($str[$i]=="("){
            $stack[]="(";
        }
        if($str[$i]==')'){
            if(!array_pop($stack)){
                return false;
            }
        }
    }
    if(count($stack)==0){
        return true;
    }else{
        return false;
    }
}
var_dump( checkClose('(()))'));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值