FileUrl.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. * @return mixed|null
  29. * @throws Exception
  30. */
  31. public function getFileUrl($tmpPath, $filename, $mimeType) {
  32. // 控制频率
  33. $objLock = new Lock('file_upload', 300, 50);
  34. $objLock->lock(User::getUserId());
  35. if (!file_exists($tmpPath)) {
  36. throw new Exception('file not exists', CODE_PARAM_ERROR);
  37. }
  38. $md5 = md5_file($tmpPath);
  39. $row = $this->objTable->getRow(['id' => $md5]);
  40. if ($row) {
  41. return self::_fixUrl($row['url']);
  42. }
  43. $ext = pathinfo($filename, PATHINFO_EXTENSION);
  44. $type = self::getType($mimeType);
  45. $filename = self::getFileName($md5, $tmpPath, $type, $ext);
  46. $url = self::s3PutObject($tmpPath, $filename, $mimeType);
  47. if ($url) {
  48. $this->objTable->addObject([
  49. 'id' => $md5,
  50. 'url' => $url,
  51. 'type' => $type,
  52. ]);
  53. }
  54. return $url;
  55. }
  56. private static function getFileName($md5, $path, $type, $ext = '') {
  57. $str = '';
  58. $len = filesize($path);
  59. if ($type == self::TYPE_IMAGE) {
  60. $arr = getimagesize($path);
  61. $str = sprintf('%s_%s_%s', $md5, "size{$arr[0]}x{$arr[1]}", "len{$len}");
  62. } else {
  63. $str = sprintf('%s_%s', $md5, "len{$len}");
  64. }
  65. $ext && $str .= ".{$ext}";
  66. return $str;
  67. }
  68. /**
  69. * 获取类型
  70. * @author solu
  71. * @param $mineType
  72. * @return int
  73. */
  74. public static function getType($mineType) {
  75. if (false !== strpos($mineType, 'image')) {
  76. return self::TYPE_IMAGE;
  77. } elseif (false !== strpos($mineType, 'video')) {
  78. return self::TYPE_VIDEO;
  79. } elseif (false !== strpos($mineType, 'audio')) {
  80. return self::TYPE_AUDIO;
  81. }
  82. return self::TYPE_OTHER;
  83. }
  84. /**
  85. * 上传文件
  86. * @author solu
  87. * @param $path
  88. * @param $name
  89. * @return string
  90. * @throws Exception
  91. */
  92. private static function s3PutObject($path, $name, $mime) {
  93. $s3 = new S3Client([
  94. 'version' => 'latest',
  95. 'region' => 'ap-northeast-1',
  96. 'scheme' => 'http',
  97. 'credentials' => [
  98. 'key' => AWS_ACCESS_KEY,
  99. 'secret' => AWS_SECRET_KEY,
  100. ],
  101. ]);
  102. $result = $s3->putObject([
  103. 'Bucket' => BUCKET_MEE,
  104. 'Key' => $name,
  105. 'CacheControl' => 'max-age=8640000', // 前端缓存100天
  106. 'Body' => fopen($path, 'r'),
  107. 'ACL' => 'public-read',
  108. 'ContentType' => $mime,
  109. ]);
  110. $url = $result->get('ObjectURL');
  111. if (!$url) {
  112. throw new Exception('upload to s3 error', CODE_NORMAL_ERROR);
  113. }
  114. return self::_fixUrl($url);
  115. }
  116. /**
  117. * 转换url
  118. * @author solu
  119. * @param $url
  120. * @return string
  121. */
  122. private static function _fixUrl($url) {
  123. if (strpos($url, CDN_HOST) === false) {
  124. $pos = strrpos($url, '/') + 1;
  125. $path = substr($url, $pos);
  126. return sprintf('https://%s/%s', CDN_HOST, $path);
  127. }
  128. return $url;
  129. }
  130. }