class.wsdlcache.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. /*
  3. The NuSOAP project home is:
  4. http://sourceforge.net/projects/nusoap/
  5. The primary support for NuSOAP is the mailing list:
  6. nusoap-general@lists.sourceforge.net
  7. */
  8. /**
  9. * caches instances of the wsdl class
  10. *
  11. * @author Scott Nichol <snichol@users.sourceforge.net>
  12. * @author Ingo Fischer <ingo@apollon.de>
  13. * @version $Id: class.wsdlcache.php,v 1.7 2007/04/17 16:34:03 snichol Exp $
  14. * @access public
  15. */
  16. class nusoap_wsdlcache {
  17. /**
  18. * @var resource
  19. * @access private
  20. */
  21. var $fplock;
  22. /**
  23. * @var integer
  24. * @access private
  25. */
  26. var $cache_lifetime;
  27. /**
  28. * @var string
  29. * @access private
  30. */
  31. var $cache_dir;
  32. /**
  33. * @var string
  34. * @access public
  35. */
  36. var $debug_str = '';
  37. /**
  38. * constructor
  39. *
  40. * @param string $cache_dir directory for cache-files
  41. * @param integer $cache_lifetime lifetime for caching-files in seconds or 0 for unlimited
  42. * @access public
  43. */
  44. function nusoap_wsdlcache($cache_dir='.', $cache_lifetime=0) {
  45. $this->fplock = array();
  46. $this->cache_dir = $cache_dir != '' ? $cache_dir : '.';
  47. $this->cache_lifetime = $cache_lifetime;
  48. }
  49. /**
  50. * creates the filename used to cache a wsdl instance
  51. *
  52. * @param string $wsdl The URL of the wsdl instance
  53. * @return string The filename used to cache the instance
  54. * @access private
  55. */
  56. function createFilename($wsdl) {
  57. return $this->cache_dir.'/wsdlcache-' . md5($wsdl);
  58. }
  59. /**
  60. * adds debug data to the class level debug string
  61. *
  62. * @param string $string debug data
  63. * @access private
  64. */
  65. function debug($string){
  66. $this->debug_str .= get_class($this).": $string\n";
  67. }
  68. /**
  69. * gets a wsdl instance from the cache
  70. *
  71. * @param string $wsdl The URL of the wsdl instance
  72. * @return object wsdl The cached wsdl instance, null if the instance is not in the cache
  73. * @access public
  74. */
  75. function get($wsdl) {
  76. $filename = $this->createFilename($wsdl);
  77. if ($this->obtainMutex($filename, "r")) {
  78. // check for expired WSDL that must be removed from the cache
  79. if ($this->cache_lifetime > 0) {
  80. if (file_exists($filename) && (time() - filemtime($filename) > $this->cache_lifetime)) {
  81. unlink($filename);
  82. $this->debug("Expired $wsdl ($filename) from cache");
  83. $this->releaseMutex($filename);
  84. return null;
  85. }
  86. }
  87. // see what there is to return
  88. if (!file_exists($filename)) {
  89. $this->debug("$wsdl ($filename) not in cache (1)");
  90. $this->releaseMutex($filename);
  91. return null;
  92. }
  93. $fp = @fopen($filename, "r");
  94. if ($fp) {
  95. $s = implode("", @file($filename));
  96. fclose($fp);
  97. $this->debug("Got $wsdl ($filename) from cache");
  98. } else {
  99. $s = null;
  100. $this->debug("$wsdl ($filename) not in cache (2)");
  101. }
  102. $this->releaseMutex($filename);
  103. return (!is_null($s)) ? unserialize($s) : null;
  104. } else {
  105. $this->debug("Unable to obtain mutex for $filename in get");
  106. }
  107. return null;
  108. }
  109. /**
  110. * obtains the local mutex
  111. *
  112. * @param string $filename The Filename of the Cache to lock
  113. * @param string $mode The open-mode ("r" or "w") or the file - affects lock-mode
  114. * @return boolean Lock successfully obtained ?!
  115. * @access private
  116. */
  117. function obtainMutex($filename, $mode) {
  118. if (isset($this->fplock[md5($filename)])) {
  119. $this->debug("Lock for $filename already exists");
  120. return false;
  121. }
  122. $this->fplock[md5($filename)] = fopen($filename.".lock", "w");
  123. if ($mode == "r") {
  124. return flock($this->fplock[md5($filename)], LOCK_SH);
  125. } else {
  126. return flock($this->fplock[md5($filename)], LOCK_EX);
  127. }
  128. }
  129. /**
  130. * adds a wsdl instance to the cache
  131. *
  132. * @param object wsdl $wsdl_instance The wsdl instance to add
  133. * @return boolean WSDL successfully cached
  134. * @access public
  135. */
  136. function put($wsdl_instance) {
  137. $filename = $this->createFilename($wsdl_instance->wsdl);
  138. $s = serialize($wsdl_instance);
  139. if ($this->obtainMutex($filename, "w")) {
  140. $fp = fopen($filename, "w");
  141. if (! $fp) {
  142. $this->debug("Cannot write $wsdl_instance->wsdl ($filename) in cache");
  143. $this->releaseMutex($filename);
  144. return false;
  145. }
  146. fputs($fp, $s);
  147. fclose($fp);
  148. $this->debug("Put $wsdl_instance->wsdl ($filename) in cache");
  149. $this->releaseMutex($filename);
  150. return true;
  151. } else {
  152. $this->debug("Unable to obtain mutex for $filename in put");
  153. }
  154. return false;
  155. }
  156. /**
  157. * releases the local mutex
  158. *
  159. * @param string $filename The Filename of the Cache to lock
  160. * @return boolean Lock successfully released
  161. * @access private
  162. */
  163. function releaseMutex($filename) {
  164. $ret = flock($this->fplock[md5($filename)], LOCK_UN);
  165. fclose($this->fplock[md5($filename)]);
  166. unset($this->fplock[md5($filename)]);
  167. if (! $ret) {
  168. $this->debug("Not able to release lock for $filename");
  169. }
  170. return $ret;
  171. }
  172. /**
  173. * removes a wsdl instance from the cache
  174. *
  175. * @param string $wsdl The URL of the wsdl instance
  176. * @return boolean Whether there was an instance to remove
  177. * @access public
  178. */
  179. function remove($wsdl) {
  180. $filename = $this->createFilename($wsdl);
  181. if (!file_exists($filename)) {
  182. $this->debug("$wsdl ($filename) not in cache to be removed");
  183. return false;
  184. }
  185. // ignore errors obtaining mutex
  186. $this->obtainMutex($filename, "w");
  187. $ret = unlink($filename);
  188. $this->debug("Removed ($ret) $wsdl ($filename) from cache");
  189. $this->releaseMutex($filename);
  190. return $ret;
  191. }
  192. }
  193. /**
  194. * For backward compatibility
  195. */
  196. class wsdlcache extends nusoap_wsdlcache {
  197. }
  198. ?>