class.wsdlcache.php 5.2 KB

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