Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Customize code using closures

License

NotificationsYou must be signed in to change notification settings

aimeos/macro

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The PHP Macro package offers closure (anonymous function) based setter dependencyinjection by providing a trait which can be included into any class.

composer req aimeos/macro

This package is for application, framework and library developers who want toallow customizing the behavior of their code by their users.

Why macros

In applications, frameworks or libraries which are build for customization it’snecessary to allow overwriting existing functionality to be able customize itsbehavior. This is where macros are very handy because they can add custom codeusing closures.

With the PHP Macro package, you can also allow users to overwrite methods inbase classes without forcing your users to extend these classes. The PHP Macropackage usesNO reflection or other hacks, justpure PHP methods.

There are some pros and cons when compared to class based depencency injection:

Pro:

  • Less code to write and much easier to implement for simple stuff
  • Custom closures can be inherited and overwritten like class methods

Con:

  • Limited static code analysis possibilities
  • Anonymous function can not be forced to implement an interface

Thus, it's not a replacement for class based depencency injection but a lightweightaddition for small extension points where full-blown dependency injection usingclasses implementing interfaces are too much work.

Allow customization

The result of existing methods can be modified if the original method checksfor an existing macro and use that instead its own implementation:

// original codeclass Order{useAimeos\Macro\Macroable;private$id ='123';publicfunctiongetOrderNumber()    {$fcn =static::macro('orderNumber' );return$fcn ?$fcn($this->id ) :$this->id;    }};

Now, you can add your customorderNumber macro that will be used instead:

// user codeOrder::macro('orderNumber',function(string$id ) {returndate('Y' ) .'-' .$id;} );(newOrder)->getOrderNumber();// now returns '2020-123'

Thus, you can generate own output or pass a different result to subseqent methodswithin the application.

Access class properties

When macros are called in an object context, they can also access class properties:

// original codeclass A{useAimeos\Macro\Macroable;private$name ='A';};

Here, the private property$name is available in the macro:

// user codeA::macro('concat',function(array$values ) {return$this->name .':' .implode('-',$values );} );(newA)->concat( ['1','2','3'] );// returns 'A:1-2-3'

The macro can use the property as input for creating the returned value.

Use inherited macros

The PHP macro package also allows to inherit macros from parent classes. Then,they can access class properties of the child class just like regular classmethods:

// original codeclass A{useAimeos\Macro\Macroable;private$name ='A';};class Bextends A{private$name ='B';};

Macros added to the parent class will be available in child classes too:

// user codeA::macro('concat',function(array$values ) {return$this->name .':' .implode('-',$values );} );(newB)->concat( ['1','2','3'] );// returns 'B:1-2-3'

ClassB extends from classA but provides a different$name property. Themacro inherited from classA will now use the property of classB.

Overwrite inherited macros

It's also possible to overwrite macros inherited from parent classes as it'spossible with regular class methods:

// original codeclass A{useAimeos\Macro\Macroable;publicfunctiondo() {returnstatic::macro('concat' )( [1,2,3] );    }};class Bextends A {};class Cextends A {};

Now you can add macros to the parent class and one of the child classes:

// user codeA::macro('concat',function(array$values ) {returnimplode(',',$values );} );C::macro('concat',function(array$values ) {returnimplode('-',$values );} );(newB)->do();// returns '1,2,3'(newC)->do();// returns '1-2-3'

This enables you to add special handling for single classes even if all otherclasses still use the macro added to classA.

Overwrite protected methods

Base classes often offer a set of methods that are used by the child classes.In PHP, replacing the methods of a base class is impossible and thus, you haveto overwrite each child class with your own implementation.

To avoid that, the original method can use thecall() method instead of callingthe method of the parent class directly:

// original codeclass A{useAimeos\Macro\Macroable;protectedfunctiongetName($prefix )    {return$prefix .'A';    }};class Bextends A{publicfunctiondo()    {return$this->call('getName','B-' );    }};

This will check if there's a macrogetName available and will call that insteadof thegetName() method:

// user code(newB)->do();// returns 'B-A'A::macro('getName',function($prefix ) {return$this->getName($prefix ) .'-123';} );(newB)->do();// returns 'B-A-123'

The originalgetName() method can still be used in the macro.

Reset macros

Sometimes, it may be necessary to remove macros from objects, especially whenrunning automated tests. You can unset a macro by using:

class A{useAimeos\Macro\Macroable;};// add macroA::macro('test',function() {return'test';} );// remove macroA::unmacro('test' );

[8]ページ先頭

©2009-2025 Movatter.jp