方維團購系統是基于groupon模式開發的團購系統。它可以讓用戶高效、快速、低成本的構建個性化、專業化、強大功能的團購網站。采用php語言,便于二次開發,小編對它還是比較了解的,今天就以增加短信接口為例,一步步教大家如何進行二次開發,使用的短信接口是我們短信寶短信群發平臺的短信接口,我們短信寶短信群發平臺非常穩定,發送速度快,注冊就送測試短信,推薦大家使用。
首先第一步我們要在項目\system\sms下新建一個文件,文件名為smsbao_sms.php,這個文件是短信寶接口文件,代碼內容如下:
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
|
<?php // +---------------------------------------------------------------------- // | Fanweo2o商業系統 最新版V3.03.3285 含4個手機APP。 // +---------------------------------------------------------------------- // | Copyright (c) 2010 http://www.fanwe.com All rights reserved. // +---------------------------------------------------------------------- /* 模塊的基本信息 */ if (isset( $read_modules ) && $read_modules == true) { $module [ 'class_name' ] = 'smsbao' ; /* 名稱 */ $module [ 'name' ] = "短信寶增值平臺 (<a href='http://www.gjrencai.com/reg?r=5001' target='_blank'><font color='red'>還沒賬號?點擊這免費注冊</font></a>)" ; if (ACTION_NAME == "install" || ACTION_NAME == "edit" ){ $module [ 'lang' ] = array (); $module [ 'config' ] = array (); } return $module ; } // 短信寶短信平臺 require_once APP_ROOT_PATH. "system/libs/sms.php" ; //引入接口 require_once APP_ROOT_PATH. "system/utils/sms_trans.php" ; class smsbao_sms implements sms { public $sms ; public $message = "" ; private $statusStr = array ( "0" => "短信發送成功" , "-1" => "參數不全" , "-2" => "服務器空間不支持,請確認支持curl或者fsocket,聯系您的空間商解決或者更換空間!" , "30" => "密碼錯誤" , "40" => "賬號不存在" , "41" => "余額不足" , "42" => "帳戶已過期" , "43" => "IP地址限制" , "50" => "內容含有敏感詞" ); public function __construct( $smsInfo = '' ) { if (! empty ( $smsInfo )) { $this ->sms = $smsInfo ; } } public function sendSMS( $mobile_number , $content , $sendTime = '' , $is_adv =0) { if ( is_array ( $mobile_number )) { $mobile_number = implode( "," , $mobile_number ); } $sms = new sms_trans(); $params = array ( "u" => $this ->sms[ 'user_name' ], "p" =>md5( $this ->sms[ 'password' ]), "m" => $mobile_number , "c" =>urlencode( $content ) ); $result = $sms ->request( $this ->sms[ 'server_url' ], $params ); $code = $result [ 'body' ]; if ( $code == '0' ) { $result [ 'status' ] = 1; } else { $result [ 'status' ] = 0; $result [ 'msg' ] = $this ->statusStr[ $code ]; } return $result ; } public function getSmsInfo() { return "短信寶增值平臺" ; } public function check_fee() { es_session::start(); $last_visit = intval (es_session::get( "last_visit_smsbao" )); if (get_gmtime() - $last_visit > 10) { $sms = new sms_trans(); $params = array ( "u" => $this ->sms[ 'user_name' ], "p" =>md5( $this ->sms[ 'password' ]) ); $result = $sms ->request( $url , $params ); $match = explode ( ',' , $result [ 'body' ]); if ( $match [0] != '' ) { $remain = (int) $match [1]; $str = sprintf( '短信寶增值平臺 剩余:%d 條' , $remain ); } else { $str = "短信寶增值平臺 (<a href='http://www.gjrencai.com/reg?r=5001' target='_blank'><font color='red'>還沒賬號?點擊這免費注冊</font></a>)" ; } es_session::set( "smsbao_info" , $str ); es_session::set( "last_visit_smsbao" ,get_gmtime()); return $str ; } else { $qxt_info = es_session::get( "smsbao_info" ); if ( $smsbao_info ) return $smsbao_info ; else return "短信寶增值平臺 (<a href='http://www.gjrencai.com/reg?r=5001' target='_blank'><font color='red'>還沒賬號?點擊這免費注冊</font></a>)" ; } } } ?> |
第二步,我們要在項目\system\utils下新建一個文件,文件名為sms_trans.php,這個文件是安裝短信寶短信群發平臺的文件,代碼內容如下:
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
378
379
380
381
382
383
|
<?php class sms_trans { /** * 腳本執行時間。-1表示采用PHP的默認值。 * * @access private * @var integer $time_limit */ var $time_limit = -1; /** * 在多少秒之內,如果連接不可用,腳本就停止連接。-1表示采用PHP的默認值。 * * @access private * @var integer $connect_timeout */ var $connect_timeout = -1; /** * 連接后,限定多少秒超時。-1表示采用PHP的默認值。此項僅當采用CURL庫時啟用。 * * @access private * @var integer $stream_timeout */ var $stream_timeout = -1; /** * 是否使用CURL庫來連接。false表示采用fsockopen進行連接。 * * @access private * @var boolean $use_curl */ var $use_curl = false; /** * 構造函數 * * @access public * @param integer $time_limit * @param integer $connect_timeout * @param integer $stream_timeout * @param boolean $use_curl * @return void */ function __construct( $time_limit = -1, $connect_timeout = -1, $stream_timeout = -1, $use_curl = false) { //$this->transport($time_limit, $connect_timeout, $stream_timeout, $use_curl); $this ->time_limit = $time_limit ; $this ->connect_timeout = $connect_timeout ; $this ->stream_timeout = $stream_timeout ; $this ->use_curl = $use_curl ; } /** * 請求遠程服務器 * * @access public * @param string $url 遠程服務器的URL * @param mix $params 查詢參數,形如bar=foo&foo=bar;或者是一維關聯數組,形如array('a'=>'aa',...) * @param string $method 請求方式,是POST還是GET * @param array $my_header 用戶要發送的頭部信息,為一維關聯數組,形如array('a'=>'aa',...) * @return array 成功返回一維關聯數組,形如array('header'=>'bar', 'body'=>'foo'), * 重大錯誤程序直接停止運行,否則返回false。 */ function request( $url , $params = '' , $method = 'POST' , $my_header = '' ) { $fsock_exists = function_exists( 'fsockopen' ); $curl_exists = function_exists( 'curl_init' ); if (! $fsock_exists && ! $curl_exists ) { die ( 'No method available!' ); } if (! $url ) { die ( 'Invalid url!' ); } if ( $this ->time_limit > -1) //如果為0,不限制執行時間 { set_time_limit( $this ->time_limit); } $method = $method === 'GET' ? $method : 'POST' ; $response = '' ; $temp_str = '' ; /* 格式化將要發要送的參數 */ if ( $params && is_array ( $params )) { foreach ( $params AS $key => $value ) { $temp_str .= '&' . $key . '=' . $value ; } $params = preg_replace( '/^&/' , '' , $temp_str ); } /* 如果fsockopen存在,且用戶不指定使用curl,則調用use_socket函數 */ if ( $fsock_exists && ! $this ->use_curl) { $response = $this ->use_socket( $url , $params , $method , $my_header ); } /* 只要上述條件中的任一個不成立,流程就轉向這里,這時如果curl模塊可用,就調用use_curl函數 */ elseif ( $curl_exists ) { $response = $this ->use_curl( $url , $params , $method , $my_header ); } /* 空響應或者傳輸過程中發生錯誤,程序將返回false */ if (! $response ) { return false; } return $response ; } /** * 使用fsockopen進行連接 * * @access private * @param string $url 遠程服務器的URL * @param string $params 查詢參數,形如bar=foo&foo=bar * @param string $method 請求方式,是POST還是GET * @param array $my_header 用戶要發送的頭部信息,為一維關聯數組,形如array('a'=>'aa',...) * @return array 成功返回一維關聯數組,形如array('header'=>'bar', 'body'=>'foo'), * 否則返回false。 */ function use_socket( $url , $params , $method , $my_header ) { $query = '' ; $auth = '' ; $content_type = '' ; $content_length = '' ; $request_body = '' ; $request = '' ; $http_response = '' ; $temp_str = '' ; $error = '' ; $errstr = '' ; $crlf = $this ->generate_crlf(); if ( $method === 'GET' ) { $query = $params ? "?$params" : '' ; } else { $request_body = $params ; $content_type = 'Content-Type: application/x-www-form-urlencoded' . $crlf ; $content_length = 'Content-Length: ' . strlen ( $request_body ) . $crlf . $crlf ; } $url_parts = $this ->parse_raw_url( $url ); $path = $url_parts [ 'path' ] . $query ; if (! empty ( $url_parts [ 'user' ])) { $auth = 'Authorization: Basic ' . base64_encode ( $url_parts [ 'user' ] . ':' . $url_parts [ 'pass' ]) . $crlf ; } /* 格式化自定義頭部信息 */ if ( $my_header && is_array ( $my_header )) { foreach ( $my_header AS $key => $value ) { $temp_str .= $key . ': ' . $value . $crlf ; } $my_header = $temp_str ; } /* 構造HTTP請求頭部 */ $request = "$method $path HTTP/1.0$crlf" . 'Host: ' . $url_parts [ 'host' ] . $crlf . $auth . $my_header . $content_type . $content_length . $request_body ; if ( $this ->connect_timeout > -1) { $fp = @ fsockopen ( $url_parts [ 'host' ], $url_parts [ 'port' ], $error , $errstr , $connect_timeout ); } else { $fp = @ fsockopen ( $url_parts [ 'host' ], $url_parts [ 'port' ], $error , $errstr ); } if (! $fp ) { return false; //打開失敗 } if (!@fwrite( $fp , $request )) { return false; //寫入失敗 } while (! feof ( $fp )) { $http_response .= fgets ( $fp ); } if (! $http_response ) { return false; //空響應 } $separator = '/\r\n\r\n|\n\n|\r\r/' ; list( $http_header , $http_body ) = preg_split( $separator , $http_response , 2); $http_response = array ( 'header' => $http_header , //header肯定有值 'body' => $http_body ); //body可能為空 @fclose( $fp ); return $http_response ; } /** * 使用curl進行連接 * * @access private * @param string $url 遠程服務器的URL * @param string $params 查詢參數,形如bar=foo&foo=bar * @param string $method 請求方式,是POST還是GET * @param array $my_header 用戶要發送的頭部信息,為一維關聯數組,形如array('a'=>'aa',...) * @return array 成功返回一維關聯數組,形如array('header'=>'bar', 'body'=>'foo'), * 失敗返回false。 */ function use_curl( $url , $params , $method , $my_header ) { /* 開始一個新會話 */ $curl_session = curl_init(); /* 基本設置 */ curl_setopt( $curl_session , CURLOPT_FORBID_REUSE, true); // 處理完后,關閉連接,釋放資源 curl_setopt( $curl_session , CURLOPT_HEADER, true); //結果中包含頭部信息 curl_setopt( $curl_session , CURLOPT_RETURNTRANSFER, true); //把結果返回,而非直接輸出 curl_setopt( $curl_session , CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); //采用1.0版的HTTP協議 $url_parts = $this ->parse_raw_url( $url ); /* 設置驗證策略 */ if (! empty ( $url_parts [ 'user' ])) { $auth = $url_parts [ 'user' ] . ':' . $url_parts [ 'pass' ]; curl_setopt( $curl_session , CURLOPT_USERPWD, $auth ); curl_setopt( $curl_session , CURLOPT_HTTPAUTH, CURLAUTH_BASIC); } $header = array (); /* 設置主機 */ $header [] = 'Host: ' . $url_parts [ 'host' ]; /* 格式化自定義頭部信息 */ if ( $my_header && is_array ( $my_header )) { foreach ( $my_header AS $key => $value ) { $header [] = $key . ': ' . $value ; } } if ( $method === 'GET' ) { curl_setopt( $curl_session , CURLOPT_HTTPGET, true); $url .= $params ? '?' . $params : '' ; } else { curl_setopt( $curl_session , CURLOPT_POST, true); $header [] = 'Content-Type: application/x-www-form-urlencoded' ; $header [] = 'Content-Length: ' . strlen ( $params ); curl_setopt( $curl_session , CURLOPT_POSTFIELDS, $params ); } /* 設置請求地址 */ curl_setopt( $curl_session , CURLOPT_URL, $url ); /* 設置頭部信息 */ curl_setopt( $curl_session , CURLOPT_HTTPHEADER, $header ); if ( $this ->connect_timeout > -1) { curl_setopt( $curl_session , CURLOPT_CONNECTTIMEOUT, $this ->connect_timeout); } if ( $this ->stream_timeout > -1) { curl_setopt( $curl_session , CURLOPT_TIMEOUT, $this ->stream_timeout); } /* 發送請求 */ $http_response = curl_exec( $curl_session ); if (curl_errno( $curl_session ) != 0) { return false; } $separator = '/\r\n\r\n|\n\n|\r\r/' ; list( $http_header , $http_body ) = preg_split( $separator , $http_response , 2); $http_response = array ( 'header' => $http_header , //肯定有值 'body' => $http_body ); //可能為空 curl_close( $curl_session ); return $http_response ; } /** * Similar to PHP's builtin parse_url() function, but makes sure what the schema, * path and port keys are set to http, /, 80 respectively if they're missing * * @access private * @param string $raw_url Raw URL to be split into an array * @author http://www.cpaint.net/ * @return array */ function parse_raw_url( $raw_url ) { $retval = array (); $raw_url = (string) $raw_url ; // make sure parse_url() recognizes the URL correctly. if ( strpos ( $raw_url , '://' ) === false) { } // split request into array $retval = parse_url ( $raw_url ); // make sure a path key exists if (!isset( $retval [ 'path' ])) { $retval [ 'path' ] = '/' ; } // set port to 80 if none exists if (!isset( $retval [ 'port' ])) { $retval [ 'port' ] = '80' ; } return $retval ; } /** * 產生一個換行符,不同的操作系統會有不同的換行符 * * @access private * @return string 用雙引號引用的換行符 */ function generate_crlf() { $crlf = '' ; if ( strtoupper ( substr (PHP_OS, 0, 3) === 'WIN' )) { $crlf = "\r\n" ; } elseif ( strtoupper ( substr (PHP_OS, 0, 3) === 'MAC' )) { $crlf = "\r" ; } else { $crlf = "\n" ; } return $crlf ; } } ?> |
經過剛才的替換,短信寶短信接口就可以正常使用了,這里再給大家說一些注意點:
①,短信簽名在短信郵件->消息模版管理中配置,選中短信模版在最前面加上全角中括號,短信簽名內容在3-8個字。例:【短信寶】你的手機號為{$verify.mobile},驗證碼為{$verify.code}。
②,有的人肯定會出現發送不出去的情況,這應該是前后臺的隊列沒有開啟。不開啟隊列是無法進行隊列發送的,這是非常關鍵的一步。解決:登入后臺 -> 系統設置 -> 基礎配置 -> 開啟前后臺隊列。
③,還有一種情況就是一直正常發送,突然接收不到短信了, 這應該是方維的后臺隊列BUG導致的,解決方法:登錄方維管理后臺 –> 短信郵件 –> 隊列管理 — > 業務隊列列表,做以下三個操作:1. 選擇結果是失敗的隊列數據,點擊徹底刪除,2.點擊 重置隊列發送,3.清除緩存。
下面我們進行測試發送:
報備一下短信寶的VIP模板,這樣就可以走短信寶的優質通道了,并且免審核了,短信內容3~5秒就可送達。
最新更新
電商類
CMS類
微信類