-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Swoole AI Assistant] translate to en
- Loading branch information
Showing
9 changed files
with
578 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"latest_commit":"8e5bc8856cde91b53e08f20728b3edceafb79f07"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# Windows Compilation | ||
|
||
> Only supports `PHP-8.1` or higher | ||
|
||
## PHP Development Environment | ||
|
||
Refer to: [https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2](https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2) | ||
|
||
|
||
|
||
- Install `Visual C++ 16.0`, address: [https://aka.ms/vs/16/release/vs_buildtools.exe](https://aka.ms/vs/16/release/vs_buildtools.exe) | ||
|
||
- Install `php-sdk-binary-tools`, address: [https://github.com/php/php-sdk-binary-tools](https://github.com/php/php-sdk-binary-tools) | ||
|
||
- Download `php` source code | ||
- Install dependency libraries, address: [https://windows.php.net/downloads/php-sdk/deps/](https://windows.php.net/downloads/php-sdk/deps/) | ||
|
||
> All files related to `PHP` are installed in the `d:\workspace` directory | ||
|
||
## Python Development Environment | ||
|
||
|
||
|
||
- Install `Python`, address: [https://www.python.org/downloads/windows/](https://www.python.org/downloads/windows/) | ||
|
||
- Set `Path` environment variable, add `d:\python` to the list, execute `Python -V` in `Windows Terminal` | ||
- Set `PYTHONHOME` environment variable, pointing to `d:\python` | ||
|
||
> `Python` is installed in the `d:\python` directory | ||
```shell | ||
C:\WINDOWS\system32>python -V | ||
Python 3.12.1 | ||
|
||
echo %Path% | ||
echo %PYTHONHOME% | ||
``` | ||
|
||
|
||
|
||
## Build Directory | ||
|
||
```shell | ||
cd D:\workspace\php-sdk\php-sdk-binary-tools-2.2.0 | ||
phpsdk-vs16-x64.bat | ||
``` | ||
|
||
After successful execution, enter the `php-src` directory in this terminal | ||
|
||
```shell | ||
cd D:\workspace\php-sdk\php-sdk-binary-tools-2.2.0\phpdev\vs16\x64\php-8.1.5 | ||
phpsdk_deps -u | ||
``` | ||
|
||
Place extension projects in the `ext` directory of `php-src`, for example: `D:\workspace\php-sdk\php-sdk-binary-tools-2.2.0\phpdev\vs16\x64\php-8.1.5\ext\phpy`. You can also use the `mklink` command to create a symbolic link. | ||
|
||
|
||
|
||
## Compilation Configuration | ||
|
||
```shell | ||
$ buildconf --force | ||
Rebuilding configure.js | ||
Now run 'configure --help' | ||
configure --with-openssl --with-mysqlnd --with-mysqli --enable-mbstring --enable-pdo --with-pdo-mysql --with-curl --enable-cli --enable-opcache --disable-zts --enable-phpy=shared | ||
``` | ||
|
||
`--enable-phpy=shared` indicates enabling the `phpy` extension and compiling it into a `.dll` dynamic link library. | ||
|
||
After successful execution, the output: | ||
|
||
```shell | ||
... | ||
|
||
Generating main/config.w32.h | ||
Generating phpize | ||
Done. | ||
|
||
|
||
Enabled extensions: | ||
----------------------- | ||
| Extension | Mode | | ||
----------------------- | ||
| date | static | | ||
| hash | static | | ||
| json | static | | ||
| pcre | static | | ||
| phpy | shared | | ||
| reflection | static | | ||
| spl | static | | ||
| standard | static | | ||
----------------------- | ||
|
||
|
||
Enabled SAPI: | ||
------------- | ||
| Sapi Name | | ||
------------- | ||
| cli | | ||
------------- | ||
|
||
|
||
--------------------------------------- | ||
| | | | ||
--------------------------------------- | ||
| Build type | Release | | ||
| Thread Safety | No | | ||
| Compiler | Visual C++ 2019 | | ||
| Architecture | x64 | | ||
| Optimization | PGO disabled | | ||
| Native intrinsics | SSE2 | | ||
| Static analyzer | disabled | | ||
--------------------------------------- | ||
|
||
|
||
Type 'nmake' to build PHP | ||
|
||
D:\workspace\php-sdk\php-sdk-binary-tools-2.2.0\phpdev\vs16\x64\php-8.1.5 | ||
$ | ||
``` | ||
|
||
|
||
|
||
## Compile Extensions | ||
```shell | ||
nmake clean | ||
nmake | ||
``` | ||
|
||
## Binary Packaging | ||
|
||
```shell | ||
nmake snap | ||
``` | ||
|
||
After successful execution, `php-8.1.5-nts-Win32-vs16-x64.zip` will be generated in `D:\workspace\php-sdk\php-sdk-binary-tools-2.2.0\phpdev\vs16\x64\php-8.1.5\x64\Release`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
# Inheriting `Python` Classes | ||
|
||
You can use the following method to make a `Python` class the parent class of a `PHP` class. | ||
|
||
## Install Composer Package | ||
|
||
This function requires an additional installation of the `phpy` composer extension package. | ||
|
||
```shell | ||
composer require swoole/phpy | ||
``` | ||
|
||
## Write PHP Class | ||
```php | ||
use phpy\PyClass; | ||
|
||
#[Inherit('Animal', 'animal')] | ||
class Dog extends PyClass | ||
{ | ||
protected string $weight; | ||
|
||
function __construct(string $name, int $age) | ||
{ | ||
parent::__construct(); | ||
// This attribute is not defined in the PHP layer and will be set as a Python attribute | ||
$this->color = 'black'; | ||
// This attribute is defined in the PHP layer and will not be set as a Python attribute | ||
$this->weight = '10kg'; | ||
// Read and write Python attribute | ||
$this->self()->color = 'black'; | ||
// Call Python method | ||
$this->get_age(); | ||
$this->self()->get_age(); | ||
// Call parent class constructor | ||
$this->super()->__init__($name, $age); | ||
} | ||
|
||
public function speak(string $name): void | ||
{ | ||
echo "Dog $name, color: {$this->self()->color}, speak: wang wang wang\n"; | ||
$this->super()->speak('dog'); | ||
} | ||
|
||
protected function test() | ||
{ | ||
debug_print_backtrace(); | ||
} | ||
|
||
// This method will not be mapped to the Python layer and cannot be used in Python | ||
private function get_weight(): string | ||
{ | ||
return $this->weight; | ||
} | ||
} | ||
``` | ||
|
||
- `PHP` classes must inherit from the `PyClass` base class. | ||
- Use the `#[Inherit('Animal', 'animal')]` attribute to declare the inheritance relationship. | ||
- The first parameter is the `Python` class name and the second parameter is the `Python` package name. | ||
|
||
- Supports multiple inheritance; you can add multiple `#[Inherit]` attributes. | ||
- The constructor of the subclass must execute the parent class's constructor `parent::__construct()`, or it will throw an error. | ||
|
||
|
||
## Call Base Class Constructor | ||
```php | ||
$this->super()->__init__($name, $age); | ||
``` | ||
|
||
It must be called after `parent::__construct()`, otherwise an error will occur. | ||
|
||
|
||
## Read and Write Properties | ||
```php | ||
$this->self()->color = 'black'; | ||
$this->color = 'red'; | ||
``` | ||
|
||
- If there are properties with the same name in both `PHP` and `Python` classes, the `Python` properties can be accessed using the `$this->self()` method. | ||
- Properties not defined in the `PHP` class can be accessed directly with `$this->{$attr}`, equivalent to `$this->self()->{$attr}`. | ||
|
||
|
||
## Call Methods | ||
```php | ||
$this->self()->get_age(); | ||
$this->get_age(); | ||
``` | ||
|
||
- If there are methods with the same name in both `PHP` and the `Python` parent class, the `Python` methods can be called using `$this->self()->{$method}()`. | ||
- Methods not defined in the `PHP` class can be called directly with `$this->{$method}()`, equivalent to `$this->self()->{$method}()`. | ||
|
||
|
||
## Call Parent Class Methods | ||
|
||
When the subclass and parent class have methods with the same name, you can call the parent class's method using `$this->super()->{$method}()`. | ||
|
||
```php | ||
$this->super()->speak('dog'); | ||
``` | ||
|
||
## Multiple Inheritance | ||
|
||
```php | ||
#[Inherit('Animal', 'animal')] | ||
#[Inherit('Base', 'dog')] | ||
class Dog extends PyClass {} | ||
``` | ||
|
||
This is equivalent to the following `Python` code: | ||
```python | ||
class Dog(Animal, Base): | ||
pass | ||
``` | ||
|
||
## Passing Objects to the `Python` Layer | ||
```php | ||
$framework = PyCore::import('framework'); | ||
$framework->run($this->self()); | ||
``` | ||
|
||
In certain scenarios, it is necessary to pass `PHP` objects to the `Python` layer. You can use the `$this->self()` method to get the `Python` object and pass it to the `Python` layer. When calling the object’s methods internally in `Python`, it will invoke the methods of the `PHP` class. | ||
|
||
> Only `public/protected` methods can be called by `Python`. | ||
|
||
## Set Proxy File Path | ||
```php | ||
phpy\PyClass::setProxyDir(__DIR__, true); | ||
``` | ||
|
||
- The first parameter is the path for the proxy file, and the `__phpy_proxy__` directory will be created in this directory, generating the proxy file, which defaults to the `getcwd()` path. | ||
- The second parameter determines whether to check if the proxy file is outdated; if the modification time of the proxy file is earlier than that of the `PHP` class file, the proxy file will be regenerated, defaulting to `false`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Memory Copy | ||
|
||
When `PHP` calls `Python` functions/methods, parameter and return value may involve memory copying, which needs to be considered when writing performance-sensitive programs. | ||
|
||
## Parameters | ||
|
||
- Integer, boolean, floating point, and null (`null`) are always passed by value. | ||
|
||
- Objects, resources, and references are always passed by reference, meaning no memory is copied. | ||
- Strings and arrays will undergo recursive deep copying to convert to native types. | ||
|
||
```php | ||
$user = PyCore::import("user"); | ||
$arg1 = 1234; | ||
$arg2 = 1234.5678; | ||
$arg3 = true; | ||
|
||
$arg4 = new PyDict(); | ||
$arg5 = new stdClass(); | ||
$arg6 = fopen("php://input", "r"); | ||
|
||
$arg7 = ['hello' => 'world']; | ||
$arg8 = "hello world"; | ||
$arg9 = [1, 2, 3, 4, 5]; | ||
|
||
$user->test($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8, $arg9); | ||
``` | ||
|
||
- `$arg1`, `$arg2`, and `$arg3` will be converted to integers, floating point, and boolean in `Python`, copying the values directly. | ||
|
||
- `$arg4`, `$arg5`, and `$arg6` will directly pass references to `Python`, resulting in no memory copies. | ||
- `$arg6`, `$arg7`, and `$arg8` will be traversed and deeply copied in memory, converting to `Python`'s `list`, `dict`, and `str`. | ||
|
||
## Return Values | ||
|
||
- Integers, booleans, floating point numbers, and null (`None` and `null`) will be converted to `PHP`'s native types. | ||
|
||
- All other returned content from `Python` will be of type `PyObject`. | ||
- You can also use `phpy.String` or `phpy.Array` in `Python` code to achieve transparent forwarding of `PHP` native types. | ||
|
||
## Avoiding Memory Copy | ||
Using the `PyObject::object($value)` method can convert string and array types to `PyObject`, where the type obtained in `Python` will be `phpy.String` and `phpy.Array`. | ||
|
||
This method requires the `Python` code to adapt to the `phpy` type system. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
|
||
Socket API | ||
===== | ||
In `phpy` programming development, it is often necessary to use the `Socket API` to write network communication programs. The following methods can be used to convert the `Python Socket object` and the `PHP Stream resource` to each other. | ||
|
||
Python to PHP | ||
----- | ||
```php | ||
$socket = PyCore::import('socket'); | ||
const HOST = "127.0.0.1"; | ||
const PORT = 5432; | ||
|
||
$client = $socket->socket($socket->AF_INET, $socket->SOCK_STREAM); | ||
$client->connect(PyCore::tuple([HOST, PORT])); | ||
|
||
$fp = fopen('php://fd/' . $client->fileno(), 'rw'); | ||
fwrite($fp, $msg); | ||
$data = fread($fp, 1024); | ||
fclose($fp); | ||
``` | ||
|
||
- Use the `Python Socket.fileno()` method to get the file descriptor. | ||
- Use `PHP fopen('php://fd/{$fileno}')` to convert the file handle corresponding to the `Socket` into a `PHP Stream`. | ||
- Use `fwrite/fread/fclose` to read, write, and close the handle. | ||
|
||
`fopen()` will copy the file descriptor, so calling `fclose()` will not affect the `Python Socket object`, and you can continue to use the `Python Socket API` to perform data transmission operations on this network connection. | ||
|
||
PHP to Python | ||
---- | ||
```php | ||
$socket = PyCore::import('socket'); | ||
|
||
$HOST = "127.0.0.1"; | ||
$PORT = 5432; | ||
|
||
$fp = stream_socket_client("tcp://$HOST:$PORT", $errno, $errstr, 30); | ||
if (!$fp) { | ||
exit("Error: $errstr ($errno)\n"); | ||
} | ||
$client = $socket->fromfd(PyCore::fileno($fp), $socket->AF_INET, $socket->SOCK_STREAM); | ||
fclose($fp); | ||
``` | ||
|
||
- Use the `PyCore::fileno($fp)` method to obtain the `PHP Stream` file descriptor. | ||
- Use `Python Socket.fromfd()` to convert the file handle corresponding to the `Socket` into a `Python Socket object`. | ||
|
||
`Socket.fromfd()` will copy the file descriptor, so closing the `Python Socket` will not affect the `PHP Stream`, and you can still use `PHP`'s `fwrite/fread/fclose` to perform data transmission operations on this network connection. |
Oops, something went wrong.