When storing an object via apcu_store() where the class defines __serialize() but not __unserialize(), the object returned by apcu_fetch() is corrupted: it contains both a private property slot (with the default value) and a dynamic public property (with the actual value) under the same name simultaneously. This state is impossible to achieve through normal PHP code.
Environment:
PHP version: 8.4.18
APCu version: 5.1.28
igbinary version: 3.2.16
OS: Linux Ubuntu
APCu config:
apc.entries_hint = 100000
apc.slam_defense = On
apc.gc_ttl = 600
apc.serializer = igbinary
apc.shm_size = 128M
apc.ttl = 3600
Code for reproducing:
<?php
class Foo
{
public function __construct(private string $name = 'default') {}
public function __serialize(): array { return ['name' => $this->name]; }
public function getName(): string { return $this->name; }
// __unserialize() is intentionally undefined
// public function __unserialize(array $data): void { $this->name = $data['name']; }
}
$original = new Foo('actual');
apcu_store('test_key', $original);
$restored = apcu_fetch('test_key');
echo "Original name: " . $original->getName() . PHP_EOL;
echo "Restored name: " . $restored->getName() . PHP_EOL;
$arr = (array) $restored;
echo PHP_EOL . "Cast to array (raw keys):" . PHP_EOL;
foreach ($arr as $key => $value) {
echo " " . json_encode($key) . " => " . json_encode($value) . PHP_EOL;
}
When apc.serializer = igbinary enabled:

After disabled:

See, two discussions about investigations this bug:
👉 krakjoe/apcu#609
👉 symfony/symfony#63431
When storing an object via apcu_store() where the class defines __serialize() but not __unserialize(), the object returned by apcu_fetch() is corrupted: it contains both a private property slot (with the default value) and a dynamic public property (with the actual value) under the same name simultaneously. This state is impossible to achieve through normal PHP code.
Environment:
PHP version: 8.4.18
APCu version: 5.1.28
igbinary version: 3.2.16
OS: Linux Ubuntu
APCu config:
apc.entries_hint = 100000
apc.slam_defense = On
apc.gc_ttl = 600
apc.serializer = igbinary
apc.shm_size = 128M
apc.ttl = 3600
Code for reproducing:
When

apc.serializer = igbinaryenabled:After disabled:

See, two discussions about investigations this bug:
👉 krakjoe/apcu#609
👉 symfony/symfony#63431