is_array()和is_object()判断结果完全不同:前者仅对原生数组返回true,后者仅对对象返回true;ArrayObject是纯对象,不兼容数组函数;选型应依语义与性能需求而定。

is_array() 和 is_object() 的判断结果完全不同
这是最直接、最不可绕过的区别。PHP 中 array 是原生类型,object 是对象类型,两者在类型系统里完全隔离:
-
is_array($arr)对数组返回 true,对任何对象(包括ArrayObject、stdClass、自定义类实例)都返回 false -
is_object($obj)对对象返回 true,对数组返回 false - 哪怕你用
(object) ['name' => 'jack']强转,得到的仍是对象,is_array()依然为 false
很多内置函数(比如 sort()、array_merge()、count() 默认行为)只认 array,传入对象会直接报 Warning:Warning: sort() expects parameter 1 to be array, object given。
访问语法和键名语义差异明显
数组用方括号 [],对象用箭头 ->,这不是风格问题,而是底层结构决定的:
- 数组支持整数索引(
$arr[0])、字符串键($arr['name']),甚至混合($arr[0]['id']);它本质是哈希表,键可以是 int 或 string,值任意 - 对象属性名必须是合法标识符(不能是数字字符串如
'123',也不能含空格或特殊字符),且区分大小写;$obj->name和$obj->{'user name'}写法不同,后者需用花括号 - 关联数组的键是“数据的一部分”,而对象属性是“结构定义的一部分”——这影响 JSON 编码:
json_encode(['foo' => 'bar'])输出{"foo":"bar"},而json_encode((object)['foo' => 'bar'])输出一样,但若键非法(如123),数组能存,对象会丢或报错
ArrayObject 不是 object 和 array 的混合体,它只是个对象
别被名字误导。ArrayObject 是一个实现了 ArrayAccess、Traversable、Countable 等接口的**纯对象**:
立即学习“PHP免费学习笔记(深入)”;
- 它支持
$ao['key'] = 'val'和foreach ($ao as $v),但这只是接口提供的“语法糖”,底层仍是方法调用(offsetSet()、getIterator()) -
is_array($ao)→ false,is_object($ao)→ true,gettype($ao)→ "object" - 它不兼容数组函数:
array_keys($ao)会失败;但可以用$ao->getArrayCopy()拿到真数组再操作 - 它可被继承、可加方法、可序列化保留类信息——这些是普通数组做不到的
性能、内存和实际选型建议
如果你只是存取数据,没额外逻辑,优先用 array:
- 原生数组更快,内存更省,函数生态完整(
array_filter、array_column等) -
object(尤其是stdClass)适合表示“有固定结构的实体”,比如从数据库查出一行后映射为对象:$user = (object)['id' => 1, 'name' => 'Alice'],后续用$user->name更符合语义 - 需要动态扩展 + 方法封装 + 迭代控制时,才考虑
ArrayObject或自定义类;不要为了“看起来像数组”而用它 - 注意
json_decode($json, false)返回对象,true才返回数组——这个布尔参数常被忽略,导致后续访问方式出错
真正容易被忽略的是:数组的键可以是任意字符串(包括 '0'、' '、'foo-bar'),而对象属性名受限于 PHP 变量命名规则;一旦你拿到的数据键名不合规,强行转对象就会丢失或报 Notice。



















