Skip to content

Commit

Permalink
Update README.md for improved clarity and completeness
Browse files Browse the repository at this point in the history
Update the README with detailed installation steps, expanded usage examples, and a comprehensive explanation of the extension's design. Clarify the relationship and integration with Ray.Aop and provide concise instructions for building, testing, and contributing to the project.
  • Loading branch information
koriym committed Nov 5, 2024
1 parent 2b5b83a commit fff2983
Showing 1 changed file with 79 additions and 103 deletions.
182 changes: 79 additions & 103 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,165 +4,141 @@

<img src="https://ray-di.github.io/images/logo.svg" alt="ray-di logo" width="150px;">

A PHP extension that provides Aspect-Oriented Programming (AOP) functionality for method interception, designed to complement Ray.Aop.
Low-level PHP extension that provides core method interception functionality for [Ray.Aop](https://github.com/ray-di/Ray.Aop). While this extension can be used standalone, it is designed to be a foundation for Ray.Aop's more sophisticated AOP features.

## Features

- Efficient method interception for specific classes
- Apply custom logic before and after method execution
- Works with `final` classes and methods
- Efficient low-level method interception
- Support for intercepting final classes and methods
- Full parameter and return value modification support
- Works seamlessly with the `new` keyword

## Requirements

- PHP 8.1 or higher
- Linux, macOS, or Windows with appropriate build tools

## Installation

1. Clone the repository:

```
```bash
git clone https://github.com/ray-di/ext-rayaop.git
cd ext-rayaop
```

2. Build and install the extension:

```
```bash
phpize
./configure
make --enable-rayaop-quiet // Suppress E_NOTICE to indicate experimental.
make
make install
```

3. Add the following line to your php.ini file:

```ini
extension=rayaop.so # For Unix/Linux
extension=rayaop.dll # For Windows
```
extension=rayaop.so

4. Verify installation:
```bash
php -m | grep rayaop
```

## About this Extension
## Design Decisions

This PECL extension is designed to enhance Ray.Aop by providing method interception capabilities at a lower level. While it can be used independently, it's primarily intended to be used in conjunction with Ray.Aop for optimal functionality.
This extension provides minimal, high-performance method interception capabilities:

Key points:
- The extension intentionally binds only one interceptor per method for simplicity and performance.
- Multiple interceptor chaining should be implemented in PHP code, either using Ray.Aop or custom implementation.
- The main advantages are the ability to intercept `final` classes/methods and unrestricted use of the `new` keyword.
- One interceptor per method: The extension supports a single active interceptor per method, with the last registered interceptor taking precedence
- Final class support: Can intercept final classes and methods, unlike pure PHP implementations
- Raw interception: No built-in matching or conditions (use Ray.Aop for these features)

## Usage
## Relationship with Ray.Aop

### Defining an Interceptor
This extension provides low-level method interception, while [Ray.Aop](https://github.com/ray-di/Ray.Aop) offers high-level AOP features:

Create a class that implements the `Ray\Aop\MethodInterceptorInterface`:
Ray.Aop provides:
- Conditional interception using Matchers
- Multiple interceptors per method
- Attribute/Annotation based interception
- Sophisticated AOP features

```php
namespace Ray\Aop {
interface MethodInterceptorInterface
{
public function intercept(object $object, string $method, array $params): mixed;
}
}
When both are used together:
- Ray.Aop handles the high-level AOP logic
- This extension provides the low-level interception mechanism
- Ray.Aop automatically utilizes this extension when available for better performance

## Basic Usage

class MyInterceptor implements Ray\Aop\MethodInterceptorInterface
### Simple Interceptor
```php
class LoggingInterceptor implements Ray\Aop\MethodInterceptorInterface
{
public function intercept(object $object, string $method, array $params): mixed
{
echo "Before method execution\n";
$result = call_user_func_array([$object, $method], $params);
echo "After method execution\n";
echo "Before {$method}\n";
$result = $object->$method(...$params);
echo "After {$method}\n";
return $result;
}
}
```

### Registering an Interceptor

Use the `method_intercept` function to register an interceptor for a specific class and method:

```php
$interceptor = new MyInterceptor();
method_intercept('TestClass', 'testMethod', $interceptor);
// Register the interceptor
method_intercept(TestClass::class, 'testMethod', new LoggingInterceptor());
```

### Complete Example

### Intercepting Final Methods
```php
class TestClass
final class FinalClass
{
public function testMethod($arg)
final public function finalMethod($value)
{
echo "TestClass::testMethod($arg) called\n";
return "Result: $arg";
return "Final: {$value}";
}
}

$interceptor = new MyInterceptor();
method_intercept('TestClass', 'testMethod', $interceptor);

$test = new TestClass();
$result = $test->testMethod("test");
echo "Final result: $result\n";
```

Output:
```
Before method execution
TestClass::testMethod(test) called
After method execution
Final result: Result: test
method_intercept(FinalClass::class, 'finalMethod', new LoggingInterceptor());
$instance = new FinalClass();
echo $instance->finalMethod('test'); // Interceptor will be invoked
```

## Integration with Ray.Aop
## Development

For more complex AOP scenarios, it's recommended to use this extension in combination with [Ray.Aop](https://github.com/ray-di/Ray.Aop). Ray.Aop provides a higher-level API for managing multiple interceptors and more advanced AOP features.

## The Power of AOP

Aspect-Oriented Programming (AOP) is a powerful paradigm that complements Object-Oriented Programming (OOP) in building more flexible and maintainable software systems. By using AOP:

1. **Separation of Concerns**: You can cleanly separate cross-cutting concerns (like logging, security, or transaction management) from your core business logic.

2. **Enhanced Modularity**: AOP allows you to modularize system-wide concerns that would otherwise be scattered across multiple classes.

3. **Improved Code Reusability**: Aspects can be reused across different parts of your application, reducing code duplication.

4. **Easier Maintenance**: By centralizing certain behaviors, AOP can make your codebase easier to maintain and evolve over time.

5. **Non-invasive Changes**: You can add new behaviors to existing code without modifying the original classes, adhering to the Open/Closed Principle.

6. **Dynamic Behavior Modification**: With this PECL extension, you can even apply aspects to final classes and methods, providing unprecedented flexibility in your system design.

By combining the strengths of OOP and AOP, developers can create more robust, flexible, and easier-to-maintain software architectures. This PECL extension, especially when used in conjunction with Ray.Aop, opens up new possibilities for structuring your PHP applications, allowing you to tackle complex problems with elegance and efficiency.

## Build Script

The `build.sh` script provides various operations for building and managing the extension:

```sh
./build.sh clean # Clean the build environment
./build.sh prepare # Prepare the build environment
./build.sh build # Build the extension
./build.sh run # Run the extension
./build.sh all # Execute all the above steps
### Build Script
```bash
./build.sh clean # Clean build environment
./build.sh prepare # Prepare build environment
./build.sh build # Build extension
./build.sh run # Run extension
./build.sh all # Execute all steps
```

Use `./build.sh all` for a complete build and installation process.

## Running Tests

To run the tests for this extension, use the following command:

```sh
### Testing
```bash
make test
```

This command will execute the PHP extension's test suite, which is the standard method for testing PHP extensions.

If you need to run specific tests or want more verbose output, you can use:

```sh
For specific tests:
```bash
make test TESTS="-v tests/your_specific_test.phpt"
```

Replace `your_specific_test.phpt` with the actual test file you want to run.
## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Add appropriate tests for your changes
4. Ensure all tests pass (`make test`)
5. Commit your changes
6. Push to the branch
7. Create a Pull Request

## Support and Feedback

- Issues: Report bugs via GitHub Issues
- Questions: Use GitHub Discussions
- Security: Report security issues directly to maintainers

## License

[MIT License](LICENSE)

0 comments on commit fff2983

Please sign in to comment.