thinkphp和ueditor自定義后台處理方法整合


先了解一下ueditor后台請求參數與返回參數格式規范:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
1. config
 
     請求參數:
     GET { "action" "config" }
     POST  "upfile" : File Data 
 
     返回格式:
     // 需要支持callback參數,返回jsonp格式
     {
         "imageUrl" "http://localhost/ueditor/php/controller.php?action=uploadimage" ,
         "imagePath" "/ueditor/php/" ,
         "imageFieldName" "upfile" ,
         "imageMaxSize" : 2048,
         "imageAllowFiles" : [ ".png" ".jpg" ".jpeg" ".gif" ".bmp" ]
     }
 
2. uploadimage
 
     請求參數:
     GET { "action" "uploadimage" }
     POST  "upfile" : File Data 
     
     返回格式:
     {
         "state" "SUCCESS" ,
         "url" "upload/demo.jpg" ,
         "title" "demo.jpg" ,
         "original" "demo.jpg"
     }
 
3. uploadscrawl
 
     請求參數:
     GET { "action" "uploadscrawl" }
     POST  "content" : Base64 Data 
 
     返回格式:
     {
         "state" "SUCCESS" ,
         "url" "upload/demo.jpg" ,
         "title" "demo.jpg" ,
         "original" "demo.jpg"
     }
 
4. uploadvideo
 
     請求參數:
     GET { "action" "uploadvideo" }
     POST  "upfile" : File Data 
 
     返回格式:
     {
         "state" "SUCCESS" ,
         "url" "upload/demo.mp4" ,
         "title" "demo.mp4" ,
         "original" "demo.mp4"
     }
 
5. uploadfile
 
     請求參數:
     GET { "action" "uploadfile" }
     POST  "upfile" : File Data 
 
     返回格式:
     {
         "state" "SUCCESS" ,
         "url" "upload/demo.zip" ,
         "title" "demo.zip" ,
         "original" "demo.zip"
     }
 
6. listimage
 
     請求參數:
     GET { "action" "listimage" "start" : 0,  "size" : 20} 
 
     返回格式:
     // 需要支持callback參數,返回jsonp格式
     {
         "state" "SUCCESS" ,
         "list" : [{
             "url" "upload/1.jpg"
         }, {
             "url" "upload/2.jpg"
         }, ],
         "start" : 20,
         "total" : 100
     }
 
7. catchimage
 
     請求參數:
     GET {
         "action" "catchimage" ,
          "source" : [
             "http://a.com/1.jpg" ,
             "http://a.com/2.jpg"
         ]
    
 
     返回格式:
     // 需要支持callback參數,返回jsonp格式
     // list項的state屬性和最外面的state格式一致
     {
         "state" "SUCCESS" ,
         "list" : [{
             "url" "upload/1.jpg" ,
             "source" "http://b.com/2.jpg" ,
             "state" "SUCCESS"
         }, {
             "url" "upload/2.jpg" ,
             "source" "http://b.com/2.jpg" ,
             "state" "SUCCESS"
         }, ]
     }

 

 

ueditor后台統一處理方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
<?php
namespace  Home\Controller;
use  Think\Controller;
class  IndexController  extends  Controller {
     
     private  $uid  = 0; //用戶id
     
     /**
     * ueditor上傳后台處理方法
     * @param 
     */
     public  function  UploadSomething(){
         header( "Content-Type: text/html; charset=utf-8" );
         error_reporting (E_ERROR);
         
         // 未登錄狀態
         if ( $this ->uid == 0){
             if ( $_GET [ 'action' ] ==  'config' ){
                 // 讀取並輸出配置文件,用於未登錄狀態editor加載初始化
                 echo  preg_replace( "/\/\*[\s\S]+?\*\//" "" file_get_contents ( "./Public/js/php/config.json" ));
             } else {
                 // 上傳請求時,提示登錄
                 echo  json_encode( array ( 'state' =>  '請登錄!' ));
             }
             exit ;
         }
         
         
         // 登錄狀態
         $CONFIG  = json_decode(preg_replace( "/\/\*[\s\S]+?\*\//" "" file_get_contents ( "./Public/js/php/config.json" )), true);
         $action  $_GET [ 'action' ];
 
         switch  ( $action ){
             case  'config' :
                 $result  =  json_encode( $CONFIG );
                 break ;
             case  'uploadimage' :
             case  'uploadscrawl' :
             case  'uploadvideo' :
             case  'uploadfile' :
                 /**
                  * 上傳圖片或文件處理方法,返回數據格式為json,具體格式如下
                  *
                     return json_encode(
                         array(
                             "state" => "",          //上傳狀態,上傳成功時必須返回"SUCCESS"
                             "url"   => "",            //返回的地址
                             "title" => "",          //新文件名
                             "original" => "",       //原始文件名
                             "type"  => "",          //文件類型
                             "size"  => "",           //文件大小
                         )
                     );
                 */
                 $result  $this ->ueditorUpload( $CONFIG );
                 break ;
                 
                 /** 
                  * 列表操作:返回的數據格式,列出圖片或文件
                     array(
                         "state" => "SUCCESS",       // 成功返回信息
                         "start" => $start,          // 開始位置
                         "total" => count($files),   // 文件個數統計
                         // 當前列出的文件列表
                         "list"  => array(
                             array('url' => '圖片地址','mtime' => '時間戳'),
                             array('url' => '圖片地址','mtime' => '時間戳'),
                         );
                     )
                 */
             // 列出圖片
             case  'listimage' :
                 $result  $this ->ueditorList( $CONFIG );
                 break ;
             // 列出文件
             case  'listfile' :
                 $result  $this ->ueditorList( $CONFIG );
                 break ;
                 
                 /** 
                  * 抓取遠程文件操作:返回的數據格式
                     array(
                         'state' => count($list) ? 'SUCCESS':'ERROR',
                         'list'  => array(
                             array(
                                 "state"     => $info["state"],
                                 "url"       => $info["url"],
                                 "size"      => $info["size"],
                                 "title"     => htmlspecialchars($info["title"]),
                                 "original"  => htmlspecialchars($info["original"]),
                                 "source"    => htmlspecialchars($imgUrl)
                             ),
                             array(
                                 "state"     => $info["state"],
                                 "url"       => $info["url"],
                                 "size"      => $info["size"],
                                 "title"     => htmlspecialchars($info["title"]),
                                 "original"  => htmlspecialchars($info["original"]),
                                 "source"    => htmlspecialchars($imgUrl)
                             )
                         )
                     )
                 */
             // 抓取遠程文件
             case  'catchimage' :
                 $result  $this ->ueditorCrawler( $CONFIG );
                 break ;
             default :
                 $result  = json_encode( array (
                     'state' =>  '請求地址出錯'
                 ));
                 break ;
         }
         
         if (isset( $_GET [ "callback" ])){
             if (preg_match( "/^[\w_]+$/" $_GET [ "callback" ])){
                 echo  htmlspecialchars( $_GET [ "callback" ]) .  '('  $result  ')' ;
             } else {
                 echo  json_encode( array ( 'state' =>  'callback參數不合法' ));
             }
         } else {
             echo  $result ;
         }
     }
     
     
     /**
     * 上傳文件
     * @param json $CONFIG 配置文件
     * @return json {
         "state":"SUCCESS",
         "url":"返回的地址",
         "title":"新文件名",
         "original":"原始文件名",
         "type":"文件類型",
         "size":"文件大小"
     }
     */
     private  function  ueditorUpload( $CONFIG ){
         // 導入上傳類
         Vendor( 'Uploader' , '' , '.class.php' );
         
         $base64  "upload" ;
         switch  (htmlspecialchars( $_GET [ 'action' ])) {
             case  'uploadimage' :
                 $config  array (
                     "pathFormat"  =>  $CONFIG [ 'imagePathFormat' ],
                     "maxSize"  =>  $CONFIG [ 'imageMaxSize' ],
                     "allowFiles"  =>  $CONFIG [ 'imageAllowFiles' ]
                 );
                 $fieldName  $CONFIG [ 'imageFieldName' ];
                 break ;
             case  'uploadscrawl' :
                 $config  array (
                     "pathFormat"  =>  $CONFIG [ 'scrawlPathFormat' ],
                     "maxSize"  =>  $CONFIG [ 'scrawlMaxSize' ],
                     "allowFiles"  =>  $CONFIG [ 'scrawlAllowFiles' ],
                     "oriName"  =>  "scrawl.png"
                 );
                 $fieldName  $CONFIG [ 'scrawlFieldName' ];
                 $base64  "base64" ;
                 break ;
             case  'uploadvideo' :
                 $config  array (
                     "pathFormat"  =>  $CONFIG [ 'videoPathFormat' ],
                     "maxSize"  =>  $CONFIG [ 'videoMaxSize' ],
                     "allowFiles"  =>  $CONFIG [ 'videoAllowFiles' ]
                 );
                 $fieldName  $CONFIG [ 'videoFieldName' ];
                 break ;
             case  'uploadfile' :
             default :
                 $config  array (
                     "pathFormat"  =>  $CONFIG [ 'filePathFormat' ],
                     "maxSize"  =>  $CONFIG [ 'fileMaxSize' ],
                     "allowFiles"  =>  $CONFIG [ 'fileAllowFiles' ]
                 );
                 $fieldName  $CONFIG [ 'fileFieldName' ];
                 break ;
         }
         $up  new  \Uploader( $fieldName $config $base64 , $this ->uid);
         return  json_encode( $up ->getFileInfo());
     }
     
     
     /**
     * 圖片列表
     * @param json $CONFIG 配置文件
     * @return json {
         "state":"SUCCESS",
         "start":"開始位置",
         "total":"文件個數統計",
         "list":[
             {"url":"圖片地址","mtime":"時間戳"},
             {"url":"圖片地址","mtime":"時間戳"}
         ]
     }
     */
     private  function  ueditorList( $CONFIG ){
         switch  ( $_GET [ 'action' ]) {
             /* 列出文件 */
             case  'listfile' :
                 $allowFiles  $CONFIG [ 'fileManagerAllowFiles' ];
                 $listSize  $CONFIG [ 'fileManagerListSize' ];
                 $path  $CONFIG [ 'fileManagerListPath' ];
                 break ;
             /* 列出圖片 */
             case  'listimage' :
             default :
                 $allowFiles  $CONFIG [ 'imageManagerAllowFiles' ];
                 $listSize  $CONFIG [ 'imageManagerListSize' ];
                 $path  $CONFIG [ 'imageManagerListPath' ];
         }
         $allowFiles  substr ( str_replace ( "." "|" , join( "" $allowFiles )), 1);
 
         /* 獲取參數 */
         $size  = isset( $_GET [ 'size' ]) ? htmlspecialchars( $_GET [ 'size' ]) :  $listSize ;
         $start  = isset( $_GET [ 'start' ]) ? htmlspecialchars( $_GET [ 'start' ]) : 0;
         $end  $start  $size ;
 
         /* 獲取文件列表 */
         $path  $_SERVER [ 'DOCUMENT_ROOT' ] . ( substr ( $path , 0, 1) ==  "/"  "" : "/" ) .  $path ;
         $files  = getfiles( $path $allowFiles );
         if  (! count ( $files )){
             return  json_encode( array (
                 "state"  =>  "no match file" ,
                 "list"  =>  array (),
                 "start"  =>  $start ,
                 "total"  =>  count ( $files )
             ));
         }
         /* 獲取指定范圍的列表 */
         $len  count ( $files );
         for  ( $i  = min( $end $len ) - 1,  $list  array ();  $i  $len  &&  $i  >= 0 &&  $i  >=  $start $i --){
             $list [] =  $files [ $i ];
         }
         /* 返回數據 */
         $result  = json_encode( array (
             "state"  =>  "SUCCESS" ,
             "list"  =>  $list ,
             "start"  =>  $start ,
             "total"  =>  count ( $files )
         ));
         return  $result ;
     }
     
     
     /**
     * 抓取圖片
     * @param json $CONFIG 配置文件
     * @return json json_encode(array(
         'state' => count($list) ? 'SUCCESS':'ERROR',
         'list'  => array(
             array(
                 "state"     => $info["state"],
                 "url"       => $info["url"],
                 "size"      => $info["size"],
                 "title"     => htmlspecialchars($info["title"]),
                 "original"  => htmlspecialchars($info["original"]),
                 "source"    => htmlspecialchars($imgUrl)
             ),
             array(
                 "state"     => $info["state"],
                 "url"       => $info["url"],
                 "size"      => $info["size"],
                 "title"     => htmlspecialchars($info["title"]),
                 "original"  => htmlspecialchars($info["original"]),
                 "source"    => htmlspecialchars($imgUrl)
             )
         )
     ));
     */
     private  function  ueditorCrawler( $CONFIG ){
         set_time_limit(0);
         // 導入上傳類
         Vendor( 'Uploader' , '' , '.class.php' );
         
         $config  array (
             "pathFormat"  =>  $CONFIG [ 'catcherPathFormat' ],
             "maxSize"  =>  $CONFIG [ 'catcherMaxSize' ],
             "allowFiles"  =>  $CONFIG [ 'catcherAllowFiles' ],
             "oriName"  =>  "remote.png"
         );
         $fieldName  $CONFIG [ 'catcherFieldName' ];
         $list  array ();
         if  (isset( $_POST [ $fieldName ])) {
             $source  $_POST [ $fieldName ];
         else  {
             $source  $_GET [ $fieldName ];
         }
         foreach  ( $source  as  $imgUrl ) {
             $item  new  \Uploader( $imgUrl $config "remote" , $this ->uid);
             $info  $item ->getFileInfo();
             array_push ( $list array (
                 "state"  =>  $info [ "state" ],
                 "url"  =>  $info [ "url" ],
                 "size"  =>  $info [ "size" ],
                 "title"  => htmlspecialchars( $info [ "title" ]),
                 "original"  => htmlspecialchars( $info [ "original" ]),
                 "source"  => htmlspecialchars( $imgUrl )
             ));
         }
         return  json_encode( array (
             'state' =>  count ( $list ) ?  'SUCCESS' : 'ERROR' ,
             'list' =>  $list
         ));
     }
     
     
     
     
     
     
     
     
     
     
     
}



 

 

要調用的上傳類,放在Think/Library/Vendor目錄下,用Vendor()調用即可。

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
<?php
 
/**
  * Created by JetBrains PhpStorm.
  * User: taoqili
  * Date: 12-7-18
  * Time: 上午11: 32
  * UEditor編輯器通用上傳類
  * 比較原百度的上傳類,此方法在構造方法中加入了一個參數,用於區分文件保存路徑,具體看代碼
  */
class  Uploader
{
     private  $fileField //文件域名
     private  $file //文件上傳對象
     private  $base64 //文件上傳對象
     private  $config //配置信息
     private  $oriName //原始文件名
     private  $fileName //新文件名
     private  $fullName //完整文件名,即從當前配置目錄開始的URL
     private  $filePath //完整文件名,即從當前配置目錄開始的URL
     private  $fileSize //文件大小
     private  $fileType //文件類型
     private  $stateInfo //上傳狀態信息,
     private  $uid ; // 用戶id
     private  $stateMap  array //上傳狀態映射表,國際化用戶需考慮此處數據的國際化
         "SUCCESS" //上傳成功標記,在UEditor中內不可改變,否則flash判斷會出錯
         "文件大小超出 upload_max_filesize 限制" ,
         "文件大小超出 MAX_FILE_SIZE 限制" ,
         "文件未被完整上傳" ,
         "沒有文件被上傳" ,
         "上傳文件為空" ,
         "ERROR_TMP_FILE"  =>  "臨時文件錯誤" ,
         "ERROR_TMP_FILE_NOT_FOUND"  =>  "找不到臨時文件" ,
         "ERROR_SIZE_EXCEED"  =>  "文件大小超出網站限制" ,
         "ERROR_TYPE_NOT_ALLOWED"  =>  "文件類型不允許" ,
         "ERROR_CREATE_DIR"  =>  "目錄創建失敗" ,
         "ERROR_DIR_NOT_WRITEABLE"  =>  "目錄沒有寫權限" ,
         "ERROR_FILE_MOVE"  =>  "文件保存時出錯" ,
         "ERROR_FILE_NOT_FOUND"  =>  "找不到上傳文件" ,
         "ERROR_WRITE_CONTENT"  =>  "寫入文件內容錯誤" ,
         "ERROR_UNKNOWN"  =>  "未知錯誤" ,
         "ERROR_DEAD_LINK"  =>  "鏈接不可用" ,
         "ERROR_HTTP_LINK"  =>  "鏈接不是http鏈接" ,
         "ERROR_HTTP_CONTENTTYPE"  =>  "鏈接contentType不正確" ,
         "INVALID_URL"  =>  "非法 URL" ,
         "INVALID_IP"  =>  "非法 IP"
     );
 
     /**
      * 構造函數
      * @param string $fileField  表單名稱
      * @param array      $config     配置項
      * @param bool       $base64     是否解析base64編碼,可省略。若開啟,則$fileField代表的是base64編碼的字符串表單名
      * @param int        $uid        用戶id,用於區分圖片保存的文件夾
      */
     public  function  __construct( $fileField $config $type  "upload" , $uid )
     {
         $this ->uid =  $uid ; // 在293行使用到
         $this ->fileField =  $fileField ;
         $this ->config =  $config ;
         $this ->type =  $type ;
         if  ( $type  ==  "remote" ) {
             $this ->saveRemote();
         else  if ( $type  ==  "base64" ) {
             $this ->upBase64();
         else  {
             $this ->upFile();
         }
 
         $this ->stateMap[ 'ERROR_TYPE_NOT_ALLOWED' ] = iconv( 'unicode' 'utf-8' $this ->stateMap[ 'ERROR_TYPE_NOT_ALLOWED' ]);
     }
 
     /**
      * 上傳文件的主處理方法
      * @return mixed
      */
     private  function  upFile()
     {
         $file  $this ->file =  $_FILES [ $this ->fileField];
         if  (! $file ) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_FILE_NOT_FOUND" );
             return ;
         }
         if  ( $this ->file[ 'error' ]) {
             $this ->stateInfo =  $this ->getStateInfo( $file [ 'error' ]);
             return ;
         else  if  (! file_exists ( $file [ 'tmp_name' ])) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_TMP_FILE_NOT_FOUND" );
             return ;
         else  if  (! is_uploaded_file ( $file [ 'tmp_name' ])) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_TMPFILE" );
             return ;
         }
 
         $this ->oriName =  $file [ 'name' ];
         $this -> fileSize  $file [ 'size' ];
         $this -> fileType  $this ->getFileExt();
         $this ->fullName =  $this ->getFullName();
         $this ->filePath =  $this ->getFilePath();
         $this ->fileName =  $this ->getFileName();
         $dirname  = dirname( $this ->filePath);
 
         //檢查文件大小是否超出限制
         if  (! $this ->checkSize()) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_SIZE_EXCEED" );
             return ;
         }
 
         //檢查是否不允許的文件格式
         if  (! $this ->checkType()) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_TYPE_NOT_ALLOWED" );
             return ;
         }
 
         //創建目錄失敗
         if  (! file_exists ( $dirname ) && ! mkdir ( $dirname , 0777, true)) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_CREATE_DIR" );
             return ;
         else  if  (! is_writeable ( $dirname )) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_DIR_NOT_WRITEABLE" );
             return ;
         }
 
         //移動文件
         if  (!(move_uploaded_file( $file [ "tmp_name" ],  $this ->filePath) &&  file_exists ( $this ->filePath))) {  //移動失敗
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_FILE_MOVE" );
         else  //移動成功
             $this ->stateInfo =  $this ->stateMap[0];
         }
     }
 
     /**
      * 處理base64編碼的圖片上傳
      * @return mixed
      */
     private  function  upBase64()
     {
         $base64Data  $_POST [ $this ->fileField];
         $img  base64_decode ( $base64Data );
 
         $this ->oriName =  $this ->config[ 'oriName' ];
         $this -> fileSize  strlen ( $img );
         $this -> fileType  $this ->getFileExt();
         $this ->fullName =  $this ->getFullName();
         $this ->filePath =  $this ->getFilePath();
         $this ->fileName =  $this ->getFileName();
         $dirname  = dirname( $this ->filePath);
 
         //檢查文件大小是否超出限制
         if  (! $this ->checkSize()) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_SIZE_EXCEED" );
             return ;
         }
 
         //創建目錄失敗
         if  (! file_exists ( $dirname ) && ! mkdir ( $dirname , 0777, true)) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_CREATE_DIR" );
             return ;
         else  if  (! is_writeable ( $dirname )) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_DIR_NOT_WRITEABLE" );
             return ;
         }
 
         //移動文件
         if  (!( file_put_contents ( $this ->filePath,  $img ) &&  file_exists ( $this ->filePath))) {  //移動失敗
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_WRITE_CONTENT" );
         else  //移動成功
             $this ->stateInfo =  $this ->stateMap[0];
         }
 
     }
 
     /**
      * 拉取遠程圖片
      * @return mixed
      */
     private  function  saveRemote()
     {
         $imgUrl  = htmlspecialchars( $this ->fileField);
         $imgUrl  str_replace ( "&amp;" "&" $imgUrl );
 
         //http開頭驗證
         if  ( strpos ( $imgUrl "http" ) !== 0) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_HTTP_LINK" );
             return ;
         }
 
         preg_match( '/(^https*:\/\/[^:\/]+)/' $imgUrl $matches );
         $host_with_protocol  count ( $matches ) > 1 ?  $matches [1] :  '' ;
 
         // 判斷是否是合法 url
         if  (!filter_var( $host_with_protocol , FILTER_VALIDATE_URL)) {
             $this ->stateInfo =  $this ->getStateInfo( "INVALID_URL" );
             return ;
         }
 
         preg_match( '/^https*:\/\/(.+)/' $host_with_protocol $matches );
         $host_without_protocol  count ( $matches ) > 1 ?  $matches [1] :  '' ;
 
         // 此時提取出來的可能是 ip 也有可能是域名,先獲取 ip
         $ip  gethostbyname ( $host_without_protocol );
         // 判斷是否是私有 ip
         if (!filter_var( $ip , FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
             $this ->stateInfo =  $this ->getStateInfo( "INVALID_IP" );
             return ;
         }
 
         //獲取請求頭並檢測死鏈
         $heads  = get_headers( $imgUrl , 1);
         if  (!( stristr ( $heads [0],  "200" ) &&  stristr ( $heads [0],  "OK" ))) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_DEAD_LINK" );
             return ;
         }
         //格式驗證(擴展名驗證和Content-Type驗證)
         $fileType  strtolower ( strrchr ( $imgUrl '.' ));
         if  (!in_array( $fileType $this ->config[ 'allowFiles' ]) || !isset( $heads [ 'Content-Type' ]) || ! stristr ( $heads [ 'Content-Type' ],  "image" )) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_HTTP_CONTENTTYPE" );
             return ;
         }
 
         //打開輸出緩沖區並獲取遠程圖片
         ob_start();
         $context  = stream_context_create(
             array ( 'http'  =>  array (
                 'follow_location'  => false  // don't follow redirects
             ))
         );
         readfile( $imgUrl , false,  $context );
         $img  = ob_get_contents();
         ob_end_clean();
         preg_match( "/[\/]([^\/]*)[\.]?[^\.\/]*$/" $imgUrl $m );
 
         $this ->oriName =  $m  $m [1]: "" ;
         $this -> fileSize  strlen ( $img );
         $this -> fileType  $this ->getFileExt();
         $this ->fullName =  $this ->getFullName();
         $this ->filePath =  $this ->getFilePath();
         $this ->fileName =  $this ->getFileName();
         $dirname  = dirname( $this ->filePath);
 
         //檢查文件大小是否超出限制
         if  (! $this ->checkSize()) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_SIZE_EXCEED" );
             return ;
         }
 
         //創建目錄失敗
         if  (! file_exists ( $dirname ) && ! mkdir ( $dirname , 0777, true)) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_CREATE_DIR" );
             return ;
         else  if  (! is_writeable ( $dirname )) {
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_DIR_NOT_WRITEABLE" );
             return ;
         }
 
         //移動文件
         if  (!( file_put_contents ( $this ->filePath,  $img ) &&  file_exists ( $this ->filePath))) {  //移動失敗
             $this ->stateInfo =  $this ->getStateInfo( "ERROR_WRITE_CONTENT" );
         else  //移動成功
             $this ->stateInfo =  $this ->stateMap[0];
         }
 
     }
 
     /**
      * 上傳錯誤檢查
      * @param $errCode
      * @return string
      */
     private  function  getStateInfo( $errCode )
     {
         return  ! $this ->stateMap[ $errCode ] ?  $this ->stateMap[ "ERROR_UNKNOWN" ] :  $this ->stateMap[ $errCode ];
     }
 
     /**
      * 獲取文件擴展名
      * @return string
      */
     private  function  getFileExt()
     {
         return  strtolower ( strrchr ( $this ->oriName,  '.' ));
     }
 
     /**
      * 重命名文件
      * @return string
      */
     private  function  getFullName()
     {
         //替換日期事件
         $t  = time();
         $d  explode ( '-' date ( "Y-y-m-d-H-i-s" ));
         $format  $this ->config[ "pathFormat" ];
         $format  str_replace ( "{uid}" $this ->uid,  $format ); //uid:用戶id
         $format  str_replace ( "{yyyy}" $d [0],  $format );
         $format  str_replace ( "{yy}" $d [1],  $format );
         $format  str_replace ( "{mm}" $d [2],  $format );
         $format  str_replace ( "{dd}" $d [3],  $format );
         $format  str_replace ( "{hh}" $d [4],  $format );
         $format  str_replace ( "{ii}" $d [5],  $format );
         $format  str_replace ( "{ss}" $d [6],  $format );
         $format  str_replace ( "{time}" $t $format );
 
         //過濾文件名的非法自負,並替換文件名
         $oriName  substr ( $this ->oriName, 0,  strrpos ( $this ->oriName,  '.' ));
         $oriName  = preg_replace( "/[\|\?\"\<\>\/\*\\\\]+/" '' $oriName );
         $format  str_replace ( "{filename}" $oriName $format );
 
         //替換隨機字符串
         $randNum  = rand(1, 10000000000) . rand(1, 10000000000);
         if  (preg_match( "/\{rand\:([\d]*)\}/i" $format $matches )) {
             $format  = preg_replace( "/\{rand\:[\d]*\}/i" substr ( $randNum , 0,  $matches [1]),  $format );
         }
 
         $ext  $this ->getFileExt();
         return  $format  $ext ;
     }
 
     /**
      * 獲取文件名
      * @return string
      */
     private  function  getFileName () {
         return  substr ( $this ->filePath,  strrpos ( $this ->filePath,  '/' ) + 1);
     }
 
     /**
      * 獲取文件完整路徑
      * @return string
      */
     private  function  getFilePath()
     {
         $fullname  $this ->fullName;
         $rootPath  $_SERVER [ 'DOCUMENT_ROOT' ];
 
         if  ( substr ( $fullname , 0, 1) !=  '/' ) {
             $fullname  '/'  $fullname ;
         }
 
         return  $rootPath  $fullname ;
     }
 
     /**
      * 文件類型檢測
      * @return bool
      */
     private  function  checkType()
     {
         return  in_array( $this ->getFileExt(),  $this ->config[ "allowFiles" ]);
     }
 
     /**
      * 文件大小檢測
      * @return bool
      */
     private  function   checkSize()
     {
         return  $this -> fileSize  <= ( $this ->config[ "maxSize" ]);
     }
 
     /**
      * 獲取當前上傳成功文件的各項信息
      * @return array
      */
     public  function  getFileInfo()
     {
         return  array (
             "state"  =>  $this ->stateInfo,
             "url"  =>  $this ->fullName,
             "title"  =>  $this ->fileName,
             "original"  =>  $this ->oriName,
             "type"  =>  $this -> fileType ,
             "size"  =>  $this -> fileSize
         );
     }
 
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM