在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1 <?php 2 3 if (!class_exists('FastDFS', false)) { 4 define('FDFS_PROTO_PKG_LEN_SIZE', 8); 5 define('FDFS_PROTO_CMD_ACTIVE_TEST', 111); 6 define('FDFS_PROTO_CMD_RESP', 100); 7 define('FDFS_PROTO_CMD_UPLOAD_SLAVE_FILE', 21); 8 define('FDFS_PROTO_CMD_DELETE_FILE', 12); 9 define('FDFS_PROTO_CMD_GET_METADATA', 15); 10 define('FDFS_PROTO_CMD_SET_METADATA', 13); 11 12 //body_length + command + status 13 define('FDFS_HEADER_LENGTH', 10); 14 define('FDFS_IP_ADDRESS_SIZE', 16); 15 define('FDFS_FILE_EXT_NAME_MAX_LEN', 6); 16 define('FDFS_GROUP_NAME_MAX_LEN', 16); 17 define('FDFS_OVERWRITE_METADATA', 1); 18 define('FDFS_MERGE_METADATA', 2); 19 20 // 连接超时时间 21 define('FDFS_CONNECT_TIME_OUT', 5); 22 define('FDFS_FILE_PREFIX_MAX_LEN', 16); 23 24 //传输超时时间 25 define('FDFS_TRANSFER_TIME_OUT', 0); 26 define('FDFS_QUERY_STORE_WITHOUT_GROUP_ONE', 101); 27 define('FDFS_QUERY_STORE_WITH_GROUP_ONE', 104); 28 29 define('FDFS_TRACKER_QUERY_STORAGE_STORE_BODY_LEN', FDFS_GROUP_NAME_MAX_LEN + FDFS_IP_ADDRESS_SIZE + FDFS_PROTO_PKG_LEN_SIZE); 30 31 class FastDFS { 32 33 public $gConfig = array(); 34 35 /** 36 * 37 * @var FastDFSTrackerClient 38 */ 39 private $tracker; 40 41 /** 42 * 43 * @var FastDFSStorageClient 44 */ 45 private $storage; 46 private $error = array( 47 'code' => 0, 48 'msg' => '' 49 ); 50 51 /** 52 * 要使用这个类,你一定要在php的ini文件中进行fastdfs的配置 53 * 54 * @throws FastDFSException 55 */ 56 public function __construct() { 57 $configFile = ''; 58 $ini = parse_ini_file(php_ini_loaded_file()); 59 60 if (!isset($ini['fastdfs_client.tracker_group_count'])) { 61 throw new FastDFSException("no define fastdfs config"); 62 } 63 for ($i = 0; $i < $ini['fastdfs_client.tracker_group_count']; $i++) { 64 if (isset($ini['fastdfs_client.tracker_group' . $i])) { 65 $configFile = $ini['fastdfs_client.tracker_group' . $i]; 66 break; 67 } 68 } 69 if (!file_exists($configFile)) { 70 throw new FastDFSException("client config $configFile not found"); 71 } 72 $this->gConfig = parse_ini_file($configFile); 73 list($this->gConfig['tracker_host'], $this->gConfig['tracker_port']) = explode(':', $this->gConfig['tracker_server']); 74 } 75 76 /** 77 * 获得一个tracker 78 * 79 * @return \FastDFSTrackerClient 80 */ 81 public function tracker_get_connection() { 82 $this->tracker = new FastDFSTrackerClient($this, $this->gConfig['tracker_host'], $this->gConfig['tracker_port']); 83 84 return $this->tracker; 85 } 86 87 /** 88 * 通过tracker获取一个stroage 89 * 90 * @param string $groupName 文件组名,当为空时,组名由tracker决定 91 * @param FastDFSTrackerClient $tracker 92 * @return \FastDFSStorageClient 93 */ 94 public function tracker_query_storage_store($groupName, FastDFSTrackerClient $tracker) { 95 $this->storage = new FastDFSStorageClient($this, $groupName, $tracker); 96 97 return $this->storage; 98 } 99 100 /** 101 * 测试一下tracker服务器是否正常 102 * 103 * @param FastDFSTrackerClient $tracker 104 * @return boolean 105 */ 106 public function active_test(FastDFSTrackerClient $tracker = null) { 107 $this->initTrackerAndStorage($tracker); 108 109 $header = self::packHeader(FDFS_PROTO_CMD_ACTIVE_TEST, 0); 110 $tracker->send($header); 111 112 $resHeader = self::parseHeader($tracker->read(FDFS_HEADER_LENGTH)); 113 114 return $resHeader['status'] == 0 ? true : false; 115 } 116 117 public function get_last_error_no() { 118 return $this->error['code']; 119 } 120 121 public function add_error($errorNo, $info) { 122 $this->error['code'] = $errorNo; 123 $this->error['msg'] = $info; 124 } 125 126 public function get_last_error_info() { 127 return $this->error['msg']; 128 } 129 130 /** 131 * 在storage中删除一个文件 132 * 133 * @param string $groupName 文件所在的组名 134 * @param string $remoteFile 要删除的文件路径 135 * @param FastDFSStorageClient $tracker 136 * @param FastDFSStorageClient $storage 137 */ 138 public function storage_delete_file($groupName, $remoteFile, FastDFSStorageClient $tracker, FastDFSStorageClient $storage) { 139 $this->initTrackerAndStorage($tracker, $storage, $groupName); 140 141 $this->storage->deleteFile($groupName, $remoteFile); 142 } 143 144 /** 145 * 往storage中上传一个文件 146 * 147 * @param string $localFile 你本地的文件路径 148 * @param string $extName 文件的扩展名,当名优提供扩展名时,会自动取文件的扩展名 149 * @param array $metas 文件的附加信息 150 * @param string $groupName 所在的组名,可以为空,为空时,由tracker决定 151 * @param FastDFSTrackerClient $tracker 152 * @param FastDFSStorageClient $storage 153 */ 154 public function storage_upload_by_filename($localFile, $extName = '', $metas = array(), $groupName = '', FastDFSTrackerClient $tracker = null, FastDFSStorageClient $storage = null) { 155 $this->initTrackerAndStorage($tracker, $storage, $groupName); 156 157 return $this->storage->uploadByFilename($localFile, $extName, $metas); 158 } 159 160 /** 161 * 上传一个文件的附属文件,主要使用一个图片有缩略图的情况下 162 * 163 * @param string $localFile 本地文件的路径,缩略图的文件路径 164 * @param string $groupName 组名,最好和主文件在同一个组 165 * @param string $masterFileName 主文件名 166 * @param string $prefix 文件的前缀 167 * @param string $extName 文件的后缀,可以为空,为空时,由tracker决定 168 * @param array $meta 附件信息 169 * @param FastDFSTrackerClient $tracker 170 * @param FastDFSStorageClient $storage 171 */ 172 public function storage_upload_slave_by_filename($localFile, $groupName, $masterFileName, $prefix = '', $extName = '', $meta = array(), FastDFSTrackerClient $tracker = null, FastDFSStorageClient $storage = null) { 173 $this->initTrackerAndStorage($tracker, $storage, $groupName); 174 /*echo $localFile."<br/>".$groupName."<br/>".$masterFileName."<br/>".$prefix; 175 exit;*/ 176 return $this->storage->uploadSalveFile($localFile, $groupName, $masterFileName, $prefix, $extName, $meta); 177 } 178 179 /** 180 * 检查这个文件是否已经存在 181 * 182 * @param string $groupName 文件所在组名 183 * @param string $remoteFile 文件在storage中的名字 184 * @param FastDFSStorageClient $tracker 185 * @param FastDFSStorageClient $storage 186 */ 187 public function storage_file_exist($groupName, $remoteFile, FastDFSTrackerClient $tracker, FastDFSStorageClient $storage) { 188 $this->initTrackerAndStorage($tracker, $storage, $groupName); 189 190 return $this->storage->fileExists($groupName, $remoteFile); 191 } 192 193 public function close() { 194 if ($this->tracker) { 195 $this->tracker->close(); 196 $this->tracker = null; 197 } 198 } 199 200 public function tracker_close_all_connections() { 201 $this->close(); 202 if (!$this->storage) { 203 $this->storage->close(); 204 } 205 } 206 207 public static function padding($str, $len) { 208 209 $str_len = strlen($str); 210 211 return $str_len > $len ? substr($str, 0, $len) : $str . pack('x' . ($len - $str_len)); 212 } 213 214 /** 215 * 216 * @param int $command 217 * @param int $length 218 * @return bytes 219 */ 220 public static function packHeader($command, $length = 0) { 221 return self::packU64($length) . pack('Cx', $command); 222 } 223 224 public static function packMetaData($data) { 225 $S1 = "\x01"; 226 $S2 = "\x02"; 227 228 $list = array(); 229 foreach ($data as $key => $val) { 230 $list[] = $key . $S2 . $val; 231 }; 232 233 return implode($S1, $list); 234 } 235 236 public static function parseMetaData($data) { 237 238 $S1 = "\x01"; 239 $S2 = "\x02"; 240 241 $arr = explode($S1, $data); 242 $result = array(); 243 244 foreach ($arr as $val) { 245 list($k, $v) = explode($S2, $val); 246 $result[$k] = $v; 247 } 248 249 return $result; 250 } 251 252 public static function parseHeader($str, $len = FDFS_HEADER_LENGTH) { 253 254 assert(strlen($str) === $len); 255 256 $result = unpack('C10', $str); 257 258 $length = self::unpackU64(substr($str, 0, 8)); 259 $command = $result[9]; 260 $status = $result[10]; 261 262 return array( 263 'length' => $length, 264 'command' => $command, 265 'status' => $status 266 ); 267 } 268 269 /** 270 * From: sphinxapi.php 271 */ 272 private static function unpackU64($v) { 273 list ( $hi, $lo ) = array_values(unpack("N*N*", $v)); 274 275 if (PHP_INT_SIZE >= 8) { 276 if ($hi < 0) 277 $hi += (1 << 32); // because php 5.2.2 to 5.2.5 is totally fucked up again 278 if ($lo < 0) 279 $lo += (1 << 32); 280 281 // x64, int 282 if ($hi <= 2147483647) 283 return ($hi << 32) + $lo; 284 285 // x64, bcmath 286 if (function_exists("bcmul")) 287 return bcadd($lo, bcmul($hi, "4294967296")); 288 289 // x64, no-bcmath 290 $C = 100000; 291 $h = ((int) ($hi / $C) << 32) + (int) ($lo / $C); 292 $l = (($hi % $C) << 32) + ($lo % $C); 293 if ($l > $C) { 294 $h += (int) ($l / $C); 295 $l = $l % $C; 296 } 297 298 if ($h == 0) 299 return $l; 300 return sprintf("%d%05d", $h, $l); 301 } 302 303 // x32, int 304 if ($hi == 0) { 305 if ($lo > 0) 306 return $lo; 307 return sprintf("%u", $lo); 308 } 309 310 $hi = sprintf("%u", $hi); 311 $lo = sprintf("%u", $lo); 312 313 // x32, bcmath 314 if (function_exists("bcmul")) 315 return bcadd($lo, bcmul($hi, "4294967296")); 316 317 // x32, no-bcmath 318 $hi = (float) $hi; 319 $lo = (float) $lo; 320 321 $q = floor($hi / 10000000.0); 322 $r = $hi - $q * 10000000.0; 323 $m = $lo + $r * 4967296.0; 324 $mq = floor($m / 10000000.0); 325 $l = $m - $mq * 10000000.0; 326 $h = $q * 4294967296.0 + $r * 429.0 + $mq; 327 328 $h = sprintf("%.0f", $h); 329 $l = sprintf("%07.0f", $l); 330 if ($h == "0") 331 return sprintf("%.0f", (float) $l); 332 return $h . $l; 333 } 334 335 private function initTrackerAndStorage(FastDFSTrackerClient $tracker = null, FastDFSStorageClient $storage = null, $groupName = '') { 336 $reNewStorage = false; 337 if ($tracker && $tracker !== $this->tracker) { 338 $this->tracker_get_connection(); 339 } 340 if (($storage && $storage !== $this->storage) || $reNewStorage) { 341 $this->tracker_query_storage_store($groupName, $this-> |
2022-08-18
2022-08-17
2022-11-06
2022-08-17
2022-07-18
请发表评论