1
1
# -*- coding: UTF-8 -*-
2
+
3
+ # -*- coding: UTF-8 -*-
4
+ #-----------------------------------------------------------
5
+ # PPython(PHP and Python).
6
+ # (2012-15 http://code.google.com/p/ppython/)
7
+ #
8
+ # License: http://www.apache.org/licenses/LICENSE-2.0
9
+ #-----------------------------------------------------------
10
+
2
11
import sys
3
12
import time
4
13
import threading
10
19
REQUEST_MIN_LEN = 10
11
20
TIMEOUT = 180
12
21
13
- pc_dict = {} #预编译字典,key:调用模块、函数、参数字符串,值是编译对象
14
- global_env = {} #global环境变量
22
+ pc_dict = {}
23
+ global_env = {}
15
24
25
+ # find position of c in bytes
26
+ # pos: the start position
16
27
def index (bytes , c , pos = 0 ):
17
- """
18
- 查找c字符在bytes中的位置(从0开始),找不到返回-1
19
- pos: 查找起始位置
20
- """
21
28
for i in range (len (bytes )):
22
29
if (i <= pos ):
23
30
continue
@@ -28,48 +35,42 @@ def index(bytes, c, pos=0):
28
35
return - 1
29
36
30
37
38
+ # encode parameters from python to php
31
39
def z_encode (p ):
32
- """
33
- encode param from python data
34
- """
35
- if p == None : #None->PHP中的NULL
40
+ if p == None : #python None to PHP NULL
36
41
return "N;"
37
- elif isinstance (p , int ): #int->PHP整形
42
+ elif isinstance (p , int ): #python int to PHP int
38
43
return "i:%d;" % p
39
- elif isinstance (p , str ): #String->PHP字符串
44
+ elif isinstance (p , str ): #python String to PHP String
40
45
p_bytes = p .encode (php_python .CHARSET );
41
46
ret = 's:%d:"' % len (p_bytes )
42
47
ret = ret .encode (php_python .CHARSET )
43
48
ret = ret + p_bytes + '";' .encode (php_python .CHARSET )
44
49
#ret = str(ret, php_python.CHARSET)
45
50
ret = str (ret )
46
51
return ret
47
- elif isinstance (p , bool ): #boolean->PHP布尔
52
+ elif isinstance (p , bool ): #python boolean to PHP boolean
48
53
b = 1 if p else 0
49
54
return 'b:%d;' % b
50
- elif isinstance (p , float ): #float->PHP浮点
55
+ elif isinstance (p , float ): #python float to PHP float
51
56
return 'd:%r;' % p
52
- elif isinstance (p , list ) or isinstance (p , tuple ): #list,tuple->PHP数组(下标int)
57
+ elif isinstance (p , list ) or isinstance (p , tuple ): #python list,tuple to PHP array with int indice
53
58
s = ''
54
59
for pos ,i in enumerate (p ):
55
60
s += z_encode (pos )
56
61
s += z_encode (i )
57
62
return "a:%d:{%s}" % (len (p ),s )
58
- elif isinstance (p , dict ): #字典->PHP数组(下标str)
63
+ elif isinstance (p , dict ): #python dictionary to PHP array with string indice
59
64
s = ''
60
65
for key in p :
61
66
s += z_encode (key )
62
67
s += z_encode (p [key ])
63
68
return "a:%d:{%s}" % (len (p ),s )
64
- else : #其余->PHP中的NULL
69
+ else : #Other types in python to PHP NULL
65
70
return "N;"
66
71
67
-
72
+ #decode php parameters from string to python
68
73
def z_decode (p ):
69
- """
70
- decode php param from string to python
71
- p: bytes
72
- """
73
74
if p [0 ]== chr (0x4e ): #NULL 0x4e-'N'
74
75
return None ,p [2 :]
75
76
elif p [0 ]== chr (0x62 ): #bool 0x62-'b'
@@ -91,18 +92,18 @@ def z_decode(p):
91
92
#return str(v, php_python.CHARSET), p[end+1:]
92
93
return v .encode (php_python .CHARSET ), p [end + 1 :]
93
94
elif p [0 ]== chr (0x61 ): #array 0x61-'a'
94
- list_ = [] #数组
95
- dict_ = {} #字典
96
- flag = True #类型, true-元组 false-字典
95
+ list_ = [] #array
96
+ dict_ = {} #dictionary
97
+ flag = True #true-tuple false-dictionary
97
98
second = index (p , chr (0x3a ), 2 ) # 0x3a-":"
98
- num = int (p [2 :second ]) #元素数量
99
- pp = p [second + 2 :] #所有元素
99
+ num = int (p [2 :second ]) #number of elements
100
+ pp = p [second + 2 :] #all elements
100
101
for i in range (num ):
101
- key ,pp = z_decode (pp ) #key解析
102
- if (i == 0 ): #判断第一个元素key是否int 0
102
+ key ,pp = z_decode (pp ) #key decode
103
+ if (i == 0 ):
103
104
if (not isinstance (key , int )) or (key != 0 ):
104
105
flag = False
105
- val ,pp = z_decode (pp ) #value解析
106
+ val ,pp = z_decode (pp )
106
107
list_ .append (val )
107
108
dict_ [key ]= val
108
109
return (list_ , pp [2 :]) if flag else (dict_ , pp [2 :])
@@ -111,144 +112,89 @@ def z_decode(p):
111
112
112
113
113
114
def parse_php_req (p ):
114
- """
115
- 解析PHP请求消息
116
- 返回:元组(模块名,函数名,入参list)
117
- """
118
115
while p :
119
- v ,p = z_decode (p ) #v:值 p:bytes(每次z_decode计算偏移量)
116
+ v ,p = z_decode (p )
120
117
params = v
121
118
122
- modul_func = params [0 ] #第一个元素是调用模块和函数名
123
- #print("模块和函数名:%s" % modul_func)
124
- #print("参数:%s" % params[1:])
119
+ modul_func = params [0 ]
125
120
pos = modul_func .find ("::" )
126
- modul = modul_func [:pos ] #模块名
127
- func = modul_func [pos + 2 :] #函数名
121
+ modul = modul_func [:pos ]
122
+ func = modul_func [pos + 2 :]
128
123
return modul , func , params [1 :]
129
124
130
125
131
126
class ProcessThread (threading .Thread ):
132
- """
133
- preThread 处理线程
134
- """
135
127
def __init__ (self , socket ):
136
128
threading .Thread .__init__ (self )
137
-
138
- #客户socket
139
129
self ._socket = socket
140
130
141
- def run (self ):
142
-
143
- #---------------------------------------------------
144
- # 1.接收消息
145
- #---------------------------------------------------
146
-
131
+ def run (self ):
147
132
try :
148
- self ._socket .settimeout (TIMEOUT ) #设置socket超时时间
149
- firstbuf = self ._socket .recv (16 * 1024 ) #接收第一个消息包(bytes)
150
- if len (firstbuf ) < REQUEST_MIN_LEN : #不够消息最小长度
151
- #print ("非法包,小于最小长度: %s" % firstbuf)
133
+ self ._socket .settimeout (TIMEOUT )
134
+ firstbuf = self ._socket .recv (16 * 1024 )
135
+ if len (firstbuf ) < REQUEST_MIN_LEN :
152
136
print 'error message,less than minimum length:' ,firstbuf
153
137
self ._socket .close ()
154
138
return
155
139
156
- firstComma = index (firstbuf , chr (0x2c )) #查找第一个","分割符
157
- #firstComma = index(firstbuf, ',')
140
+ firstComma = index (firstbuf , chr (0x2c ))
158
141
print firstbuf
159
- totalLen = int (firstbuf [0 :firstComma ]) #消息包总长度
160
- #print("消息长度:%d" % totalLen)
142
+ totalLen = int (firstbuf [0 :firstComma ])
161
143
print 'message length:' ,totalLen
162
144
reqMsg = firstbuf [firstComma + 1 :]
163
145
print 'reqMsg:' ,reqMsg
164
146
while (len (reqMsg ) < totalLen ):
165
147
reqMsg = reqMsg + self ._socket .recv (16 * 1024 )
166
-
167
- #调试
168
- #print ("请求包:%s" % reqMsg)
169
-
170
148
except Exception ,e :
171
- #print ('接收消息异常', e)
172
149
print 'getMessage error' ,str (e )
173
150
self ._socket .close ()
174
151
return
175
-
176
- #---------------------------------------------------
177
- # 2.调用模块、函数检查,预编译。
178
- #---------------------------------------------------
179
-
180
- #从消息包中解析出模块名、函数名、入参list
181
152
modul , func , params = parse_php_req (reqMsg )
182
153
print 'module:' ,modul ,'func:' ,func ,'parmas:' ,params
183
154
184
- if (modul not in pc_dict ): #预编译字典中没有此编译模块
185
- #检查模块、函数是否存在
155
+ if (modul not in pc_dict ):
186
156
try :
187
- callMod = __import__ (modul ) #根据module名,反射出module
188
- pc_dict [modul ] = callMod #预编译字典缓存此模块
157
+ callMod = __import__ (modul )
158
+ pc_dict [modul ] = callMod
189
159
except Exception ,e :
190
160
print 'module not exist:' ,modul
191
- #print ('模块不存在:%s' % modul)
192
- self ._socket .sendall (("F" + "module '%s' is not exist!" % modul ).encode (php_python .CHARSET )) #异常
161
+ self ._socket .sendall (("F" + "module '%s' is not exist!" % modul ).encode (php_python .CHARSET ))
193
162
self ._socket .close ()
194
163
return
195
164
else :
196
- callMod = pc_dict [modul ] #从预编译字典中获得模块对象
165
+ callMod = pc_dict [modul ]
197
166
198
167
try :
199
168
callMethod = getattr (callMod , func )
200
169
except Exception ,e :
201
170
print 'function not exist:' ,func
202
- #print ('函数不存在:%s' % func)
203
171
self ._socket .sendall (("F" + "function '%s()' is not exist!" % func ).encode (php_python .CHARSET )) #异常
204
172
self ._socket .close ()
205
173
return
206
-
207
- #---------------------------------------------------
208
- # 3.Python函数调用
209
- #---------------------------------------------------
210
-
211
174
try :
212
175
params = ',' .join ([repr (x ) for x in params ])
213
- #print ("调用函数及参数:%s(%s)" % (modul+'.'+func, params) )
214
-
215
- #加载函数
216
176
compStr = "import %s\n ret=%s(%s)" % (modul , modul + '.' + func , params )
217
- #print("函数调用代码:%s" % compStr)
218
177
rpFunc = compile (compStr , "" , "exec" )
219
178
220
179
if func not in global_env :
221
180
global_env [func ] = rpFunc
222
181
local_env = {}
223
- exec (rpFunc , global_env , local_env ) #函数调用
224
- #print (global_env)
225
- #print (local_env)
182
+ exec (rpFunc , global_env , local_env )
226
183
except Exception ,e :
227
- #print ('调用Python业务函数异常', e )
228
184
print 'call python error:' ,str (e )
229
185
errType , errMsg , traceback = sys .exc_info ()
230
- self ._socket .sendall (("F%s" % errMsg ).encode (php_python .CHARSET )) #异常信息返回
186
+ self ._socket .sendall (("F%s" % errMsg ).encode (php_python .CHARSET ))
231
187
self ._socket .close ()
232
188
return
233
-
234
- #---------------------------------------------------
235
- # 4.结果返回给PHP
236
- #---------------------------------------------------
237
- #retType = type(local_env['ret'])
238
- #print ("函数返回:%s" % retType)
239
- rspStr = z_encode (local_env ['ret' ]) #函数结果组装为PHP序列化字符串
189
+ rspStr = z_encode (local_env ['ret' ])
240
190
241
191
try :
242
- #加上成功前缀'S'
243
192
rspStr = "S" + rspStr
244
- #调试
245
- #print ("返回包:%s" % rspStr)
246
193
self ._socket .sendall (rspStr .encode (php_python .CHARSET ))
247
194
except Exception ,e :
248
195
print 'send message error:' ,str (e )
249
- #print ('发送消息异常', e)
250
196
errType , errMsg , traceback = sys .exc_info ()
251
- self ._socket .sendall (("F%s" % errMsg ).encode (php_python .CHARSET )) #异常信息返回
197
+ self ._socket .sendall (("F%s" % errMsg ).encode (php_python .CHARSET ))
252
198
finally :
253
199
self ._socket .close ()
254
200
return
0 commit comments