php调用python服务

侃侃:公司用的php的popen以命令的形式调用python,首先说说这样做的缺点。

php执行命令行调用python的缺点

popen('python test.py [参数]', 'r');
  1. 缺点一:windows默认的是gbk编码,当php中传utf-8中文参数的时候,python接收到的参数会有问题。

    #当然,这是有解决的办法的,就是windows下转换一下字符的编码,linux不用转换。再来python接收参数的时候肯定也要转换编码了,烦不烦?
  2. cmd命令或者shell命令是有长度限制的,传的参数过长的时候,接收到的参数就不会完整。
  3. 执行shell命令是有危险的,万一参数里面多了个啥,你知道的。

    #这也能解决,php中的函数escapeshellarg,嗯哼先给他escape一下。
    

那怎么办呢?

python socket server

不多说,不清楚的百度"socket",下面上代码(写的一个php调用python服务美化javascript的应用,服务器端python):

#代码中引用的模块将会在附件中给出
import sys, json
import traceback
import SocketServer
from daemon import Daemon
import jsbeautifier

class Todo:
    def __init__(self):
        print('Welcome!')
    def test(self, args):
        res = jsbeautifier.beautify(args[0].encode('utf-8'))
        return res;
    def error(self, args):
        return 'not function!'

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                data = self.request.recv(1024)
                if not data:
                    print('end')
                    break
                data = json.loads(data)
                res =  getattr(self._object, data['func'], 'error')(data['args'])
                if not res:
                    res = ''
                res = str(len(res)).rjust(8, '0') + str(res)
                self.request.send(res)
            except:
                print('error in ThreadedTCPRequestHandler :%s, res:%s' % (traceback.format_exc(), data))

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

class Server(Daemon):        
    def conf(self, host, port, obj):
        self.host = host
        self.port = port
        self.obj = obj
        ThreadedTCPServer.allow_reuse_address = True
    def run(self):
        ThreadedTCPRequestHandler._object = self.obj
        server = ThreadedTCPServer((self.host, self.port), ThreadedTCPRequestHandler)
        server.serve_forever()

if __name__ == '__main__':
    server = Server('/tmp/daemon-tortoise.pid')
    server.conf('0.0.0.0', 1990, Todo())
    if len(sys.argv) == 2:
        if 'start' == sys.argv[1]:
            server.start()
        elif 'stop' == sys.argv[1]:
            server.stop()
        elif 'restart' == sys.argv[1]:
            server.restart()
        else:
            print("Unknown command")
            sys.exit(2)
        sys.exit(0)
    else:
        print("usage: %s start|stop|restart" % sys.argv[0])
        sys.exit(2)

解释一下,上面这些代码是用python创建一个socket服务器,并且加入系统的守护进程。Todo里面实现策略工厂啥的,你懂的。使用方法:

python sever.py [start|stop|restart]
#接着设为系统启动项就O了。

php通过socket调用python

//代码中引用的文件将会在附件中给出,附件中还给出了php并发的写法
require 'socketapi.php';
header("Content-type: text/html; charset=utf-8");
$s = new server('192.168.1.8', 1990);
$code = <<<EOT
/*   美化:格式化代码,使之容易阅读            */
/*   净化:去掉代码中多余的注释、换行、空格等    */
/*   压缩:将代码压缩为更小体积,便于传输        */
/*   解压:将压缩后的代码转换为人可以阅读的格式    */

/*   如果有用,请别忘了推荐给你的朋友:        */
/*   javascript在线美化、净化、压缩、解压:http://box.inote.cc/js   */

/*   以下是演示代码                */

    var getPositionLite = function(el) {        var x = 0,        y = 0;        while (el) {            x += el.offsetLeft || 0;            y += el.offsetTop || 0;            el = el.offsetParent        }        return {            x: x,            y: y        }    };
/*   更新记录:                    */
    var history = {
        'v1.0':    ['2011-01-18','javascript工具上线']
    };
EOT;
$res = $s->obj('Todo')->test($code);
echo '<pre>'.$res.'</pre>';

附件,你懂的。

client.zip | server.zip

标签: php, python

已有 8 条评论

  1. 护国程序 护国程序

    有大神遇到这个问题嘛
    ErrnoA PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot.
    我加了一段php多线程代码 参考这个
    https://segmentfault.com/q/1010000002557069

  2. 护国程序 护国程序

    [root@iZ9478owwe7Z py]# python server.py stop
    Welcome!
    pidfile /tmp/daemon-tortoise.pid does not exist. Daemon not running?

  3. 护国程序 护国程序

    一点都看不懂 请问我自己的业务python代码怎么加进去

  4. [...]原文:http://type.so/python/php-call-python.html[...]

  5. 好吧,我没有考虑到分包的情况。

  6. 你的python版本是多少呢? 我的是刚装的3.2版的,出现了不少语法错误。折腾了一番总算看到了---Welcome!
    usage: server.py start|stop|restart
    写的很不错!学习了!并赞一个!

    1. 2.7很多第三方的模块还不支持3.2

  7. 鼓掌膜拜~~~~

添加新评论