PHP 7.1+ 中类属性必须显式声明访问修饰符,省略会直接报语法错误;所谓“默认 public”是历史误解,源于 PHP 5.x 的旧规则和 const 语法的误迁移。

PHP 7.1 中,类属性若省略访问修饰符(public/protected/private),其默认访问级别为 public。这不是运行时推断或语法糖,而是由 Zend 引擎在编译阶段强制执行的语义规则。
默认 public 是语法层面的硬性规定
PHP 解析器在词法与语法分析阶段就要求:所有类属性声明必须显式或隐式携带可见性。当开发者写:
class User {
$name; // ❌ 语法错误!PHP 7.1+ 不允许省略修饰符
}这会直接触发 Parse error: syntax error, unexpected '$name'。
也就是说,“省略修饰符”在 PHP 7.1+ 已不合法——它根本不会走到底层 zval 或对象模型阶段,更不存在“默认处理”的底层机制。
真正的底层机制只作用于合法声明
只有符合语法的属性定义(如 public $name;)才会进入编译流程,并最终影响 zend_object 的内存布局:
-
public属性被存入对象的propertieshashtable,键名为"name",值为 zval; -
protected属性键名被重写为"\0*\0name",用于运行时可见性校验; -
private属性键名被重写为"\0User\0name",实现类级隔离;
这些键名变形由 Zend 引擎在初始化对象时完成,是访问控制的底层基础。
立即学习“PHP免费学习笔记(深入)”;
为什么会有“默认 public”的误解?
该说法实际源于两个历史上下文:
- PHP 5.0–5.6 允许省略修饰符,此时确实按
public处理(但已被废弃); - 类常量(
const FOO = 1;)至今仍无需修饰符,且始终是public—— 这个例外常被误迁移到属性上。
正确写法与建议
class User {
public $name; // 显式声明,清晰可靠
protected $email;
private $password;
}- ✅ 始终显式写出修饰符,避免兼容性陷阱和 IDE 误判;
- ❌ 不要依赖“默认”,PHP 7.1+ 已移除该语法支持;
- ?
var $x;是 PHP 4 遗留语法,等价于public $x;,但自 PHP 7.4 起已废弃,PHP 8.0+ 完全移除。
不复杂但容易忽略。



















