ext-php-rs 0.3.2

Bindings for the Zend API to build PHP extensions natively in Rust.
Documentation
# `#[php_impl]`

You can export an entire `impl` block to PHP. This exports all methods as well
as constants to PHP on the class that it is implemented on. This requires the
`#[php_class]` macro to already be used on the underlying struct. Trait
implementations cannot be exported to PHP.

If you do not want a function exported to PHP, you should place it in a seperate
`impl` block.

## Methods

Methods basically follow the same rules as functions, so read about the
[`php_function`] macro first. The primary difference between functions and
methods is they are bounded by their class object.

Class methods can take a `&self` or `&mut self` parameter. They cannot take a
consuming `self` parameter. Static methods can omit this `self` parameter.

As there is no attribute directly on the method, options are passed as separate
attributes:

- `#[defaults(i = 5, b = "hello")]` - Sets the default value for parameter(s).
- `#[optional(i)]` - Sets the first optional parameter. Note that this also sets
  the remaining parameters as optional, so all optional parameters must be a
  variant of `Option<T>`.
- `#[public]`, `#[protected]` and `#[private]` - Sets the visibility of the
  method.

The `#[defaults]` and `#[optional]` attributes operate the same as the
equivalent function attribute parameters.

## Constants

Constants are defined as regular Rust `impl` constants. Any type that implements
`IntoZval` can be used as a constant. Constant visibility is not supported at
the moment, and therefore no attributes are valid on constants.

## Example

Continuing on from our `Human` example in the structs section, we will define a
constructor, as well as getters for the properties. We will also define a
constant for the maximum age of a `Human`.

```rust
# extern crate ext_php_rs;
# use ext_php_rs::prelude::*;
# #[php_class]
# #[derive(Default)]
# pub struct Human {
#     name: String,
#     age: i32
# }
#[php_impl]
impl Human {
    const MAX_AGE: i32 = 100;

    pub fn __construct(&mut self, name: String, age: i32) {
        self.name = name;
        self.age = age;
    }

    pub fn get_name(&self) -> String {
        self.name.to_string()
    }

    pub fn get_age(&self) -> i32 {
        self.age
    }

    pub fn introduce(&self) {
        use ext_php_rs::php::types::object::RegisteredClass;
        
        // SAFETY: The `Human` struct is only constructed from PHP.
        let address: String = unsafe { self.get_property("address") }.unwrap();
        println!("My name is {} and I am {} years old. I live at {}.", self.name, self.age, address);
    }

    pub fn get_max_age() -> i32 {
        Self::MAX_AGE
    }
}
```

Using our newly created class in PHP:

```php
<?php

$me = new Human('David', 20);

$me->introduce(); // My name is David and I am 20 years old.
var_dump(Human::get_max_age()); // int(100)
var_dump(Human::MAX_AGE); // int(100)
```

[`php_function`]: ./function.md