在进行Web应用程序开发的时候,人们经常会用Session存储数据。但可能有人不知道,在PHP中,Session使用不当可能会引起并发问题。印度医疗行业软件解决方案提供商Plus91 Technologies高级工程师Kishan Gor在个人博客上对这个问题进行了阐释。 如果同一个客户端并发发送多个请求,而每个请求都使用了Session,那么PHP Session锁的存在会导致服务器串行响应这些请求,而不是并行。这是因为在默认情况下,PHP使用文件存储Session数据。对于每一个新的 Session,PHP会创建一个文件,并持续向其中写入数据。所以,每次调用session_start()方法,就会打开Session文件,并取得 文件的独占锁。这样,如果服务器脚本正在处理一个请求,而客户端又发送了一个同样需要使用Session的请求,那么后一个请求会阻塞,直至前一个请求处 理完成释放了文件上的独占锁。不过,这只限于来自同一个客户端的多个请求,也就是说,来自一个客户端的请求并不会阻塞另一个客户端的请求。 如果脚本很短,这通常没有问题。但如果脚本运行时间比较长,那就可能会产生问题。在现代Web应用程序开发中,有一个非常常见的情况,就是使用…
PHP与Python进行数据交互, PHP传参数给Python, Python接受php参数, PHP调用python
思路
我解决此问题的方法是利用了PHP
的passthru
函数来调用命令运行Python
脚本。
实现
在PHP中调用命令运行Python脚本
//php.php <?php $params = "value"; #传递给python脚本的入口参数 $path="python python.py "; //需要注意的是:末尾要加一个空格 passthru($path.$params);//等同于命令`python python.py 参数`,并接收打印出来的信息 ?>
若存在多个参数,则参数之间以空格
分开
在Python中接收PHP传入的参数
sys.argv[]
用于获取到的PHP传入python的入口参数
//python.py import sys params = sys.argv[1] #即为获取到的PHP传入python的入口参数 print(params);
若在Python中接收多个参数
params = sys.argv[1:]
从Python中返回参数
若要从Python中返回多个值
,需要将值写入元组
中,然后通过json.dumps()
转化为json
,并进行打印,PHP中通过passthru
可以获得Python脚本打印的json
import sys import json params = ('Google', 'Runoob', 1997, 2000); json_str =json.dumps(params); print(json_str);
另需要在PHP中passthru
前加@
,否则会报以下提示
Notice: Array to string conversion in php.php on line 6
效果
运行调用Python脚本的PHP文件,浏览器中输出值为Python打印的值
另一种尝试:popen — 打开进程文件指针
关于具体如何使用,去看官网api说明:
http://php.net/manual/zh/function.popen.php
然后把popen的参数,改为对应的python文件的路径,应该就可以了。
popen ( string $command
, string $mode
) : resource
<?php error_reporting(E_ALL); /* 加入重定向以得到标准错误输出 stderr。 */ $handle = popen('/path/to/executable 2>&1', 'r'); echo "'$handle'; " . gettype($handle) . "\n"; $read = fread($handle, 2096); echo $read; pclose($handle); ?>
如果需要双向支持,使用 proc_open()。
proc_open ( string $cmd
, array $descriptorspec
, array &$pipes
[, string $cwd
[, array $env
[, array $other_options
]]] ) : resource
<?php $descriptorspec = array( 0 => array("pipe", "r"), // 标准输入,子进程从此管道中读取数据 1 => array("pipe", "w"), // 标准输出,子进程向此管道中写入数据 2 => array("file", "/tmp/error-output.txt", "a") // 标准错误,写入到一个文件 ); $cwd = '/tmp'; $env = array('some_option' => 'aeiou'); $process = proc_open('php', $descriptorspec, $pipes, $cwd, $env); if (is_resource($process)) { // $pipes 现在看起来是这样的: // 0 => 可以向子进程标准输入写入的句柄 // 1 => 可以从子进程标准输出读取的句柄 // 错误输出将被追加到文件 /tmp/error-output.txt fwrite($pipes[0], '<?php print_r($_ENV); ?>'); fclose($pipes[0]); echo stream_get_contents($pipes[1]); fclose($pipes[1]); // 切记:在调用 proc_close 之前关闭所有的管道以避免死锁。 $return_value = proc_close($process); echo "command returned $return_value\n"; } ?>
以上例程的输出类似于:
Array ( [some_option] => aeiou [PWD] => /tmp [SHLVL] => 1 [_] => /usr/local/bin/php ) command returned 0
参见
- popen() – 打开进程文件指针
- exec() – 执行一个外部程序
- system() – 执行外部程序,并且显示输出
- passthru() – 执行外部程序并且显示原始输出
- stream_select() – Runs the equivalent of the select() system call on the given arrays of streams with a timeout specified by tv_sec and tv_usec
- The 执行操作符
利用popen实现php和python交互的实例
test.py
import sys print sys.argv
php:
<?php error_reporting(E_ALL); $cmd="python test.py test"; $handle=popen($cmd,"r"); $data=fread($handle,4096); echo $data; pclose($handle);
另一种尝试:通过端口交互
使用php、python结合写了一个简单的小玩意,python作为一个服务器监听本地的一个端口,php作为客户端向python服务器传递参数,python在服务器端执行ls -l并将结果返回给客户端。
server.py
#!/usr/bin/python import socket import subprocess socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) socket.bind(('127.0.0.1',8001)) socket.listen(5) while True: connection,addr = socket.accept() buf=connection.recv(1024) d=subprocess.Popen('ls -l /tmp', stdout=subprocess.PIPE, shell=True) connection.send("You give me" + buf+"\n") connection.send("".join(d.stdout.readlines())) connection.close()
client.php
<?php $handle = fsockopen("127.0.0.1",8001); if($handle) { fputs($handle,"/home/sky/python"); while($line=fgets($handle,1024)) { echo $line; } } fclose($handle);
本文:PHP与Python进行数据交互, PHP传参数给Python, Python接受php参数, PHP调用python