Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Cosapi often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Cosapi, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
7 | class Cosapi |
||
8 | { |
||
9 | //计算sign签名的时间参数 |
||
10 | const EXPIRED_SECONDS = 180; |
||
11 | //1M |
||
12 | const SLICE_SIZE_1M = 1048576; |
||
13 | //20M 大于20M的文件需要进行分片传输 |
||
14 | const MAX_UNSLICE_FILE_SIZE = 20971520; |
||
15 | //失败尝试次数 |
||
16 | const MAX_RETRY_TIMES = 3; |
||
17 | |||
18 | //HTTP请求超时时间 |
||
19 | private static $timeout = 60; |
||
20 | private static $region = 'gz'; // default region is guangzou |
||
21 | |||
22 | /** |
||
23 | * 设置HTTP请求超时时间. |
||
24 | * |
||
25 | * @param int $timeout 超时时长 |
||
26 | * |
||
27 | * @return bool |
||
28 | */ |
||
29 | public static function setTimeout($timeout = 60) |
||
39 | |||
40 | public static function setRegion($region) |
||
44 | |||
45 | /** |
||
46 | * 上传文件,自动判断文件大小,如果小于20M则使用普通文件上传,大于20M则使用分片上传. |
||
47 | * |
||
48 | * @param string $bucket bucket名称 |
||
49 | * @param string $srcPath 本地文件路径 |
||
50 | * @param string $dstPath 上传的文件路径 |
||
51 | * @param string $bizAttr 文件属性 |
||
52 | * @param string $sliceSize 分片大小(512k,1m,2m,3m),默认:1m |
||
53 | * @param string $insertOnly 同名文件是否覆盖 |
||
54 | * |
||
55 | * @return array |
||
56 | */ |
||
57 | 2 | public static function upload($bucket, $srcPath, $dstPath, $bizAttr = null, $sliceSize = null, $insertOnly = null) |
|
78 | |||
79 | /** |
||
80 | * 创建目录. |
||
81 | * |
||
82 | * @param string $bucket bucket名称 |
||
83 | * @param string $folder 目录路径 |
||
84 | * @param string $bizAttr 目录属性 |
||
85 | * |
||
86 | * @return array |
||
87 | */ |
||
88 | 1 | public static function createFolder($bucket, $folder, $bizAttr = null) |
|
89 | { |
||
90 | 1 | if (!self::isValidPath($folder)) { |
|
91 | return [ |
||
92 | 'code' => ErrorCode::COSAPI_PARAMS_ERROR, |
||
93 | 'message' => 'folder '.$folder.' is not a valid folder name', |
||
94 | 'data' => [], |
||
95 | ]; |
||
96 | } |
||
97 | |||
98 | 1 | $folder = self::normalizerPath($folder, true); |
|
99 | 1 | $folder = self::cosUrlEncode($folder); |
|
100 | 1 | $expired = time() + self::EXPIRED_SECONDS; |
|
101 | 1 | $url = self::generateResUrl($bucket, $folder); |
|
102 | 1 | $signature = Auth::createReusableSignature($expired, $bucket); |
|
103 | |||
104 | $data = [ |
||
105 | 1 | 'op' => 'create', |
|
106 | 1 | 'biz_attr' => (isset($bizAttr) ? $bizAttr : ''), |
|
107 | 1 | ]; |
|
108 | |||
109 | 1 | $data = json_encode($data); |
|
110 | |||
111 | $req = [ |
||
112 | 1 | 'url' => $url, |
|
113 | 1 | 'method' => 'post', |
|
114 | 1 | 'timeout' => self::$timeout, |
|
115 | 1 | 'data' => $data, |
|
116 | 'header' => [ |
||
117 | 1 | 'Authorization: '.$signature, |
|
118 | 1 | 'Content-Type: application/json', |
|
119 | 1 | ], |
|
120 | 1 | ]; |
|
121 | |||
122 | 1 | return self::sendRequest($req); |
|
123 | } |
||
124 | |||
125 | /** |
||
126 | * 目录列表. |
||
127 | * |
||
128 | * @param string $bucket bucket名称 |
||
129 | * @param string $folder 目录路径,sdk会补齐末尾的 '/' |
||
130 | * @param int $num 拉取的总数 |
||
131 | * @param string $pattern eListBoth,ListDirOnly,eListFileOnly 默认both |
||
132 | * @param int $order 默认正序(=0), 填1为反序, |
||
133 | * @param string $context 透传字段,用于翻页,前端不需理解,需要往前/往后翻页则透传回来 |
||
134 | * |
||
135 | * @return array |
||
136 | */ |
||
137 | 1 | public static function listFolder($bucket, $folder, $num = 20, $pattern = 'eListBoth', $order = 0, $context = null) |
|
143 | |||
144 | /** |
||
145 | * 目录列表(前缀搜索). |
||
146 | * |
||
147 | * @param string $bucket bucket名称 |
||
148 | * @param string $prefix 列出含此前缀的所有文件 |
||
149 | * @param int $num 拉取的总数 |
||
150 | * @param string $pattern eListBoth(默认),ListDirOnly,eListFileOnly |
||
151 | * @param int $order 默认正序(=0), 填1为反序, |
||
152 | * @param string $context 透传字段,用于翻页,前端不需理解,需要往前/往后翻页则透传回来 |
||
153 | * |
||
154 | * @return array |
||
155 | */ |
||
156 | public static function prefixSearch($bucket, $prefix, $num = 20, $pattern = 'eListBoth', $order = 0, $context = null) |
||
162 | |||
163 | /** |
||
164 | * 目录更新. |
||
165 | * |
||
166 | * @param string $bucket bucket名称 |
||
167 | * @param string $folder 文件夹路径,SDK会补齐末尾的 '/' |
||
168 | * @param string $bizAttr 目录属性 |
||
169 | * |
||
170 | * @return array |
||
171 | */ |
||
172 | public static function updateFolder($bucket, $folder, $bizAttr = null) |
||
178 | |||
179 | /** |
||
180 | * 查询目录信息. |
||
181 | * |
||
182 | * @param string $bucket bucket名称 |
||
183 | * @param string $folder 目录路径 |
||
184 | * |
||
185 | * @return array |
||
186 | */ |
||
187 | public static function statFolder($bucket, $folder) |
||
193 | |||
194 | /** |
||
195 | * 删除目录. |
||
196 | * |
||
197 | * @param string $bucket bucket名称 |
||
198 | * @param string $folder 目录路径 |
||
199 | * 注意不能删除bucket下根目录/ |
||
200 | * |
||
201 | * @return array |
||
202 | */ |
||
203 | 1 | View Code Duplication | public static function delFolder($bucket, $folder) |
215 | |||
216 | /** |
||
217 | * 更新文件. |
||
218 | * |
||
219 | * @param string $bucket bucket名称 |
||
220 | * @param string $path 文件路径 |
||
221 | * @param null $bizAttr |
||
222 | * @param string $authority eInvalid(继承Bucket的读写权限)/eWRPrivate(私有读写)/eWPrivateRPublic(公有读私有写) |
||
223 | * @param array $customer_headers_array 携带的用户自定义头域,包括 |
||
224 | * 'Cache-Control' => '*' |
||
225 | * 'Content-Type' => '*' |
||
226 | * 'Content-Disposition' => '*' |
||
227 | * 'Content-Language' => '*' |
||
228 | * 'x-cos-meta-自定义内容' => '*' |
||
229 | * |
||
230 | * @return array |
||
231 | */ |
||
232 | 1 | public static function update($bucket, $path, $bizAttr = null, $authority = null, $customer_headers_array = null) |
|
238 | |||
239 | /** |
||
240 | * 查询文件信息. |
||
241 | * |
||
242 | * @param string $bucket bucket名称 |
||
243 | * @param string $path 文件路径 |
||
244 | * |
||
245 | * @return array |
||
246 | */ |
||
247 | 6 | public static function stat($bucket, $path) |
|
253 | |||
254 | /** |
||
255 | * 删除文件. |
||
256 | * |
||
257 | * @param string $bucket |
||
258 | * @param string $path 文件路径 |
||
259 | * |
||
260 | * @return array |
||
261 | */ |
||
262 | 1 | View Code Duplication | public static function delFile($bucket, $path) |
274 | |||
275 | /** |
||
276 | * 内部方法, 上传文件. |
||
277 | * |
||
278 | * @param string $bucket bucket名称 |
||
279 | * @param string $srcPath 本地文件路径 |
||
280 | * @param string $dstPath 上传的文件路径 |
||
281 | * @param string $bizAttr 文件属性 |
||
282 | * @param int $insertOnly 是否覆盖同名文件:0 覆盖,1:不覆盖 |
||
283 | * |
||
284 | * @return array |
||
285 | */ |
||
286 | 2 | private static function uploadFile($bucket, $srcPath, $dstPath, $bizAttr = null, $insertOnly = null) |
|
328 | |||
329 | /** |
||
330 | * 内部方法,上传文件. |
||
331 | * |
||
332 | * @param string $bucket bucket名称 |
||
333 | * @param string $srcFpath 本地文件路径 |
||
334 | * @param string $dstFpath 上传的文件路径 |
||
335 | * @param string $bizAttr 文件属性 |
||
336 | * @param string $sliceSize 分片大小 |
||
337 | * @param int $insertOnly 是否覆盖同名文件:0 覆盖,1:不覆盖 |
||
338 | * |
||
339 | * @return array |
||
340 | */ |
||
341 | private static function uploadBySlicing($bucket, $srcFpath, $dstFpath, $bizAttr = null, $sliceSize = null, $insertOnly = null) |
||
410 | |||
411 | /** |
||
412 | * 内部公共函数. |
||
413 | * |
||
414 | * @param string $bucket bucket名称 |
||
415 | * @param string $path 文件夹路径 |
||
416 | * @param int $num 拉取的总数 |
||
417 | * @param string $pattern eListBoth(默认),ListDirOnly,eListFileOnly |
||
418 | * @param int $order 默认正序(=0), 填1为反序, |
||
419 | * @param string $context 在翻页查询时候用到 |
||
420 | * |
||
421 | * @return array |
||
422 | */ |
||
423 | 1 | private static function listBase($bucket, $path, $num = 20, $pattern = 'eListBoth', $order = 0, $context = null) |
|
475 | |||
476 | /** |
||
477 | * 内部公共方法(更新文件和更新文件夹). |
||
478 | * |
||
479 | * @param string $bucket bucket名称 |
||
480 | * @param string $path 路径 |
||
481 | * @param string $bizAttr 文件/目录属性 |
||
482 | * @param string $authority eInvalid/eWRPrivate(私有)/eWPrivateRPublic(公有读写) |
||
483 | * @param array $custom_headers_array 携带的用户自定义头域,包括 |
||
484 | * 'Cache-Control' => '*' |
||
485 | * 'Content-Type' => '*' |
||
486 | * 'Content-Disposition' => '*' |
||
487 | * 'Content-Language' => '*' |
||
488 | * 'x-cos-meta-自定义内容' => '*' |
||
489 | * |
||
490 | * @return array |
||
491 | */ |
||
492 | 1 | private static function updateBase( |
|
536 | |||
537 | /** |
||
538 | * 内部方法. |
||
539 | * |
||
540 | * @param string $bucket bucket名称 |
||
541 | * @param string $path 文件/目录路径 |
||
542 | * |
||
543 | * @return array |
||
544 | */ |
||
545 | 6 | private static function statBase($bucket, $path) |
|
567 | |||
568 | /** |
||
569 | * 内部私有方法. |
||
570 | * |
||
571 | * @param string $bucket bucket名称 |
||
572 | * @param string $path 文件/目录路径路径 |
||
573 | * |
||
574 | * @return array |
||
575 | */ |
||
576 | 2 | private static function delBase($bucket, $path) |
|
607 | |||
608 | /** |
||
609 | * 内部公共方法, 路径编码 |
||
610 | * |
||
611 | * @param string $path 待编码路径 |
||
612 | * |
||
613 | * @return string |
||
614 | */ |
||
615 | 13 | private static function cosUrlEncode($path) |
|
619 | |||
620 | /** |
||
621 | * 内部公共方法, 构造URL. |
||
622 | * |
||
623 | * @param string $bucket |
||
624 | * @param string $dstPath |
||
625 | * |
||
626 | * @return string |
||
627 | */ |
||
628 | 15 | private static function generateResUrl($bucket, $dstPath) |
|
635 | |||
636 | /** |
||
637 | * 内部公共方法, 发送消息. |
||
638 | * |
||
639 | * @param array $req |
||
640 | * |
||
641 | * @return array |
||
642 | */ |
||
643 | 15 | private static function sendRequest($req) |
|
665 | |||
666 | /** |
||
667 | * Get slice size. |
||
668 | * |
||
669 | * @param string $sliceSize |
||
670 | * |
||
671 | * @return int |
||
672 | */ |
||
673 | private static function getSliceSize($sliceSize) |
||
697 | |||
698 | /** |
||
699 | * 内部方法, 规整文件路径. |
||
700 | * |
||
701 | * @param string $path 文件路径 |
||
702 | * @param bool $isfolder 是否为文件夹 |
||
703 | * |
||
704 | * @return string |
||
705 | */ |
||
706 | 15 | private static function normalizerPath($path, $isfolder = false) |
|
723 | |||
724 | /** |
||
725 | * 判断authority值是否正确. |
||
726 | * |
||
727 | * @param string $authority |
||
728 | * |
||
729 | * @return bool |
||
730 | */ |
||
731 | 1 | private static function isAuthorityValid($authority) |
|
739 | |||
740 | /** |
||
741 | * 判断pattern值是否正确. |
||
742 | * |
||
743 | * @param string $pattern |
||
744 | * |
||
745 | * @return bool |
||
746 | */ |
||
747 | 1 | private static function isPatternValid($pattern) |
|
755 | |||
756 | /** |
||
757 | * 判断是否符合自定义属性. |
||
758 | * |
||
759 | * @param string $key |
||
760 | * |
||
761 | * @return bool |
||
762 | */ |
||
763 | private static function isCustomer_header($key) |
||
775 | |||
776 | /** |
||
777 | * 增加自定义属性到data中. |
||
778 | * |
||
779 | * @param array $data |
||
780 | * @param array $customer_headers_array |
||
781 | */ |
||
782 | private static function add_customer_header(&$data, &$customer_headers_array) |
||
793 | |||
794 | // Check |$path| is a valid file path. |
||
795 | // Return true on success, otherwise return false. |
||
796 | |||
797 | /** |
||
798 | * @param string $path |
||
799 | */ |
||
800 | 1 | private static function isValidPath($path) |
|
829 | |||
830 | /** |
||
831 | * Copy a file. |
||
832 | * |
||
833 | * @param string $bucket bucket name. |
||
834 | * @param string $srcFpath source file path. |
||
835 | * @param string $dstFpath destination file path. |
||
836 | * @param bool $overwrite if the destination location is occupied, overwrite it or not? |
||
837 | * |
||
838 | * @return array|mixed. |
||
839 | */ |
||
840 | 1 | View Code Duplication | public static function copyFile($bucket, $srcFpath, $dstFpath, $overwrite = false) |
864 | |||
865 | /** |
||
866 | * Move a file. |
||
867 | * |
||
868 | * @param string $bucket bucket name. |
||
869 | * @param string $srcFpath source file path. |
||
870 | * @param string $dstFpath destination file path. |
||
871 | * @param bool $overwrite if the destination location is occupied, overwrite it or not? |
||
872 | * |
||
873 | * @return array |
||
874 | */ |
||
875 | 1 | View Code Duplication | public static function moveFile($bucket, $srcFpath, $dstFpath, $overwrite = false) |
899 | } |
||
900 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.