设为首页 收藏本站
查看: 1017|回复: 0

[经验分享] FastDFS php API

[复制链接]

尚未签到

发表于 2015-8-24 13:19:42 | 显示全部楼层 |阅读模式
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->tracker);
342             }
343         }
344
345         /**
346          * From: sphinxapi.php
347          */
348         public static function packU64($v) {
349
350
351             assert(is_numeric($v));
352
353             // x64
354             if (PHP_INT_SIZE >= 8) {
355                 assert($v >= 0);
356
357                 // x64, int
358                 if (is_int($v))
359                     return pack("NN", $v >> 32, $v & 0xFFFFFFFF);
360
361                 // x64, bcmath
362                 if (function_exists("bcmul")) {
363                     $h = bcdiv($v, 4294967296, 0);
364                     $l = bcmod($v, 4294967296);
365                     return pack("NN", $h, $l);
366                 }
367
368                 // x64, no-bcmath
369                 $p = max(0, strlen($v) - 13);
370                 $lo = (int) substr($v, $p);
371                 $hi = (int) substr($v, 0, $p);
372
373                 $m = $lo + $hi * 1316134912;
374                 $l = $m % 4294967296;
375                 $h = $hi * 2328 + (int) ($m / 4294967296);
376
377                 return pack("NN", $h, $l);
378             }
379
380             // x32, int
381             if (is_int($v))
382                 return pack("NN", 0, $v);
383
384             // x32, bcmath
385             if (function_exists("bcmul")) {
386                 $h = bcdiv($v, "4294967296", 0);
387                 $l = bcmod($v, "4294967296");
388                 return pack("NN", (float) $h, (float) $l); // conversion to float is intentional; int would lose 31st bit
389             }
390
391             // x32, no-bcmath
392             $p = max(0, strlen($v) - 13);
393             $lo = (float) substr($v, $p);
394             $hi = (float) substr($v, 0, $p);
395
396             $m = $lo + $hi * 1316134912.0;
397             $q = floor($m / 4294967296.0);
398             $l = $m - ($q * 4294967296.0);
399             $h = $hi * 2328.0 + $q;
400
401             return pack("NN", $h, $l);
402         }
403
404     }
405
406     abstract class FastDFSBase {
407
408         abstract public function getSocket();
409
410         abstract public function close();
411
412         public function read($length, $socket = null) {
413             if (!$socket) {
414                 $socket = $this->getSocket();
415             }
416
417             if (feof($socket)) {
418                 throw new FastDFS_Exception('connection unexpectedly closed (timed out?)', $this->_errno);
419             }
420
421             $data = stream_get_contents($socket, $length);
422
423             assert($length === strlen($data));
424
425             return $data;
426         }
427
428         public function send($data, $length = 0, $socket = null) {
429             if (!$socket) {
430                 $socket = $this->getSocket();
431             }
432
433             if (!$length) {
434                 $length = strlen($data);
435             }
436
437             if (feof($socket) || fwrite($socket, $data, $length) !== $length) {
438                 throw new Exception('connection unexpectedly closed (timed out?)');
439             }
440
441             return true;
442         }
443
444     }
445
446     class FastDFSTrackerClient extends FastDFSBase {
447
448         private $host;
449         private $port;
450
451         /**
452          *
453          * @var FastDFS
454          */
455         private $dfs;
456         private $_socket;
457
458         public function __construct(FastDFS &$dfs, $host, $port) {
459             $this->host = $host;
460             $this->port = $port;
461             $this->dfs = $dfs;
462
463             $this->_socket = @fsockopen("tcp://$host", $port, $errno, $errstr, $this->dfs->gConfig['connect_timeout']);
464             if (!$this->_socket) {
465                 $this->dfs->add_error(-2, $errstr);
466             }
467         }
468
469         public function getSocket() {
470             return $this->_socket;
471         }
472
473         public function close() {
474             fclose($this->_socket);
475         }
476
477     }
478
479     class FastDFSStorageClient extends FastDFSBase {
480
481         private $groupName;
482
483         /**
484          *
485          * @var FastDFSTrackerClient
486          */
487         private $tracker;
488
489         /**
490          *
491          * @var FastDFS
492          */
493         private $dfs;
494         private $_socket;
495         private $host;
496         private $port;
497         private $storeIndex;
498
499         public function __construct(FastDFS &$dfs, $groupName, FastDFSTrackerClient $tracker) {
500             $this->tracker = $tracker;
501             $this->dfs = $dfs;
502
503             $reqBody = '';
504             if ($groupName) {
505                 $cmd = FDFS_QUERY_STORE_WITH_GROUP_ONE;
506                 $len = FDFS_GROUP_NAME_MAX_LEN;
507                 $reqBody = FastDFS::padding($groupName, $len);
508             } else {
509                 $cmd = FDFS_QUERY_STORE_WITHOUT_GROUP_ONE;
510                 $len = 0;
511             }
512             $reqHeader = FastDFS::packHeader($cmd, $len);
513             $this->tracker->send($reqHeader . $reqBody);
514
515             $resHeader = $this->tracker->read(FDFS_HEADER_LENGTH);
516             $resInfo = FastDFS::parseHeader($resHeader);
517
518             if ($resInfo['status'] != 0) {
519                 throw new Exception("something wrong with get storage by group name", $resInfo['status']);
520             }
521
522             $resBody = !!$resInfo['length'] ? $this->tracker->read($resInfo['length']) : '';
523             $this->groupName = trim(substr($resBody, 0, FDFS_GROUP_NAME_MAX_LEN));
524             $this->host = trim(substr($resBody, FDFS_GROUP_NAME_MAX_LEN, FDFS_IP_ADDRESS_SIZE + 1));
525
526             list(,, $this->port) = unpack('N2', substr($resBody, FDFS_GROUP_NAME_MAX_LEN + FDFS_IP_ADDRESS_SIZE - 1, FDFS_PROTO_PKG_LEN_SIZE));
527
528             $this->storeIndex = ord(substr($resBody, -1));
529
530             $this->_socket = @fsockopen($this->host, $this->port, $errno, $errstr, $this->dfs->gConfig['connect_timeout']);
531
532             if (!$this->_socket) {
533                 $this->dfs->add_error($errno, $errstr);
534             }
535         }
536
537         public function getSocket() {
538             return $this->_socket;
539         }
540
541         public function getStorePathIndex() {
542             return $this->storeIndex;
543         }
544
545         public function uploadByFilename($localFile, $extName, $metas) {
546             if (!file_exists($localFile)) {
547                 throw new FastDFSException("$localFile file is not exists");
548             }
549             $pathInfo = pathinfo($localFile);
550
551             $extName = $extName ? $extName : $pathInfo['extension'];
552             $extLen = strlen($extName);
553
554             if ($extLen > FDFS_FILE_EXT_NAME_MAX_LEN) {
555                 throw new FastDFSException("file ext too long");
556             }
557             $fp = fopen($localFile, 'rb');
558             flock($fp, LOCK_SH);
559             $fileSize = filesize($localFile);
560
561             $reqBodyLen = 1 + FDFS_PROTO_PKG_LEN_SIZE + FDFS_FILE_EXT_NAME_MAX_LEN + $fileSize;
562             $reqHeader = FastDFS::packHeader(11, $reqBodyLen);
563             $reqBody = pack('C', $this->getStorePathIndex()) . FastDFS::packU64($fileSize) . FastDFS::padding($extName, FDFS_FILE_EXT_NAME_MAX_LEN);
564
565             $this->send($reqHeader . $reqBody);
566
567             stream_copy_to_stream($fp, $this->_socket, $fileSize);
568             flock($fp, LOCK_UN);
569             fclose($fp);
570
571             $resHeader = $this->read(FDFS_HEADER_LENGTH);
572             $resInfo = FastDFS::parseHeader($resHeader);
573
574             if ($resInfo['status'] !== 0) {
575                 return false;
576             }
577             $resBody = $resInfo['length'] ? $this->read($resInfo['length']) : '';
578             $groupName = trim(substr($resBody, 0, FDFS_GROUP_NAME_MAX_LEN));
579
580             $filePath = trim(substr($resBody, FDFS_GROUP_NAME_MAX_LEN));
581
582             if ($metas) {
583                 $this->setFileMetaData($groupName, $filePath, $metas);
584             }
585
586             return array(
587                 'group_name' => $groupName,
588                 'filename' => $filePath
589             );
590         }
591
592         /**
593          *
594          * @param type $fileName
595          * @param type $groupName
596          * @param type $masterfile
597          * @param type $prefix
598          * @param type $extName
599          * @param type $metas
600          * @return boolean
601          * @throws FastDFSException
602          */
603         public function uploadSalveFile($fileName, $groupName, $masterfile, $prefix = '', $extName = '', $metas = array()) {
604             if (!file_exists($fileName)) {
605                 throw new FastDFSException("salve file $fileName is not exists");
606             }
607
608             $pathInfo = pathinfo($fileName);
609
610             $extName = $extName ? $extName : $pathInfo['extension'];
611             $extLen = strlen($extName);
612
613             if ($extLen > FDFS_FILE_EXT_NAME_MAX_LEN) {
614                 throw new FastDFSException("salve file ext too long");
615             }
616             $fp = fopen($fileName, 'rb');
617             flock($fp, LOCK_SH);
618
619             $fileSize = filesize($fileName);
620             $masterFilePathLen = strlen($masterfile);
621
622             $reqBodyLength = 16 + FDFS_FILE_PREFIX_MAX_LEN + FDFS_FILE_EXT_NAME_MAX_LEN + $masterFilePathLen + $fileSize;
623             $reqHeader = FastDFS::packHeader(FDFS_PROTO_CMD_UPLOAD_SLAVE_FILE, $reqBodyLength);
624
625             $reqBody = pack('x4N', $masterFilePathLen) . FastDFS::packU64($fileSize) . FastDFS::padding($prefix, FDFS_FILE_PREFIX_MAX_LEN);
626             $reqBody .= FastDFS::padding($extName, FDFS_FILE_EXT_NAME_MAX_LEN) . $masterfile;
627
628             $this->send($reqHeader . $reqBody);
629
630             stream_copy_to_stream($fp, $this->_socket, $fileSize);
631             flock($fp, LOCK_UN);
632             fclose($fp);
633
634             $resHeader = $this->read(FDFS_HEADER_LENGTH);
635             $resInfo = FastDFS::parseHeader($resHeader);
636
637             if ($resInfo['status'] !== 0) {
638                 return false;
639             }
640             $resBody = $resInfo['length'] ? $this->read($resInfo['length']) : '';
641             $groupName = trim(substr($resBody, 0, FDFS_GROUP_NAME_MAX_LEN));
642
643             $filePath = trim(substr($resBody, FDFS_GROUP_NAME_MAX_LEN));
644
645             if ($metas) {
646                 $this->setFileMetaData($groupName, $filePath, $metas);
647             }
648
649             return array(
650                 'group_name' => $groupName,
651                 'filename' => $filePath
652             );
653         }
654
655         public function deleteFile($groupName, $fileName) {
656             $reqBodyLen = strlen($fileName) + FDFS_GROUP_NAME_MAX_LEN;
657             $reqHeader = FastDFS::packHeader(FDFS_PROTO_CMD_DELETE_FILE, $reqBodyLen);
658             $reqBody = FastDFS::padding($groupName, FDFS_GROUP_NAME_MAX_LEN) . $fileName;
659
660             $this->send($reqHeader . $reqBody);
661
662             $resHeader = $this->read(FDFS_HEADER_LENGTH);
663             $resInfo = FastDFS::parseHeader($resHeader);
664
665             return !$resInfo['status'];
666         }
667
668         public function fileExists($groupName, $filePath) {
669             $meta = $this->getFileMeta($groupName, $filePath);
670
671             return $meta ? true : false;
672         }
673
674         public function setFileMetaData($groupName, $filePath, array $metaData, $flag = FDFS_OVERWRITE_METADATA) {
675
676             $metaData = FastDFS::packMetaData($metaData);
677             $metaDataLength = strlen($metaData);
678             $filePathLength = strlen($filePath);
679             $flag = $flag === FDFS_OVERWRITE_METADATA ? 'O' : 'M';
680
681             $reqBodyLength = (FDFS_PROTO_PKG_LEN_SIZE * 2) + 1 + $metaDataLength + $filePathLength + FDFS_GROUP_NAME_MAX_LEN;
682
683             $reqHeader = FastDFS::packHeader(FDFS_PROTO_CMD_SET_METADATA, $reqBodyLength);
684
685             $reqBody = FastDFS::packU64($filePathLength) . FastDFS::packU64($metaDataLength);
686             $reqBody .= $flag . FastDFS::padding($groupName, FDFS_GROUP_NAME_MAX_LEN) . $filePath . $metaData;
687
688             $this->send($reqHeader . $reqBody);
689
690             $resHeader = $this->read(FDFS_HEADER_LENGTH);
691             $resInfo = FastDFS::parseHeader($resHeader);
692
693             return !$resInfo['status'];
694         }
695
696         /**
697          * 取得文件的元信息,如果文件不存在则,返回false,反正是一个关联数组
698          *
699          * @param type $groupName
700          * @param type $filePath
701          * @return boolean
702          */
703         public function getFileMeta($groupName, $filePath) {
704             $reqBodyLength = strlen($filePath) + FDFS_GROUP_NAME_MAX_LEN;
705             $reqHeader = FastDFS::packHeader(FDFS_PROTO_CMD_GET_METADATA, $reqBodyLength);
706             $reqBody = FastDFS::padding($groupName, FDFS_GROUP_NAME_MAX_LEN) . $filePath;
707
708             $this->send($reqHeader . $reqBody);
709
710             $resHeader = $this->read(FDFS_HEADER_LENGTH);
711             $resInfo = FastDFS::parseHeader($resHeader);
712
713             if (!!$resInfo['status']) {
714                 return false;
715             }
716
717             $resBody = $resInfo['length'] ? $this->read($resInfo['length']) : false;
718
719             return FastDFS::parseMetaData($resBody);
720         }
721
722         public function close() {
723             fclose($this->_socket);
724         }
725
726     }
727
728     class FastDFSException extends Exception {
729         
730     }
731
732 }
  上面是api基类:
  下面是调用方式:



1 /**
2      * FastDFS上传文件
3      * @param unknown $fileurl 上传文件
4      * @param unknown $sizes 附属文件
5      * @return string
6      */
7     private function applydfs($fileurl,$sizes=array()){ 9         $dfs=new FastDFS();
10         $tracker = $dfs->tracker_get_connection();
11         $location = "";
12         if($dfs->active_test($tracker)){
13             $storaged = $dfs->tracker_query_storage_store("group1",$tracker);
14             if(!empty($sizes)){
15                 $count = 0;
16                 $filename = $dfs->storage_upload_by_filename($fileurl);
17                 if(isset($filename['group_name'])&&isset($filename['filename'])){
18                     $location =$filename['group_name']."/".$filename['filename'];
19                 }
20                 foreach($sizes as $key=>$val){
21                     $snapshot_file_info =$dfs->storage_upload_slave_by_filename($val,"group1",$filename['filename'],$key);
22                     if($snapshot_file_info){
23                         $count++;
24                     }
25                 }
26                 if($count <> count($sizes)){
27                     $location = "";
28                 }
29             }else{
30                 $filename = $dfs->storage_upload_by_filename($fileurl);
31                 if(isset($filename['group_name'])&&isset($filename['filename'])){
32                     $location =$filename['group_name']."/".$filename['filename'];
33                 }
34             }
35         }
36         return $location;
37     }
  在php.ini中配置:



1 [fastdfs]
2 ; the base path
3 fastdfs_client.base_path = /tmp
4
5 ; connect timeout in seconds
6 ; default value is 30s
7 fastdfs_client.connect_timeout = 2
8
9 ; network timeout in seconds
10 ; default value is 30s
11 fastdfs_client.network_timeout = 60
12
13 ; standard log level as syslog, case insensitive, value list:
14 ;;; emerg for emergency
15 ;;; alert
16 ;;; crit for critical
17 ;;; error
18 ;;; warn for warning
19 ;;; notice
20 ;;; info
21 ;;; debug
22 fastdfs_client.log_level = info
23
24 ; set the log filename, such as /usr/local/fastdfs/logs/fastdfs_client.log
25 ; empty for output to stderr
26 fastdfs_client.log_filename = /tmp/fastdfs_client.log
27
28 ; secret key to generate anti-steal token
29 ; this parameter must be set when http.anti_steal.check_token set to true
30 ; the length of the secret key should not exceed 128 bytes
31 fastdfs_client.http.anti_steal_secret_key =
32
33 ; FastDFS cluster count, default value is 1
34 fastdfs_client.tracker_group_count = 1
35
36 ; config file of FastDFS cluster ;, based 0
37 ; must include absolute path, such as fastdfs_client.tracker_group0
38 ; the config file is same as conf/client.conf
39 ; 这是你fastdfs的tracker的配置文件的路径,必须使用绝对路径,请换成你自己的路径,附件是我们开发环境和测试环境的client.conf配置
40 ; 测试环境已经配置过,你自己的开发环境需要配置一下
41 fastdfs_client.tracker_group0 = "E:/wamp/bin/php/php5.3.13/client.conf"
42
43 ; if use connection pool
44 ; default value is false
45 ; since V4.05
46 fastdfs_client.use_connection_pool = false
47
48 ; connections whose the idle time exceeds this time will be closed
49 ; unit: second
50 ; default value is 3600
51 ; since V4.05
52 fastdfs_client.connection_pool_max_idle_time = 3600
53
54 ; the base path
55 fastdfs_client.base_path = /tmp
56
57 ; connect timeout in seconds
58 ; default value is 30s
59 fastdfs_client.connect_timeout = 2
60
61 ; network timeout in seconds
62 ; default value is 30s
63 fastdfs_client.network_timeout = 60
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-103523-1-1.html 上篇帖子: FastDFS和apache/nginx整合 下篇帖子: 分布式文件存储fastdfs
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表