• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

FastDFSphpAPI

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
  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->
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap