Skip to content

Commit

Permalink
Optimize inherit code
Browse files Browse the repository at this point in the history
  • Loading branch information
matyhtf committed Sep 6, 2024
1 parent 2148dd5 commit bca7b42
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 13 deletions.
1 change: 1 addition & 0 deletions docs/cn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ PHP 扩展
* [性能测试](benchmark.md)
* [IDE 提示](php/composer.md)
* [Socket API](php/socket.md)
* [继承 Python 类](php/inherit.md)

Python 模块
---
Expand Down
54 changes: 45 additions & 9 deletions docs/cn/php/inherit.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,40 @@ use phpy\PyClass;
#[parent('Animal', 'animal')]
class Dog extends PyClass
{
protected string $weight;

function __construct(string $name, int $age)
{
parent::__construct();
// 此属性未在 PHP 层定义,将会设置为 Python 属性
$this->color = 'black';
// 此属性由 PHP 层定义,不会设置为 Python 属性
$this->weight = '10kg';
// 读写 Python 属性
$this->self()->color = 'black';
// 调用 Python 方法
$this->get_age();
$this->self()->get_age();
// 调用父类构造方法
$this->super()->__init__($name, $age);
}

function speak(string $name): void
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();
}

// 此方法不会映射到 Python 层,无法在 Python 中使用
private function get_weight(): string
{
return $this->weight;
}
}
```

Expand All @@ -45,24 +67,27 @@ $this->super()->__init__($name, $age);

必须在 `parent::__construct()` 之后调用,否则会报错。

## 读写 Python 属性
## 读写属性
```php
$this->self()->color = 'black';
```

## 读写 PHP 属性
```php
$this->color = 'red';
```

## 调用 Python 对象方法
- `PHP` 类和 `Python` 类有同名属性,可以使用 `$this->self()` 方法访问 `Python` 属性
-`PHP` 类中未定义的属性,可以直接使用 `$this->{$attr}` 访问,等同于 `$this->self()->{$attr}`

## 调用方法
```php
$this->self()->speak('dog');
$this->self()->get_age();
$this->get_age();
```

- `PHP` 类和 `Python` 父类有同名方法,可以使用 `$this->self()->{$method}()` 调用 `Python` 方法
-`PHP` 类中未定义的方法,可以直接使用 `$this->{$method}()` 调用,等同于 `$this->self()->{$method}()`

## 调用父类方法

当子类和父类有同名方法时,可以使用 `super()` 方法调用父类的方法。
当子类和父类有同名方法时,可以使用 `$this->super()->{$method}()` 方法调用父类的方法。

```php
$this->super()->speak('dog');
Expand All @@ -76,6 +101,17 @@ $this->super()->speak('dog');
class Dog extends PyClass {}
```

## 传递对象到 `Python`
```php
$framework = PyCore::import('framework');
$framework->run($this->self());
```

某些场景需要将 `PHP` 对象传递到 `Python` 层,可以使用 `$this->self()` 方法获取 `Python` 对象,
将对象传递给 `Python` 层。当在 `Python` 内部调用对象方法时,将会调用 `PHP` 类的方法。

> `public/protected` 方法可以被 `Python` 调用
## 设置代理文件路径
```php
phpy\PyClass::setProxyDir(__DIR__, true);
Expand Down
7 changes: 6 additions & 1 deletion examples/class/Dog.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ class Dog extends PyClass
function __construct(string $name, int $age)
{
parent::__construct();
$this->self()->color = 'black';
$this->color = 'black';
$this->super()->__init__($name, $age);
}

protected function test()
{
debug_print_backtrace();
}

function speak(string $name): void
{
echo "Dog $name, color: {$this->self()->color}, speak: wang wang wang\n";
Expand Down
3 changes: 3 additions & 0 deletions examples/class/animal.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ def __init__(self, name, age):
def speak(self, name):
print("Animal speak, Age: ", self.age)
pass

def get_age(self):
return self.age
3 changes: 3 additions & 0 deletions examples/class/proxy_class.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@

$dog = new Dog('dog', 1);
$dog->speak('hello');
var_dump($dog->age);
$dog->age = 3;
var_dump($dog->get_age());
24 changes: 21 additions & 3 deletions lib/phpy/PyClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,14 @@ private function makeProxy(): void
}
}

$refMethods = $ref->getMethods(ReflectionMethod::IS_PUBLIC);
$refMethods = $ref->getMethods();
$methods = [];
foreach ($refMethods as $method) {
$modifiers = $method->getModifiers();
if (str_starts_with($method->name, '__') or $modifiers & ReflectionMethod::IS_STATIC) {
if (str_starts_with($method->name, '__')
or ($modifiers & ReflectionMethod::IS_STATIC)
or ($modifiers & ReflectionMethod::IS_PRIVATE)
or ($modifiers & ReflectionMethod::IS_ABSTRACT)) {
continue;
}
$refParams = $method->getParameters();
Expand Down Expand Up @@ -99,7 +102,7 @@ protected function super(): ?PyObject
return $this->_super;
}

protected function self(): ?PyObject
public function self(): ?PyObject
{
return $this->_self;
}
Expand Down Expand Up @@ -142,4 +145,19 @@ private function checkProxyFile(): void
unlink($this->_proxyFile);
}
}

public function __get($name)
{
return $this->_self->{$name};
}

public function __set($name, $value)
{
$this->_self->{$name} = $value;
}

public function __call($name, $arguments)
{
return $this->_self->{$name}(...$arguments);
}
}

0 comments on commit bca7b42

Please sign in to comment.