APCの挙動

phpAPCを最近良く使います。

使い方はカンタンで、

<?php
if ($data = apc_fetch('data')) {
  $data = getData(); // なんか処理
  apc_store('data', $data);
}

本当にカンタンでPHPのオブジェクトもそのまま入ります。

しかし、

<?php
$objects = array();
foreach (range(10, 30, 10) as $i) {
  $params = array();
  foreach (array('a', 'b', 'c',) as $p) $params[$p] = ++$i;
  $objects[] = new Test($params);
}

var_dump($objects);

apc_store('tests', $objects);
apc_store('tests_0', $objects[0]);

$data = apc_fetch('tests');
$data_0 = apc_fetch('tests_0');

var_dump($data);
var_dump($data_0);

class Test
{
  public    $a;
  private   $b;
  protected $c;

  public function __construct($array)
  {
    foreach (array('a', 'b', 'c',) as $p) {
      if (isset($array[$p])) $this->{$p} = $array[$p];
    }
  }
}

結果

array(3) {
  [0]=>
  object(Test)#1 (3) {
    ["a"]=>
    int(11)
    ["b:private"]=>
    int(12)
    ["c:protected"]=>
    int(13)
  }
  [1]=>
  object(Test)#2 (3) {
    ["a"]=>
    int(21)
    ["b:private"]=>
    int(22)
    ["c:protected"]=>
    int(23)
  }
  [2]=>
  object(Test)#3 (3) {
    ["a"]=>
    int(31)
    ["b:private"]=>
    int(32)
    ["c:protected"]=>
    int(33)
  }
}
array(3) {
  [0]=>
  NULL
  [1]=>
  NULL
  [2]=>
  NULL
}
object(Test)#4 (3) {
  ["a"]=>
  int(11)
  ["b:private"]=>
  int(12)
  ["c:protected"]=>
  int(13)
}

え、、、?

てっきり内部でserializeしているのかとおもったら、serializeとは挙動がちがっておりまして、
配列の要素のオブジェクトは消えてしまうようです。


というわけで,memcacheを同じで、下記の用にしてあげないと行けないみたい

<?php
if ($data = apc_fetch('data')) {
  $data = serialize(getData()); // なんか処理
  apc_store('data', $data);
}
return unserialize($data);