php中$this和::能混用吗_对象与静态作用域冲突解决【方法】
技术百科
絕刀狂花
发布时间:2026-01-01
浏览: 次 PHP中$this与::不可混用:$this仅用于实例上下文,::用于静态或父类成员访问;混用会触发Fatal error;self::静态绑定,static::后期静态绑定,$this->动态绑定。
PHP 中 $this 和 :: 不能混用,直接写会报错
在 PHP 类中,$this 指向当前实例对象,只能用于非静态(instance)上下文;而 :: 是作用域解析操作符,用于访问类的静态成员(static 属性/方法)或父类成员。二者运行时所依赖的作用域完全不同——混用会导致 Fatal error: Using $this when not in object context 或 Cannot access static property ... via $this。
$this->method() 和 self::method() 的本质区别
关键不在语法像不像,而在调用时绑定的目标不同:
-
$this->foo():运行时动态绑定,走对象的虚函数表(支持重写、多态) -
self::foo():编译期静态绑定,固定指向定义该语句的类(不随继承链变化) -
static::foo():后期静态绑定(LSB),运行时绑定到“实际调用的类”,支持继承覆盖
例如:
class A {
public function call() {
echo $this->who(); // 输出 "A"(若未重写)
echo self::who(); // 总是输出 "A"
echo static::who(); // 输出实际调用者类名(如 B::call() 则输出 "B")
}
public function who() { return 'A'; }
public static function who() { return 'A'; }
}
class B extends A {
public function who() { return 'B'; }
public static function who() { return 'B'; }
}
常见错误场景与修复方式
以下写法都会出问题:
- 在
static方法里写$this->xxx→ 报Fatal error;应改用self::/static::或传入实例参数 - 在普通方法里用
self::调用非静态方法 → 语法允许但逻辑危险(绕过$this绑定,可能丢失对象状态) - 误以为
$this::xxx是“实例版::” → 实际上它等价于static::xxx(PHP 5.3+),不是$this->xxx - 静态方法中需要访问实例数据 → 必须显式传参,不能靠
$this
什么时候必须用 static:: 而不是 self::
当类被继承,且子类重写了静态方法或常量,又希望在父类中调用“子类版本”时:
- 用
self:::永远调用父类定义的静态成员 - 用
static:::调用实际运行时的类(即 late static binding)
典型例子是工厂模式或单例基类:
class Base {
protected static $instance = null;
public static function getInstance() {
if (static::$instance === null) { // ← 这里必须用 static::
static::$instance = new static(); // ← 否则 new self() 永远创建 Base 实例
}
return static::$instance;
}
}
class Child extends Base {}
$child = Child::getInstance(); // 得到 Child 实例,而非 Base
真正容易被忽略的是:即使你没写 static 关键字,只要用了 ::,就要立刻判断当前上下文是否允许——静态方法里没有 $this,这是硬约束,不是风格问题。
# Error
# 对象
# Property
# 区别
# 子类
# access
# Static
# this
# 继承
# 作用域
# php
# 多态
# Object
# 虚函数
# 常量
# 父类
# using
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- PyTorch DDP 多进程训练在 Kaggle
- 如何使用Golang反射创建map对象_动态生成键
- c++怎么使用类型萃取type_traits_c+
- php增删改查需要哪些扩展_开启mysqli或pd
- php订单日志怎么导出excel_php导出订单日
- Win11讲述人怎么关闭_Win11误触开启语音朗
- 如何在 Go 中创建包含映射(map)的切片(sl
- Win11怎么禁用键盘自带键盘_Win11笔记本禁
- 如何使用Golang进行HTTP服务性能测试_测量
- Windows10如何更改开机密码_Win10登录
- 如何在JavaScript中动态拼接PHP的bas
- VSC里PHP变量未定义报错怎么解决_错误抑制技巧
- c++怎么处理多线程死锁_c++ lock_gua
- PythonFastAPI项目实战教程_API接口
- c++中的CRTP是什么 c++奇异递归模板模式【
- PythonDocker高级项目部署教程_多容器管
- c++ atoi和atof函数用法_c++字符数组
- Win11如何开启telnet服务 Win11启用
- Win11怎样安装企业微信_Win11安装企业微信
- Python正则表达式实战_模式匹配说明【教程】
- 如何在Golang中处理模块冲突_解决依赖版本不兼
- Windows10如何更改鼠标灵敏度_Win10鼠
- 如何使用Golang编写单元测试_创建Test函数
- Mac如何创建和管理多个桌面空间_Mac高效多任务
- 如何使用Golang搭建本地API测试环境_快速验
- Win10怎样安装Word样式库_Win10安装W
- php打包exe后无法写入文件_权限问题解决方法【
- Win11怎么更改系统语言_Win11中文语言包下
- Win11怎么恢复出厂设置_Win11重置此电脑保
- 微信JSAPI支付回调PHP怎么接收_处理JSAP
- C#如何使用XPathNavigator高效查询X
- Python数据挖掘进阶教程_分类回归与聚类案例解
- c++如何使用std::bitset进行位图算法_
- Mac怎么给文件夹加密_Mac创建加密磁盘映像教程
- PhpStorm怎么调试PHP代码_PhpStor
- Win11怎么开启空间音效_Windows11耳机
- Python对象比较与排序_魔术方法解析【教程】
- 如何在Golang中配置代码格式化工具_使用gof
- 如何在Golang中写入JSON文件_保存结构体数
- php打包exe如何加密代码_防反编译保护方法【技
- Bpmn 2.0的XML文件怎么画流程图
- 如何在 Pandas 中按元素交集合并两列字符串
- C++如何获取CPU核心数?(std::threa
- Win11怎么关闭VBS安全性_Windows11
- Windows10系统怎么查看运行时间_Win10
- c++中explicit(bool)的用法 c++
- WindowsUSB驱动安装异常怎么办_USB驱动
- Win11怎么更改电脑名称_Windows 11修
- 如何使用Golang理解结构体指针方法接收者_Go
- Python类装饰器使用_元编程解析【教程】

this仅用于实例上下文,::用于静态或父类成员访问;混用会触发Fatal error;self::静态绑定,static::后期静态绑定,$this->动态绑定。
QQ客服