PHP链式操作基本原理,call_user_func(),call_user_func_array()和Magic Methods__get(),__set(),__call()的用法

代码执行和命令执行 代码执行:未严格过滤用户输入的参数,导致用户可以通过传参在web服务器上执行恶意代码。可变函数:一个变量名后面如果有圆括号,php将寻找与变量值同名的函数并尝试执行。 阅读详情
前言

在阅读框架源码时发现源码中大量使用到了链式操作,和call_user_func()和call_user_func_array()这种调用函数的方法;
虽然两者并无关联,但是目的都是使代码更简洁,逻辑更清晰。
整理一些资料和大家一起学习。


call_user_func()和call_user_func_array():

call_user_func():把第一个参数作为回调函数调用,后面的参数作为回调函数的参数;
http://php.net/manual/zh/function.call-user-func.php

call_user_func_array():调用回调函数,并把一个数组参数作为回调函数的参数,第二各数组参数作为回调函数的参数。
http://php.net/manual/zh/function.call-user-func-array.php

两种方法类似,在不同的情况下有不同的参数传递方式,现在以call_user_func()为例讲一下各种情况:

回调函数可以用匿名函数,可以用有名函数,可以传递类的方法,

第一个参数为有名函数时,只需传函数的名称,用类的方法时,要传类的名称和方法名

内部方法作为回调函数:

<?php 
class Func{
    static public function sayHi(){
        $str ="HI ";
        if(func_num_args()){//获得参数的个数
            $arg = func_get_arg(0);//获取函数参数,获取参数也可以通过给方法设置形参来获取,这里只是没给方法设置形参获取参数的情况
            return $str.$arg;
        }else{
            return $str;
        }
    }
    
    public function number($num){
        return $num ? $num+1:$num;
    }
}
var_dump(call_user_func("Func::sayHi",'Boy !'));//静态方法,传递类名::方法名
$o = new Func;
$return = call_user_func([$o,'number'],1);//普通方法必须用数组传递该类的对象和方法名
var_dump($return);
?>

外部类作为回调函数:

<?php

namespace Foobar;

class Foo {
    static public function test() {
        print "Hello world!\n";
    }
   public function number($num){
        return $num ? $num+1:$num;
    }  
}
//静态方法
//命名空间\类名::方法名
call_user_func(__NAMESPACE__ .'\Foo::test'); // As of PHP 5.3.0
//命名空间\类名','方法名'
call_user_func([__NAMESPACE__ .'\Foo', 'test']); // As of PHP 5.3.0
//普通方法
$o = new Foo;
$return = call_user_func([$o,'number'],1);//普通方法必须用数组传递该类的对象和方法名
var_dump($return);
?>

外部类还可以通过相对路径的方法作为回调函数:
例如:回调函数为'\\think\\paginator\\driver\\'下的getCurrentPage方法,参数为$var_page

        $class = '\\think\\paginator\\driver\\' ;
        $page  = call_user_func([
            $class,
            'getCurrentPage',
        ],$var_page);

第一个参数为匿名函数时:
call_user_func函数是php引用匿名函数的一种方式,php不像js那样,可以把匿名函数赋值给变量并引用,但可以通过call_user_func函数来调用匿名函数,这也能做到局部变量不被全局污染。

<?php

call_user_func(function($call){
    echo ++$call,'<br/>';
    echo ++$call,'<br/>';
},1);

链式操作的原理

参考:https://www.jb51.net/article/103836.htm

链式操作的核心是返回$this指针,让后面的函数进行调用,和参数的共享!

结合__get(),__set(),__call()和__construct(构造方法)进行实现:

__construct 构造方法,创建类时调用
__get()是访问不存在的成员变量时调用;
__set()是设置不存在的成员变量时调用;
__call()当调用类中不存在的方法时调用。

通常在计算字符串函数的时候,要先对字符串进行过滤空格,然后再求其长度:

strlen(trim($str))

但是怎样才能以链式操作的形式实现?

$str->trim()->strlen();

核心思想:

链式操作,类的生命周期的结束在链式操作的末尾,所有可以通过成员变量的方式进行参数的共享,通过__construct进行成员变量的赋值,通过__get(),__set(),__call()来处理调用关系。

<?php
class StringHelper 
{
  private $value;
   
  function __construct($value)
  {
    $this->value = $value;
  }
 
  function __call($function, $args){
    $this->value = call_user_func($function, $this->value, $args[0]);//调用外部的trim()方法,传入2个参数
    return $this;
  }
 
  function strlen() {
    return strlen($this->value);
  }
}
 
$str = new StringHelper("hi boys and girls ! ");
echo $str->trim('0')->strlen();

查看更多:Magic Methods http://php.net/manual/zh/language.oop5.magic.php

最后

这里介绍的链式操作为其最基本的原理,而在框架中它又是如何被灵活运用呢?

敬请关注,后续文章!(o゜▽゜)o☆

深入探讨PHP中的call_user_func函数及其用法 下面是一个简单的示例,展示了如何使用$name!在上面的示例中,我们定义了一个函数,它接受一个参数$name并打印出问候语。然后,我们将函数名存储在变量中,并使用来调用该函数,同时传递参数'John'。通过,我们可以通过函数名的字符串形式来调用自定义函数,从而实现函数的动态调用。 阅读详情

相关推荐

PHP自定义函数call_user_func和call_user_func_array详解

这使得我们能够根据需要动态地调用不同的函数,并且可以在运行时根据条件决定要调用的函数。这些函数在某些情况下非常有用,例如在回调函数和事件处理程序中,或者当我们需要根据用户的输入来决定要调用的函数时。这两个函数提供了一种动态调用函数的能力,可以根据函数名的字符串形式来调用函数,而不需要提前知道函数的具体名称。函数非常相似,但是它允许我们将参数作为数组传递给被调用的函数。是一个包含参数的数组,这些参数将作为数组元素依次传递给被调用的函数。可以是一个函数名的字符串,也可以是一个包含类名和方法名的数组。

BUG?不存在的! 392

call_user_func()详解

先来看解释 : (PHP 4, PHP 5, PHP 7) call_user_func — 把第一个参数作为回调函数调用 通过函数的方式回调 &lt;?php  function barber($type){     echo "you wanted a $type haircut, no problem\n"; } call_user_func('barber','mushroom');...

moliyiran的专栏 3万+

从JX-2R-01热敏打印机芯到稳定打印:硬件设计与时序控制的实践指南

本文详细解析了JX-2R-01热敏打印机芯的硬件设计与驱动开发全流程。核心内容包括:实现严格的双电源上电时序控制、采用PWM恒流驱动步进电机确保走纸平稳,以及精确控制SPI数据加载与加热脉冲时序以获得清晰打印效果。文章提供了从电路设计、芯片选型到代码调试的实战指南,旨在帮助开发者构建稳定可靠的热敏打印模块。

weixin_29169899的博客 218

PHP call_user_func理解

 call_user_func():调用一个回调函数处理字符串,   可以用匿名函数,可以用有名函数,可以传递类的方法,   用有名函数时,只需传函数的名称   用类的方法时,要传类的名称和方法名   传递的第一个参数必须为函数名,或者匿名函数,或者方法   其他参数,可传一个参数,或者多个参数,这些参数会自动传递到回调函数中   而回调函数,可以通过传参,获取这些参数   返回回调函数处理后的结...

a18827547638的博客 7251

别再到处找模型了!手把手教你用Xinference+Docker部署本地私有大模型(Llama2/Qwen实战)

本文详细介绍了如何使用Xinference和Docker部署本地私有化大模型(如Llama2/Qwen),涵盖硬件配置、模型管理、Docker部署及性能优化等关键步骤。通过实战案例,帮助开发者快速构建企业级AI推理服务,确保数据安全与高效运行。

weixin_28683065的博客 231

C++总结笔记

/ ++操作 这是因为定义的数组,申请的是连续的内存空间,当ptr++(ptr是int类型的指针变量),地址空间向后偏移是以int类型的大小为单位进行偏移的,相当于int类型数组元素的向后偏移。使用场景:它是最通用的转换形式,用于将一种类型转换为另一种类型,例如基本数据类型的转换(如 float 转 int),指向基类的指针或引用转为指向派生类的指针或引用等。在派生类被调用时会调用派生类中的函数,不会调用基类中的被重写的函数(基类中的函数需要加上virtual才可以,即基类中的函数是虚函数)。

weixin_50890461的博客 5233

Web安全之命令执行漏洞

当 Web 应用需要调用一些执行系统命令的函数时,并且用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。

qq_42751192的博客 1675

别再手动折腾了!PICO Unity SDK 一键配置开发环境保姆级教程(含PDC串流调试)

本文详细介绍了PICO Unity SDK的一键配置功能,帮助开发者快速搭建VR开发环境。通过自动化配置流程,大幅减少手动设置时间,提升开发效率。文章还涵盖了PDC串流调试技巧和常见问题解决方案,是PICO VR开发的实用指南。

weixin_30335575的博客 449

CTF命令执行及绕过技巧

前言 今天是代码审计部分的一个技巧补充!前些阵子做了sql注入回顾篇系列!今天开启php代码审计系列! 今天内容主要是CTF中命令注入及绕过的一些技巧!以及构成RCE的一些情景! 文章目录前言正文代码执行代码执行的几种方式命令执行常见命令执行函数绕过姿势敏感字符绕过处理无回显的命令执行Think one Think 正文 在详细介绍命令注入之前,有一点需要注意:命令注入与远程代码执行不同。他们的区...

JBlock的博客 2万+

TeXstudio完整安装配置教程(2025最新版)

至此,你已经完成了TeXstudio的完整安装和配置!现在你可以:✅ 使用TeXstudio编写LaTeX文档✅ 正确编译中英文混排的文档✅ 掌握基本的编辑和配置技巧LaTeX的学习曲线较陡,但一旦掌握,你会发现它在学术写作中的强大之处。建议从简单的文档开始练习,逐步掌握更高级的功能。祝你LaTeX写作顺利!如果有任何问题,欢迎在评论区留言交流。关键词:TeXstudio安装、LaTeX环境配置、中文LaTeX、TeX Live、学术论文写作更新日期:2025年10月。

weixin_51241407的博客 4493

<PLC><汇川>汇川PLC基于EtherCat协议使用转矩模式控制SV630N伺服驱动电机

本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。除了PLC为主要内容外,PLC相关元器件如触摸屏(HMI)、交换机等工控产品,如果有值得记录的内容,也会添加进来。

用沸腾的热血,支付我们的人生吧! 4158

PHP反序列化漏洞:从原理到实战的Web安全攻防解析

序列化与反序列化是计算机科学中用于数据持久化与网络传输的基础技术,其核心原理是将复杂的数据结构(如对象)转换为可存储或传输的字符串格式,反之亦然。在PHP语言中,这一机制通过serialize()和unserialize()函数实现,为应用程序状态管理提供了便利。然而,当不可信的用户输入被直接传递给unserialize()函数时,其技术价值便可能转化为严重的安全风险。攻击者通过精心构造的序列化字符串,可以操控PHP解释器在反序列化过程中自动调用对象的魔法方法(Magic Methods),如__destr

weixin_33965305的博客 419

PDAF相位对焦原理

pdaf光路图

camerall 1万+

如何使用PHP的call_user_func()和call_user_func_array()函数?

想象一下,现在你不仅仅是一个小厨师,还是一个面包店的老板。想象一下,你现在是一个小厨师,你有很多食谱(也就是函数),但是你不想去一一记住每个食谱的做法(函数的调用方法),这个时候你就可以请一个小助手(有时候,你要调用的函数有很多参数,而且这些参数已经储存在一个数组里面了,这个时候,你就可以使用。是一个很有趣的函数,它可以帮助我们调用其他函数,就像是我们请一个小助手去帮我们做某件事情一样。会把数组中的每个元素作为函数的参数传入,而不是把整个数组作为一个参数。在实际使用中,请根据你的需求来调整代码。

长风破浪会有时的博客 1005

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之EcuM模块配置详解(上)

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之EcuM模块配置详解(上)

weixin_42412049的博客 1015

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

PHP反序列化5(回调函数call_user_func_array)

考点5:回调函数call_user_func_array()

2302_81328699的博客 1334

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

php函数重载 和call_user_func和call_user_func_array详解

php函数call_user_func和call_user_func_array详解 call_user_func函数类似于一种特别的调用函数的方法,使用方法如下:  function a($b,$c) { echo $b; echo $c; } call_user_func('a', "111","222"); call_user_func('a', "333","444");

云烟阁 2403

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

PHP之call_user_func函数

call_user_func ———— 把第一个参数作为回调函数调用 说明 call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] ) : mixed 第一个参数callback是被调用的回调函数,其余参数是回调函数的参数。 参数 callback 将被调用的回调函数(callable)。 parameter 0个或以上的参数,被传入回调函数。 Note: 请注意,传...

艺术编程 1340

在 PHP 中,call_user_func一共包含哪些部分?使用场景是什么?

是一个 PHP 内置函数,用于动态调用回调函数或方法。它可以接受一个函数名、闭包(匿名函数)或类方法作为参数,并执行它。想象你有一个遥控器,可以用来控制不同的设备(如电视、空调等)。的底层实现基于 PHP 的回调机制。PHP 会根据传入的。参数解析出要调用的函数或方法,并将其与提供的参数一起执行。的作用、使用场景、底层原理以及具体实现。就像是这个遥控器,它可以动态选择并执行某个功能。以下是一个具体的示例代码,展示如何使用。通过以上讲解和代码,你应该已经理解了。来动态调用函数、闭包和类方法。

长风破浪会有时的博客 988

php7 call_user_func,call_user_method_array()

call_user_method_array()(PHP 4 >= 4.0.5, PHP 5)以参数列表的数组,调用用户方法WarningThis function wasDEPRECATEDin PHP 4.1.0,andREMOVEDin PHP 7.0.0.Alternatives to this function include:说明call_user_method_array(st...

weixin_39611820的博客 381

简单理解call_user_func和call_user_func_array两个函数

简单理解call_user_func和call_user_func_array两个函数 描述   call_user_func():调用一个回调函数处理字符串,   可以用匿名函数,可以用有名函数,可以传递类的方法,   用有名函数时,只需传函数的名称   用类的方法时,要传类的名称和方法名   传递的第一个参数必须为函数名,或者匿名函数,或者方法   其他参数,可传一个参数,或者多个参...

dengliu_2017的博客 603

PHP函数详解:call_user_func()使用方法

call_user_func函数类似于一种特别的调用函数的方法,使用方法如下:<?php function nowamagic($a,$b) { echo $a; echo $b; } call_user_func('nowamagic', "111","222"); call_user_func('nowamagic', "333","444")

完美世界 2万+

php call_user_func()函数

1. 函数说明  调用回调函数。原型: mixed call_user_func ( callable callback[,mixedcallback [, mixed parameter [, mixed $… ]] )。 第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。参数可以有多个,也可以是数组。   参数不可以为引用,但可以通过数组传递引用。下面是一个例子:

Jeanphorn的专栏 6472

【PHP开发900个实用技巧】872.PHP call_user_func与call_user_func_array:动态函数调用的“万能钥匙”

PHP回调函数验证实战指南:is_callable()核心用法解析 摘要:本文深入探讨PHP回调验证的关键技术is_callable(),从基础使用到框架级应用层层剖析。文章首先通过典型错误案例揭示未验证回调的风险,如函数名拼写错误导致的致命错误和恶意函数注入漏洞。随后详解is_callable()的三大核心功能:普通函数检测、类方法验证和参数高级用法,特别强调语法检查模式对性能的优化。在实战部分,以Laravel框架为例,展示如何构建包含回调验证的安全控制器模板和事件系统。全文贯穿防御性编程思想,指出is

1350

java call user func_简单理解call_user_func和call_user_func_array两个函数(示例代码)

简单理解call_user_func和call_user_func_array两个函数描述call_user_func():调用一个回调函数处理字符串,可以用匿名函数,可以用有名函数,可以传递类的方法,用有名函数时,只需传函数的名称用类的方法时,要传类的名称和方法名传递的第一个参数必须为函数名,或者匿名函数,或者方法其他参数,可传一个参数,或者多个参数,这些参数会自动传递到回调函数中而回调函数,可...

weixin_36304087的博客 347
上一篇: phpWord下载出错,状态响应为 net::ERR_INVALID_RESPONSE(500)
下一篇: ArcGIS Engine 开发 (四)打开,保存,另存为地图文档功能(IMapDocument接口)
define_YIDA
博客等级 码龄9年 323粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值