blyxxyz/python-server

从Python调用PHP代码的方法

dev-master 2020-04-17 17:59 UTC

This package is not auto-updated.

Last update: 2024-09-29 05:09:18 UTC


README

这是一个运行PHP程序的Python模块。它允许你导入PHP函数、类、对象、常量和变量,以便像常规Python版本一样工作。

示例

你可以调用函数

>>> from phpbridge import php
>>> php.array_reverse(['foo', 'bar', 'baz'])
Array.list(['baz', 'bar', 'foo'])
>>> php.echo("foo\n")
foo
>>> php.getimagesize("https://php.ac.cn/images/logos/new-php-logo.png")
Array([('0', 200), ('1', 106), ('2', 3), ('3', 'width="200" height="106"'), ('bits', 8), ('mime', 'image/png')])

你可以创建和使用对象

>>> php.DateTime
<PHP class 'DateTime'>
>>> date = php.DateTime()
>>> print(date)
<DateTime PHP object (date='2018-05-03 22:59:15.114277', timezone_type=3, timezone='Europe/Berlin')>
>>> date.getOffset()
7200
>>> php.ArrayAccess
<PHP interface 'ArrayAccess'>
>>> issubclass(php.ArrayObject, php.ArrayAccess)
True

你可以使用关键字参数,尽管PHP不支持它们

>>> date.setDate(year=1900, day=20, month=10)
<DateTime PHP object (date='1900-10-20 22:59:15.114277', timezone_type=3, timezone='Europe/Berlin')>

你可以遍历迭代器和可遍历对象

>>> for path, file in php.RecursiveIteratorIterator(php.RecursiveDirectoryIterator('.git/logs')):
...     print("{}: {}".format(path, file.getSize()))
...
.git/logs/.: 16
.git/logs/..: 144
.git/logs/HEAD: 2461
[...]

你可以获得帮助

>>> help(php.echo)
Help on function echo:

echo(arg1, *rest)
    Output one or more strings.

    @param mixed $arg1
    @param mixed ...$rest

    @return void

你可以将命名空间导入为模块

>>> from phpbridge.php.blyxxyz.PythonServer import NonFunctionProxy
>>> help(NonFunctionProxy)
Help on class blyxxyz\PythonServer\NonFunctionProxy in module phpbridge.php.blyxxyz.PythonServer:

class blyxxyz\PythonServer\NonFunctionProxy(phpbridge.objects.PHPObject)
 |  Provide function-like language constructs as static methods.
 |
 |  `isset` and `empty` are not provided because it's impossible for a real
 |  function to check whether its argument is defined.
 |
 |  Method resolution order:
 |      blyxxyz\PythonServer\NonFunctionProxy
 |      phpbridge.objects.PHPObject
 |      builtins.object
 |
 |  Class methods defined here:
 |
 |  array(val) -> dict from phpbridge.objects.PHPClass
 |      Cast a value to an array.
 |
 |      @param mixed $val
 |
 |      @return array
[...]

你可以索引并获取长度

>>> arr = php.ArrayObject(['foo', 'bar', 'baz'])
>>> arr[10] = 'foobar'
>>> len(arr)
4

你可以处理PHP的异常

>>> try:
...     php.get_resource_type(3)
... except php.TypeError as e:
...     print(e.getMessage())
...
get_resource_type() expects parameter 1 to be resource, integer given

功能

  • 使用PHP函数
    • 支持关键字参数,并根据签名进行转换
    • 文档块也被转换,所以help是有信息的
  • 像Python类一样使用PHP类
    • 根据PHP类立即定义方法和常量
    • 文档块被当作文档字符串处理,所以help既起作用又具有信息性
    • 复制了原始的继承结构
    • 默认属性变为带有文档的Python属性
    • 其他属性作为属性访问的备用方案,在运行时访问
  • 创建和使用对象
  • 将命名空间导入为模块
  • 获取和设置常量
  • 获取和设置全局变量
  • 转换异常,以便它们可以被视为Python异常和PHP对象
  • 解释器的Tab补全
  • PHP对象的Python-like reprs,以比var_dump更紧凑的形式提供信息

注意事项

  • 在Windows上,使用stdin和stderr进行通信,因此PHP无法读取输入,如果写入stderr,则连接丢失
  • 你只能将基本Python对象传递到PHP中
  • 命名空间可以以不可直观的方式遮蔽名称
  • 因为PHP只有一种类型的数组,所以其数组被转换为特殊类型的有序字典

名称冲突

一些PHP包同时使用相同的名称作为类和命名空间。以nikic/PHP-Parser为例。

PhpParser\Node是一个类,但PhpParser\Node\Param也是一个类。这意味着phpbridge.php.PhpParser.Node变得模糊——它可能指的是Node类,或者Param类的命名空间。

在这种情况下,优先选择类而不是命名空间。要获取Param,必须使用from导入

>>> php.require('vendor/autoload.php')
<Composer.Autoload.ClassLoader PHP object (prefixLengthsPsr4=[...: (4)], ...>
>>> import phpbridge.php.PhpParser.Node as Node           # Not the namespace!
>>> Node
<PHP interface 'PhpParser\Node'>
>>> from phpbridge.php.PhpParser.Node import Param        # The class we want
>>> Param
<PHP class 'PhpParser\Node\Param'>
>>> import phpbridge.php.PhpParser.Node.Param as Param    # Doesn't work
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'PhpParser\Node' has no attribute 'Param'

如果没有冲突,一切按预期进行

>>> from phpbridge.php.blyxxyz.PythonServer import Commands
>>> Commands
<PHP class 'blyxxyz\PythonServer\Commands'>
>>> import phpbridge.php.blyxxyz.PythonServer as PythonServer
>>> PythonServer
<PHP namespace 'blyxxyz\PythonServer'>
>>> PythonServer.Commands
<PHP class 'blyxxyz\PythonServer\Commands'>

安装

pip3 install phpbridge

唯一的依赖项是PHP 7.0+、Python 3.5+、ext-json、ext-reflection和ext-mbstring。可以使用Composer安装开发工具和设置自动加载,但这不是必需的。