Skip to content

marcuswinkler/vent

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vent

PHP variable event system

| Quality / Metrics | Releases | Downloads | Licence | | ----- | -------- | ------- | ------------- | -------- | Build Status Coverage Status | Latest Stable Version Latest Unstable Version | Total Downloads | License

Installation

Install via composer:

php composer.phar require leedavis81/vent:dev-master

Usage

Have you ever needed to hook an event anytime a PHP variable is read? Maybe you want to ensure complete immutability even within the scope (private) of your class. PHP variable events can be easily created by hooking into the read or write of any variable.

<?php
class Foo
{
    use Vent\VentTrait;
   
    private $bar;
   
    public function __construct()
    {
        $this->registerEvent('read', 'bar', function(){
            throw new \Exception('Don\'t touch my bar!');
        });
    }
    
    public function touchBar()
    {
        $this->bar;
    }
}

$foo = new Foo();
$foo->touchBar(); // Fatal error: Uncaught exception 'Exception' with message 'Don't touch my bar!'

Or you can register a write event to protect the variable from being overwritten (even from within the scope of your class)

$this->registerEvent('write', 'bar', function(){
  throw new \Exception('Don\'t write to my bar!');
});
        
public function writeToBar()
{
  $this->bar = 'somethingElse';
}        
        
$foo = new Foo();
$foo->writeToBar(); // Fatal error: Uncaught exception 'Exception' with message 'Don't write to my bar!'        

You can masquerade any value by returning something from your registered event. Note that if multiple events are registered, execution they will stop once one of them returns a response. They are triggered in the order they're registered (first in, first out).

public $bar = 'Bill';

public function __construct()
{
  $this->registerEvent('read', 'bar', function(){
    return 'Ben';
  });
}
        
        
$foo = new Foo();
echo $foo->bar; // "Ben"

If you are returning a response on your event, this can be retained to prevent additional execution on further reads.

public $bar = 'Bill';

public function __construct()
{
  $this->registerEvent('read','bar', function(){
    sleep(1);
    return microtime();
  }, true);     // pass in "true" here (defaults to false)
}
        
        
$foo = new Foo();
var_dump($foo->bar === $foo->bar);   // true

All events must be registered within the context of your class when using VentTrait. However, if you'd like to register them from a public or protected scope then simply change the scope of the registerEvent method when importing the trait

<?php
class Foo
{
    use Vent\VentTrait {registerEvent as public;}   // allow public event registration
   
    public $bar;
}

$foo = new Foo();

$foo->registerEvent('read', 'bar', function(){
    throw new \Exception('Don\'t touch my bar!');
});

$foo->bar;  // Fatal error: Uncaught exception 'Exception' with message 'Don't touch my bar!'

todos

  • Allow event triggering for array offset reads $foo->bar['offset'];
  • Need to inject variables into the callable event
  • Expand event scope to include 'delete'

About

PHP variable access event system

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published