FileUrl.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <?php
  2. /**
  3. * 文件地址
  4. * @author solu
  5. */
  6. use Aws\S3\S3Client;
  7. class FileUrl extends Model {
  8. protected $tableName = 'file_url';
  9. protected $dbKey = 'dw_chat';
  10. const TMP_DIR = '/tmp/mee';
  11. const TYPE_OTHER = 0; // 其他
  12. const TYPE_IMAGE = 1; // 图片
  13. const TYPE_VIDEO = 2; // 视频
  14. const TYPE_AUDIO = 3; // 音频
  15. private static $arrType = [
  16. self::TYPE_OTHER => '其他',
  17. self::TYPE_IMAGE => '图片',
  18. self::TYPE_VIDEO => '视频',
  19. self::TYPE_AUDIO => '音频',
  20. ];
  21. public static function getAllType() {
  22. return self::$arrType;
  23. }
  24. /**
  25. * @param $tmpPath
  26. * @param $filename
  27. * @param $mimeType
  28. * @param $forever
  29. * @return mixed|null
  30. * @throws Exception
  31. */
  32. public function getFileUrl($tmpPath, $filename, $mimeType, $forever = false) {
  33. // 控制频率
  34. $objLock = new Lock('file_upload', 300, 50);
  35. $uid = User::getUserId();
  36. $objLock->lock($uid);
  37. if (!file_exists($tmpPath)) {
  38. throw new Exception('file not exists', CODE_PARAM_ERROR);
  39. }
  40. $md5 = md5_file($tmpPath);
  41. $row = $this->objTable->getRow(['id' => $md5]);
  42. if ($row['forever'] || (strtotime($row['update_time'])+20*86400 > time())) {
  43. return $row['url'];
  44. }
  45. $ext = pathinfo($filename, PATHINFO_EXTENSION);
  46. $type = self::getType($mimeType);
  47. $filename = self::getFileName($md5, $tmpPath, $type, $ext);
  48. $url = self::s3PutObject($tmpPath, $filename, $mimeType, $forever);
  49. if ($url) {
  50. $this->objTable->replaceObject([
  51. 'id' => $md5,
  52. 'url' => $url,
  53. 'type' => $type,
  54. 'update_time' => date('Y-m-d H:i:s'),
  55. 'forever' => $forever ? 1 : 0,
  56. ]);
  57. }
  58. $objLock->unlock($uid);
  59. return $url;
  60. }
  61. private static function getFileName($md5, $path, $type, $ext = '') {
  62. $len = filesize($path);
  63. if ($type == self::TYPE_IMAGE) {
  64. $arr = getimagesize($path);
  65. $str = sprintf('%s_%s_%s', $md5, "size{$arr[0]}x{$arr[1]}", "len{$len}");
  66. } else {
  67. $str = sprintf('%s_%s', $md5, "len{$len}");
  68. }
  69. $ext && $str .= ".{$ext}";
  70. return $str;
  71. }
  72. /**
  73. * 获取类型
  74. * @author solu
  75. * @param $mineType
  76. * @return int
  77. */
  78. public static function getType($mineType) {
  79. if (false !== strpos($mineType, 'image')) {
  80. return self::TYPE_IMAGE;
  81. } elseif (false !== strpos($mineType, 'video')) {
  82. return self::TYPE_VIDEO;
  83. } elseif (false !== strpos($mineType, 'audio')) {
  84. return self::TYPE_AUDIO;
  85. }
  86. return self::TYPE_OTHER;
  87. }
  88. /**
  89. * 上传文件
  90. * @author solu
  91. * @param $path
  92. * @param $name
  93. * @param $mime
  94. * @param $forever
  95. * @return string
  96. * @throws Exception
  97. */
  98. private static function s3PutObject($path, $name, $mime, $forever = false) {
  99. $s3 = new S3Client([
  100. 'version' => 'latest',
  101. 'region' => 'ap-northeast-1',
  102. 'scheme' => 'http',
  103. 'credentials' => [
  104. 'key' => AWS_ACCESS_KEY,
  105. 'secret' => AWS_SECRET_KEY,
  106. ],
  107. ]);
  108. $bucket = $forever ? BUCKET_MEE : BUCKET_MEE_TMP;
  109. $option = [
  110. 'Bucket' => $bucket,
  111. 'Key' => $name,
  112. 'CacheControl' => 'max-age=8640000', // 前端缓存100天
  113. 'Body' => fopen($path, 'r'),
  114. 'ACL' => 'public-read',
  115. 'ContentType' => $mime,
  116. ];
  117. $result = $s3->putObject($option);
  118. $url = $result->get('ObjectURL');
  119. if (!$url) {
  120. throw new Exception('upload to s3 error', CODE_NORMAL_ERROR);
  121. }
  122. return self::_fixUrl($url, $forever);
  123. }
  124. /**
  125. * 转换url
  126. * @author solu
  127. * @param $url
  128. * @param $forever
  129. * @return string
  130. */
  131. private static function _fixUrl($url, $forever = false) {
  132. $cdn = $forever ? CDN_HOST : CDN_HOST_TMP;
  133. if (strpos($url, $cdn) === false) {
  134. $pos = strrpos($url, '/') + 1;
  135. $path = substr($url, $pos);
  136. return sprintf('https://%s/%s', $cdn, $path);
  137. }
  138. return $url;
  139. }
  140. }