sfFunctionCache.class.php 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * This class can be used to cache the result and output of any PHP callable (function and method calls).
  11. *
  12. * @package symfony
  13. * @subpackage cache
  14. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  15. * @version SVN: $Id: sfFunctionCache.class.php 9084 2008-05-20 01:29:54Z Carl.Vondrick $
  16. */
  17. class sfFunctionCache
  18. {
  19. protected $cache = null;
  20. /**
  21. * Constructor.
  22. *
  23. * @param sfCache $cache An sfCache object instance
  24. */
  25. public function __construct($cache)
  26. {
  27. if (!is_object($cache))
  28. {
  29. $this->cache = new sfFileCache($cache);
  30. throw new sfException('DEPRECATED: You must now pass a sfCache object when initializing a sfFunctionCache object. Be warned that the call() method signature has also changed.');
  31. }
  32. $this->cache = $cache;
  33. }
  34. /**
  35. * Calls a cacheable function or method (or not if there is already a cache for it).
  36. *
  37. * Arguments of this method are read with func_get_args. So it doesn't appear in the function definition.
  38. *
  39. * The first argument can be any PHP callable:
  40. *
  41. * $cache->call('functionName', array($arg1, $arg2));
  42. * $cache->call(array($object, 'methodName'), array($arg1, $arg2));
  43. *
  44. * @param mixed $callable A PHP callable
  45. * @param array $arguments An array of arguments to pass to the callable
  46. *
  47. * @return mixed The result of the function/method
  48. */
  49. public function call($callable, $arguments = array())
  50. {
  51. // Generate a cache id
  52. $key = md5(serialize($callable).serialize($arguments));
  53. $serialized = $this->cache->get($key);
  54. if ($serialized !== null)
  55. {
  56. $data = unserialize($serialized);
  57. }
  58. else
  59. {
  60. $data = array();
  61. if (!is_callable($callable))
  62. {
  63. throw new sfException('The first argument to call() must be a valid callable.');
  64. }
  65. ob_start();
  66. ob_implicit_flush(false);
  67. try
  68. {
  69. $data['result'] = call_user_func_array($callable, $arguments);
  70. }
  71. catch (Exception $e)
  72. {
  73. ob_end_clean();
  74. throw $e;
  75. }
  76. $data['output'] = ob_get_clean();
  77. $this->cache->set($key, serialize($data));
  78. }
  79. echo $data['output'];
  80. return $data['result'];
  81. }
  82. }