HttpRequestMultipartBody.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: xiaozhuai
  5. * Date: 17/4/23
  6. * Time: 下午2:14
  7. */
  8. namespace loyalsoft\Util;
  9. class HttpRequestMultipartBody
  10. {
  11. /**
  12. * 类型,键值对
  13. */
  14. const TYPE_KV = 0;
  15. /**
  16. * 类型,文件
  17. */
  18. const TYPE_FILE = 1;
  19. /**
  20. * 列表
  21. * @var array
  22. */
  23. private $list = array();
  24. /**
  25. * 边界字符串
  26. * @var string
  27. */
  28. private $boundary;
  29. /**
  30. * 添加键值对
  31. * @param string $key
  32. * @param string $value
  33. */
  34. public function add($key, $value)
  35. {
  36. $this->list[] = array(
  37. 'type' => static::TYPE_KV,
  38. 'key' => $key,
  39. 'value' => $value,
  40. );
  41. }
  42. /**
  43. * 添加文件
  44. * @param string $key
  45. * @param string $file 文件路径
  46. * @param string $fileName 文件名
  47. */
  48. public function addFile($key, $file, $fileName)
  49. {
  50. $this->list[] = array(
  51. 'type' => static::TYPE_FILE,
  52. 'key' => $key,
  53. 'file' => $file,
  54. 'file_name' => $fileName
  55. );
  56. }
  57. /**
  58. * 移除键值
  59. * @param string $key
  60. * @return void
  61. */
  62. public function remove($key)
  63. {
  64. $count = count($this->list);
  65. for ($i = 0; $i < $count; $i++) {
  66. if ($this->list[$i]['key'] === $key) {
  67. array_splice($this->list, $i, 1);
  68. }
  69. }
  70. }
  71. /**
  72. * 清除所有键值
  73. * @return void
  74. */
  75. public function clear()
  76. {
  77. $this->list = array();
  78. }
  79. /**
  80. * 获取最终构建的body内容
  81. * @return string
  82. */
  83. public function content()
  84. {
  85. $this->generateBoundary();
  86. $content = '';
  87. foreach ($this->list as $item) {
  88. switch ($item['type']) {
  89. case static::TYPE_KV :
  90. default :
  91. $content .= sprintf("--%s\r\n", $this->boundary);
  92. $content .= sprintf("Content-Disposition: form-data; name=\"%s\"\r\n\r\n", $item['key']);
  93. $content .= $item['value'] . "\r\n";
  94. break;
  95. case static::TYPE_FILE :
  96. $content .= sprintf("--%s\r\n", $this->boundary);
  97. $content .= sprintf("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n", $item['key'], $item['file_name']);
  98. $content .= sprintf("Content-Type: application/octet-stream\r\n\r\n");
  99. $content .= file_get_contents($item['file']) . "\r\n";
  100. break;
  101. }
  102. }
  103. $content .= sprintf("--%s--\r\n\r\n", $this->boundary);
  104. return $content;
  105. }
  106. /**
  107. * 随机生成一个新的boundary
  108. */
  109. private function generateBoundary()
  110. {
  111. $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  112. $randStr = '';
  113. $max = strlen($chars) - 1;
  114. for ($i = 0; $i < 64; $i++) {
  115. $randStr .= $chars[mt_rand(0, $max)];
  116. }
  117. $this->boundary = '__BOUNDARY__' . $randStr . '__BOUNDARY__';
  118. }
  119. /**
  120. * 获取边界字符串
  121. * @return string
  122. */
  123. public function getBoundary()
  124. {
  125. return $this->boundary;
  126. }
  127. }