PHP弱类型全面复盘

写在前面

连续碰了两次不同的PHP弱类型题,都卡了很久,还是总结一下吧

有几个点在网上不同师傅的文章意见不一样,本着实践出真知的想法,本次的所有内容都跑了代码,或者查阅了官方文档

本次的代码保留了老版本的测试结果,而我会基于新的版本进行测试,本文的注意点部分很多都是最新版本中的变动

至于考证每种绕过方式具体哪些版本可用,工作量实在太大,先写进Todo里吧

PHP版本:PHP Version 8.2.2

概念

  • 强类型是两个不同类型的变量不能用同一块内存存储
  • 弱类型是两个不同类型的变量可以用同一块内存存储

PHP 是弱类型语言

弱类型简单来说就是数据类型可以被忽视的语言,和强类型语言的强制数据类型定义不同,弱类型可以一个变量赋不同数据类型的值

PHP 类型比较表

弱比较/松散比较/==

注意PHP 8.0.0是一个分水岭,有些弱比较无法使用了

强比较/严格比较/===

类型转换问题

比较操作符

  • ===在进行比较的时候,会先判断两种字符串的类型是否相等,再比较
  • ==在进行比较的时候,会先将字符串类型转化成相同,再比较

如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行
比较简单,不过多举例

Hash 比较缺陷
"0e132456789"=="0e7124511451155" //true
"0e123456abc"=="0e1dddada"  //false
"0e1abc"=="0"     //true

在进行比较运算时,如果遇到了 0exxxxx(xxxxx为纯数字) 这种字符串,就会将这种字符串解析为科学计数法

如果不满足 0exxxxx(xxxxx为纯数字) 这种模式,就会当作字符串进行比较,所以不会相等

注意点

在最新版本中"0e1abc""0"弱比较也不相等

var_dump("0e1abc"=="0"); // false
十六进制转换
"0x1e240"=="123456"     //true
"0x1e240"==123456       //true
"0x1e240"=="1e240"      //false

当其中的一个字符串是 0x 开头的时候,PHP 会将此字符串解析成为十进制然后再进行比较

注意点

在最新版本中,弱比较不再将字符串解析成为十进制然后再进行比较

"0x1e240"=="123456"     //false
"0x1e240"==123456       //false

类型转换

<?php
  $test=1 + "10.5"; // $test=11.5(float)
  $test=1 + "-1.3e3"; //$test=-1299(float)
  $test=1 + "bob-1.3e3";//$test=1(int)
  $test=1 + "2admin";//$test=3(int)
  $test=1 + "admin2";//$test=1(int)
?>

PHP 手册:

当一个字符串当作一个数值来取值,其结果和类型如下:

  • 如果该字符串没有包含.,e,E,并且其数值在整型的范围之内,则该字符串被当作 int 来取值
  • 其他所有情况下都被作为 float 来取值

该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为 0

注意点

在PHP 8.0.0引入了数字字符串,PHP 8.0.0之后之前说的部分规则不适用了

<?php
  $foo = 1 + "10.5";                // $foo 是 float (11.5)
  $foo = 1 + "-1.3e3";              // $foo 是 float (-1299)
  $foo = 1 + "bob-1.3e3";           // PHP 8.0.0 起产生 TypeError;在此之前 $foo 是 integer (1)
  $foo = 1 + "bob3";                // PHP 8.0.0 起产生 TypeError;在此之前 $foo 是 integer (1)
  $foo = 1 + "10 Small Pigs";       // PHP 8.0.0 起,$foo 是 integer (11),并且产生 E_WARNING;在此之前产生 E_NOTICE
  $foo = 4 + "10.2 Little Piggies"; // PHP 8.0.0 起,$foo 是 float (14.2),并且产生 E_WARNING;在此之前产生 E_NOTICE
  $foo = "10.0 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neolock

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值