PHP 和 Python 速查手册

部署方式

PHP 的部署方式

PHP 程序有如下几种运行方式:

其中,CGI 和 FastCGI 以进程的方式运行,使用 nts(非线程安全)版本; ISAPI Extension 和 Apache Mod 以线程方式运行在宿主进程(IIS进程或Apache进程)内,使用 ts(线程安全)版本。

以上几种方式以 FastCGI 最为常见。PHP 5 自带的 php-cgi 可以直接运行 FastCGI 服务。不过在生产环境中,一般使用 PHP-FPM 作为 FastCGI 的进程管理工具。

Nginx + FastCGI 方式配置参考:https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/

PHP 的运行特点是一请求对应一进(线)程。服务器可以处理的 PHP 请求并发数受限于运行的 PHP 进(线)程总数。当一个请求结束,对应的 PHP 进(线)程也会退出(休眠),该请求中生成的上下文环境全部销毁。所以 PHP 最大缺陷就是每次请求都要重复获取配置信息,初始化程序环境。虽然也有以服务形式运行的 PHP 框架,如 SwooleWorkerman,但并不常见于生产环境。

Python Web 的部署方式

Python Web 程序有如下几种运行方式:

其中以 WSGI 和 uWSGI 两种方式最为常见。主流 HTTP Server 软件,如 Apache、Nginx 和 Lighttpd,都支持 WSGI 协议;此外还有 Gunicorn、Tornado、Gevent、Twisted Web、bjoern、Meinheld 等也可以作为 WSGI 容器,独立运行 Python Web 程序并提供 HTTP 访问接口。uwsgi 是实现 uWSGI 协议的容器,目前主流 HTTP Server 也都支持 uWSGI 协议。普遍认为,uwsgi 的性能要高于常见的 WSGI 部署方式。

Nginx + uWSGI 方式配置参考:http://uwsgi-docs.readthedocs.org/en/latest/Nginx.html

不同于 PHP,常见的 Python Web 框架都是以服务的方式运行的。Python 程序长时间运行可能会发生各种异常,所以一些容器支持设定处理若干个请求后自动重启 Python 进程。

语言对比

内建数据类型比较

PHPPython说明
booleanboolean布尔类型
intint [1]整型
floatfloat浮点型
-long [2]长整型
-fractions分数
-complex复数
-byte字节
stringstring [3]字符串
-tuple元组
-set集合
-bytearray字节数组
array [4]list列表
arraydict散列表(数组/字典) [5]
objectobject对象
nullNoneType空类型
resource-资源
callable [6]function函数/闭包/Lambda表达式
  1. Python 3.x 的 int 类型和 PHP 一样,最大值取决于系统平台; Python 2.x 的 int 类型为 32 位的。
  2. long 是 Python 2.x 的内置类型,Python 3.x 取消了该类型。
  3. Python 2.x 字符串分为 str 和 unicode 两种类型;Python 3.x 字符串皆为 unicode 类型。
  4. PHP 可以通过 array 类型来实现大部分列表的操作,虽然在实现方式上有很大的不同。
  5. PHP 的 array 是有序字典;Python的 dict 是无序字典,如果需要用到有序字典,可以使用 OrderedDict 类。
  6. PHP 5.4 之后引入 callable 类型。该类型可以是函数名称(字符串)、对象方法(数组)或者闭包(\Closure 对象)。

代码组织

PHP 以文件方式组织代码,语言本身对于文件目录结构没有任何要求。通过 requireinclude 语句来引用其他文件中的代码,或者使用 __autoload 来自动加载源代码文件。PSR-0PSR-4 定义了 PHP autoload 的规范。

PHPrequire __DIR__ . '/lib/import.php';

$obj = new ClassNotLoaded();

function __autoload($class) {
	// $name = 'ClassNotLoaded';
	require __DIR__ . "/lib/{$class}.php";
}

Python 是由 Package 和 Module 的方式来组织的。一个包含 __init__.py 文件的文件夹可以作为一个 Package,里面的文件可以是 Module。通过 importfrom ... import ... 语句来引用其他文件中的代码,还可以使用 __import__() 实现动态加载。Python 会从 sys.path 列表中保存的路径下去查找导入的包文件夹。

PYTHONimport sys
sys.path.append(my_lib_path)
from package_name import module_name

Python 2.7 开始,默认为绝对导入。之前版本需要开启。

PYTHONfrom __future__ import absolute_import

如果要进行相对导入,需要显示声明。

PYTHONfrom .package import module
from ..package import module

函数方法速查

字符串操作

PHPPython说明
$string = $str1 . $str2;string = str1 + str2字符串拼接
“My name is {$name}”;“My name is %(name)s” % {“name”: name}
“My name is %s” % (name)
“My name is {name}".format(name=name)
字符串格式化
ucfirst($string);string.capitalize()首字母大写
trim($string);string.strip()去除首尾空白字符
strtolower($string);string.lower()转换为小写字符
strtoupper($string);string.upper()转换为大写字符
substr($string, $i, $j - $i);string[i:j]获取字符串子串
explode(”,", “1,2,3,4”);“1,2,3,4”.split(",")展开字符串为数组/列表
implode(",", [1, 2, 3, 4]);“,".join(map(str, [1, 2, 3, 4]))合并数组/列表为字符串
false !== strpos(‘php’, ‘h’);’t’ in ‘python’查找字符串是否包含子串
strlen($string);len(string)字符串长度

数组/列表操作

PHPPython说明
$array[] = $item;array.append(item)向数组/列表末尾添加元素
array_push($array, $item1, $item2);array.extend([item1, item2])向数组末尾添加多个元素
array_splice($array, $pos, 0, $item);array.insert(pos, item)指定位置插入元素
array_unshift($array, $item);array.insert(0, item)向数组/列表头部插入元素
$item = array_pop($array);item = array.pop()模拟栈,将末尾元素出栈
array_splice($array, $pos, 1);del array[pos]删除数组/列表的元素
$array = $array1 + $array2;array = array1 + array2数组/列表相加
array_search($item, $array);array.index(item)查找元素所在位置
count($array);len(array)获取数组/列表长度
array_count_values($array)[item];array.count(item)统计元素在数组/列表里出现次数
array_slice($array, $i, $j);array[i:j]切片操作
min($array);
max($array);
min(array)
max(array)
求元素最小/大值
in_array($item, $array);item in array元素是否存在
sort($array);array.sort()排序

数组/字典操作

PHPPython说明
unset($array[$key]);del array[key]删除键值对
array_key_exists($key, $array);
isset($array[$key]);
key in array
array.has_key(key)
键名是否存在
array_values($array);array.values()获取全部值组成的数组/列表
array_keys($array);array.keys()获取全部键名组成的数组/列表
array_merge($array1, $array2);dict(array1, **array2)合并两个数组/字典
array_combine($keys, $values);dict(zip(keys, values))用两个数组/列表分别作为数组/字典的键名和值

PHP 数组遍历

$array = [1, 2, 3, 4];
for ($i = 0; $i < count($array); $i++) {
    echo 'key:', $i, '; ';
    echo 'value:', $array[$i], PHP_EOL;
}

$array = [1, 2, 3, 'k1' => 'v1', 'k2' => 'v2'];
foreach ($array as $key => $value) {
    echo 'key:', $key, '; ';
    echo 'value:', $value, PHP_EOL;
}

foreach ($array as $item) {
    echo 'value:', $item, PHP_EOL;
}

Python list/dict 遍历

array = [1, 2, 3, 4]
for item in array:
    print('value: %i' % (item))

for index, value in enumerate(array):
    print('index: %i; value: %i' % (index, value))

array = {'k1': 'v1', 'k2': 'v2'}
for key in array:
    print('key: %s; value: %s' %(key, array[key]))

for key, value in array.items():
    print('key: %s; value: %s' %(key, value))

for key, value in array.iteritems():
    print('key: %s; value: %s' %(key, value))

.items().iteritems() 区别在于前者返回一个列表,后者返回一个可迭代对象,更加节省内存。在 Python 3 里,.items() 也返回一个可迭代对象,取消了 .iteritems() 方法。

Python 内建函数

PHPPython说明
abs()abs()绝对值
-all()所有值为 true/True
-any()存在任意值为 true/True
-basestring()unicode字符串和普通字符串的基类
decbin()bin()将整数转换成二进制字面表示
boolval()bool()生成一个布尔类型对象
-bytearray()
is_callable()callale()是否是可调用对象
chr()chr()返回 ASCII 字符
-classmethod()
-cmp()
-compile()
-complex()
-delattr()
array()dict()生成一个数组/字典类型对象
-dir()
-divmod()
-enumerate()
eval()eval()
require
include
execfile()执行文件内的代码
new SplFileObject()file()创建一个文件类型对象
array_filter()filter()过滤数组/可迭代对象
floatval()float()生成一个浮点类型的对象
-format()
-frozenset()
$object->$attr_namegetattr()
$GLOBALSglobals()返回所有全局变量
method_exists()
property_exists()
hasattr()
-help()
dechex()hex()将整数转换成十六进制字面表示
spl_object_hash()id()返回对象的唯一 id
-input()
intval()int()生成一个整型对象
instanceof
is_a()
isinstance()判断对象是否为某个类的实例
is_subclass_of()issubclass()判断类是否是某个类的子类
SPL Iteratorsiter()将可迭代对象转换成一个迭代器
iterator_count()
count()
strlen()
len()返回数组/迭代对象/字符串的长度(元素个数)
array()list()生成一个数组/列表对象
get_defined_vars()locals()获取所有本地变量
intval()long()生成一个长整型对象
array_map()
iterator_apply()
map()遍历数组/可迭代对象的元素生成新的对象
max()max()获取最大值
-memoryview()
min()min()获取最小值
next()next()获取可迭代对象的下一个元素
-object()
decoct()oct()将数字转换成十进制字面表示
fopen()open()打开文件
ord()ord()返回字符的 ASCII 码
pow()pow()求指数
echo
print()
print()输出
-property()
range()range()返回一个指定范围的数组/列表
-raw_input()
array_reduce()reduce()迭代计算数组/可迭代对象
-reload()
var_export()repr()输出一个可打印的对象
var_dump()pprint.pprint()格式化输出对象
array_reverse()reversed()倒序排列数组/可迭代对象
round()round()对浮点数四舍五入
-set()
$object->$attr_name = $valuesetattr()设置对象的属性值
-slice()
usort()sorted()对数组/列表/可迭代对象排序
-staticmethod()
-str()
array_sum()sum()计算元素数值的总和
parent
get_parent_class()
super()获取父类或父类对象
-tuple()
gettype()type()获取对象类型
-unichr()
-unicode()
get_object_vars()
get_class_vars()
vars()获取对象/类的成员属性和值
-xrange()
-zip()
require
include
__import__()动态载入模块/代码文件

文件操作函数

PHPPython说明
file_exists()os.path.exists()判断文件是否存在
is_file()os.path.isfile()判断是否是文件
is_dir()os.path.isdir()判断是否是目录
is_link()os.path.islink()判断是否是链接
basename()os.path.basename()获取文件名称
dirname()os.path.dirname()获取文件路径
filesize()os.path.getsize()获取文件大小
fileatime()os.path.getatime()获取文件访问时间
filemtime()os.path.getmtime()获取文件修改时间
filectime()os.path.getctime()获取文件创建时间
realpath()os.path.realpath()获取真实路径