FileLock.php 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Jenner
  5. * Date: 2015/8/21
  6. * Time: 14:30
  7. */
  8. namespace Jenner\SimpleFork\Lock;
  9. /**
  10. * file lock
  11. *
  12. * @package Jenner\SimpleFork\Lock
  13. */
  14. class FileLock implements LockInterface
  15. {
  16. /**
  17. * @var string lock file
  18. */
  19. protected $file;
  20. /**
  21. * @var resource
  22. */
  23. protected $fp;
  24. /**
  25. * @var bool
  26. */
  27. protected $locked = false;
  28. /**
  29. * @param $file
  30. */
  31. private function __construct($file)
  32. {
  33. if (!file_exists($file) || !is_readable($file)) {
  34. throw new \RuntimeException("{$file} is not exists or not readable");
  35. }
  36. $this->fp = fopen($file, "r+");
  37. if (!is_resource($this->fp)) {
  38. throw new \RuntimeException("open {$file} failed");
  39. }
  40. }
  41. /**
  42. * create a file lock instance
  43. * if the file is not exists, it will be created
  44. *
  45. * @param string $file lock file
  46. * @return FileLock
  47. */
  48. public static function create($file)
  49. {
  50. return new FileLock($file);
  51. }
  52. /**
  53. * get a lock
  54. *
  55. * @param bool $blocking
  56. * @return mixed
  57. */
  58. public function acquire($blocking = true)
  59. {
  60. if ($this->locked) {
  61. throw new \RuntimeException('already lock by yourself');
  62. }
  63. if ($blocking) {
  64. $locked = flock($this->fp, LOCK_EX);
  65. } else {
  66. $locked = flock($this->fp, LOCK_EX | LOCK_NB);
  67. }
  68. if ($locked !== true) {
  69. return false;
  70. }
  71. $this->locked = true;
  72. return true;
  73. }
  74. /**
  75. * is locked
  76. *
  77. * @return mixed
  78. */
  79. public function isLocked()
  80. {
  81. return $this->locked === true ? true : false;
  82. }
  83. /**
  84. *
  85. */
  86. public function __destory()
  87. {
  88. if ($this->locked) {
  89. $this->release();
  90. }
  91. }
  92. /**
  93. * release lock
  94. *
  95. * @return mixed
  96. */
  97. public function release()
  98. {
  99. if (!$this->locked) {
  100. throw new \RuntimeException('release a non lock');
  101. }
  102. $unlock = flock($this->fp, LOCK_UN);
  103. fclose($this->fp);
  104. if ($unlock !== true) {
  105. return false;
  106. }
  107. $this->locked = false;
  108. return true;
  109. }
  110. }