So I want to be able to add/remove class methods at runtime. Before you tell me that's horrible pratice in oop, it might be, but I don't really care. The reason I want to be able to do this is because I want the application to be very modular, so some plugin could extend some base class and add methods to it without killing the the main app.
For example, say I have the following class:
class User {
protected $Id;
protected $Name;
protected $Password;
protected $PostsPerPage;
}
And say, some plugin adds the possibility for users to change their visibility settings, adding a $Visible property to the class. The class would become:
class User {
protected $Id;
protected $Name;
protected $Password;
protected $PostsPerPage;
protected $Visible;
}
This could be achieved via __get and __set, but the most common implementation is for getting and setting runtime generated properties, and it'd be a hassle to code pseudo getters and setters for each added property, as well as using __set is a no-no in my opinion.
The other idea I had was to store the user settings separately, in another array like $UserVisiblitySettings[userid], but that makes things not as OO as I would like them to be.
Next idea was to make a helper class, something like this:
class UserHelper {
public function SetVisiblity($user_object,value);
}
Then, I could use __get and __set to implement "friend" methods/classes, but that sounds too hackish. If I were to go that way might as well just overload __call, __get and __set. Also I'm not so sure this is good OOP pratice, and it'd look ugly too.
The last idea I had was to have some function to create classes dynamically on runtime by using eval() (this is the only valid use of eval I could come up with too). Basically, get the class definition from a file, do some simple bracket finding to find the class' opening and closing brackets and send it to eval.
Using runkit is out of question, as it is outdated and I'd rather not force the user to install some extension.
When I look up to my ideas, the simplest one and less cpu intensive seems to be to overload _call and add a way for methods to be registered in the class.
Please any thoughts that aren't "don't do this" are appreciated.
RunKit extension can do it (runkit_method_add(), etc.)
However it's an experimental extension and you're already aiming at your foot...
You have other options:
Emulate new fields and methods with __get() and __call()
Use subclassing and Factory pattern (class Plugin extends BaseImplementation and have factory instantiate Plugin instead of BaseImplementation). Zend Plugin Loader does something like this.
It's the solution with least overhead, but also is limited to one plugin extending one class.
Add hooks and use delegation (Strategy pattern) ($this->plugin->onFoo()). There's library for this.
PHP doesn't allow this. It may be a dynamic language in other respects, but the class system is deliberately restrictive. You can either install the runkit extension, which changes the language to allow mocking about with classes at runtime (But then you aren't using plain PHP anymore), or you can use the magic-methods to simulate it.
You can override the class, but I don't know if you can reload it in the same request.
some behavior change can be achieved with mediator design pattern (symfony event dispatcher) but you need to know the extension points in advance, and fire events/messages to be caught by an extending class in the future..
if you can wait for the next request, and clear cache if you have it. I made a tool that might help you.
SourceEditor
Here there are more answers to a similar question too, where I put code examples.
How to generate or modify a PHP class at runtime?
Related
Sorry if this is a duplicate question or a common design principle, I have searched around but was unable to find any answers to this question. I'm probably just searching with the wrong keywords.
I have been looking at a popular library Sabre/Event (https://sabre.io/event/) and in the code there is a simple class/inheritance model that I am trying to understand:
The class EventEmitter implements EventEmitterInterface and uses EventEmitterTrait (see below for code).
There is a comment in EventEmitterTrait above the class which says:
* Using the trait + interface allows you to add EventEmitter capabilities
* without having to change your base-class.
I am trying to understand why this comment says this, and why it allows adding capabilities without changing the base class, and how that is different from just putting the routines into EventEmitter itself.
Couldn't you just extend EventEmitter and add capabilities in the derived class?
Simplified code:
// EventEmitter.php
class EventEmitter implements EventEmitterInterface {
use EventEmitterTrait;
}
// EventEmitterInterface.php
interface EventEmitterInterface {
// ... declares several function prototypes
}
// EventEmitterTrait.php
trait EventEmitterTrait {
// ... implements the routines declared in EventEmitterInterface
}
You're basically asking two questions here.
What are interfaces and why are they useful?
What are traits and why are they useful?
To understand why interfaces are useful you have to know a little about inheritance and OOP in general. If you've ever heard the term spaghetti code before (it's when you tend to write imperative code that's so tangled together you can hardly make sense of it) then you should liken that to the term lasagna code for OOP (that's when you extend a class to so many layers that it becomes difficult to understand which layer is doing what).
1. Interfaces
Interfaces diffuse some of this confusion by allow a class to implement a common set of methods without having to restrict the hierarchy of that class. we do not derive interfaces from a base class. We merely implement them into a given class.
A very clear and obvious example of that in PHP is DateTimeInterface. It provides a common set of methods which both DateTime and DateTimeImmutable will implement. It does not, however, tell those classes what the implementation is. A class is an implementation. An interface is just methods of a class sans implementation. However, since both things implement the same interface it's easy to test any class that implements that interface, since you know they will always have the same methods. So I know that both DateTime and DateTimeImmutable will implement the method format, which will accept a String as input and return a String, regardless of which class is implementing it. I could even write my own implementation of DateTime that implements DateTimeInterface and it is guaranteed to have that method with that same signature.
So imagine I wrote a method that accepts a DateTime object, and the method expects to run the format method on that object. If it doesn't care which class, specifically, is given to it, then that method could simply typehint its prototype as DateTimeInterface instead. Now anyone is free to implement DateTimeInterface in their own class, without having to extend from some base class, and provide my method with an object that's guaranteed to work the same way.
So in relation to your EventEmitter example, you can add the same capabilities of a class (like DateTime) to any class that might not even extend from DateTime, but as long as we know it implements the same interface, we know for sure it has the same methods with the same signatures. This would mean the same thing for EventEmitter.
2. Traits
Traits, unlike interfaces, actually can provide an implementation. They are also a form of horizontal inheritance, unlike the vertical inheritance of extending classes. Because two completely different class that do not derive from the same base class can use the same Trait. This is possible, because in PHP traits are basically just compiler-assisted copy and paste. Imagine, you literally copied the code inside of a trait and just pasted it into each class that uses it right before compile time. You'd get the same result. You're just injecting code into unrelated classes.
This is useful, because sometimes you have a method or set of methods that prove reusable in two distinct classes even though the rest of those classes have nothing else in common.
For example, imagine you are writing a CMS, where there is a Document class and a User class. Neither of these two classes are related in any meaningful way. They do very different things and it makes no sense for one of them to extend the other. However, they both share a particular behavior in common: flag() method that indicates the object has been flagged by a user for purposes of violating the Terms of Service.
trait FlagContent {
public function flag(Int $userId, String $reason): bool {
$this->flagged = true;
$this->byUserId = $userId;
$this->flagReason = $reason;
return $this->updateDatabase();
}
}
Now consider that perhaps your CMS has other content that's subject to being flagged, like a Image class, or a Video class, or even a Comment class. These classes are all typically unrelated. It probably wouldn't make much sense just to have a specific class for flagging content, especially if the properties of the relevant objects have to be passed around to this class to update the database, for example. It also doesn't make sense for them to derive from a base class (they're all completely unrelated to each other). It also doesn't make sense to rewrite this same code in every class, since it would easier to change it in one place instead of many.
So what seems to be most sensible here is to use a Trait.
So again, in relation to your EventEmitter example, they're giving you some traits you can reuse in your implementing class to basically make it easier to reuse the code without having to extend from a base class (horizontal inheritance).
Per Sabre's Event Emitter's docs on "Integration into other objects":
To add Emitter capabilities to any class, you can simply extend it.
If you cannot extend, because the class is already part of an existing
class hierarchy you can use the supplied trait.
So in this case, the idea is if you're using your own objects that already are part of a class hierarchy, you may simply implement the interface + use the trait, instead of extending the Emitter class (which you won't be able to).
The Integration into other objects documentation says:
If you cannot extend, because the class is already part of an existing class hierarchy you can use the supplied trait".
I understand it's a workaround when you already have an OOP design you don't want to alter and you want to add event capabilities. For example:
Model -> AppModel -> Customer
PHP doesn't have multiple inheritance so Customer can extend AppModel or Emitter but not both. If you implement the interface in Customer the code is not reusable elsewhere; if you implement in e.g. AppModel it's available everywhere, which might not be desirable.
With traits, you can write custom event code and cherry-pick where you reuse it.
This is an interesting question and I will try to give my take on it. As you asked,
What is the purpose of using traits to define functions for an interface ?
Traits basically gives you the ability to create some reusable code or functionality which can then be used any where in your code base. Now as it stands, PHP doesn't support multiple inheritance therefore traits and interfaces are there to solve that issue. The question here is why traits though ?? Well imagine a scenario like below,
class User
{
public function hasRatings()
{
// some how we want users to have ratings
}
public function hasBeenFavorited()
{
// other users can follow
}
public function name(){}
public function friends(){}
// and a few other methods
}
Now lets say that we have a post class which has the same logic as user and that can be achieved by having hasRatings() and hasBeenFavorited() methods. Now, one way would be to simply inherit from User Class.
class Post extends User
{
// Now we have access to the mentioned methods but we have inherited
// methods and properties which is not really needed here
}
Therefore, to solve this issue we can use traits.
trait UserActions
{
public function hasRatings()
{
// some how we want users to have ratings
}
public function hasBeenFavorited()
{
// other users can follow
}
}
Having that bit of logic we can now just use it any where in the code where ever it is required.
class User
{
use UserActions;
}
class Post
{
use UserActions;
}
Now lets say we have a report class where we want to generate certain report on the basis of user actions.
class Report
{
protected $user;
public function __construct(User $user)
{
$this->user = $user
}
public function generate()
{
return $this->user->hasRatings();
}
}
Now, what happens if i want to generate report for Post. The only way to achieve that would be to new up another report class i.e. maybe PostReport.. Can you see where I am getting at. Surely there could be another way, where i dont have to repeat myself. Thats where, interfaces or contracts come to place. Keeping that in mind, lets redefine our reports class and make it to accept a contract rather than concrete class which will always ensure that we have access to UserActions.
interface UserActionable
{
public function hasRatings();
public function hasBeenFavorited();
}
class Report
{
protected $actionable;
public function __construct(UserActionable $actionable)
{
$this->actionable = $actionable;
}
public function generate()
{
return $this->actionable->hasRatings();
}
}
//lets make our post and user implement the contract so we can pass them
// to report
class User implements UserActionable
{
uses UserActions;
}
class Post implements UserActionable
{
uses UserActions;
}
// Great now we can switch between user and post during run time to generate
// reports without changing the code base
$userReport = (new Report(new User))->generate();
$postReport = (new Report(new Post))->generate();
So in nutshell, interfaces and traits helps us to achieve design based on SOLID principles, much decoupled code and better composition. Hope that helps
In Java, for example, this comes out of the box due to static nature of the language. But in PHP this could be also useful especially to keep a code secure and clean from an architectural point of view.
For example, we have the following code:
interface DocumentProcessorInterface
public function process();
}
class GameSaveProcessorImpl implements DocumentProcessorInterface {
public function process() {
// do something useful
}
public function methodToSetSomethingFromFriendClass() {
// setting private fields, some postponed initialization/resetting, etc
}
}
Then, from some class (lets call it "friend class", because it lies side-by-side with the GameSaveProcessorImpl class and compelements it) we call method methodToSetSomethingFromFriendClass. Because of PHP duck typing such ability to call this method is also available to any alien client code, but this method is not for such usage. Alien (external) client code MUST use only DocumentProcessorInterface methods (this is one of the reasons why we use interfaces at all).
There are some solutions that come in mind.
1) Just leave it as is, but rename public methods that are not in interfaces, so it work as warning for those alien client code implementors, for example, rename methodToSetSomethingFromFriendClass to internalUseOnly_methodToSetSomethingFromFriendClass. Reduces risk of occassional usage, but doesn't prohibits calling methods technically.
2) Using adaptor (decorator) pattern. Pass to an external code only decorated instance which doesn't has methodToSetSomethingFromFriendClass method. It does solve problem of unwanted method access but complicates another parts of our code very much. It seems there is no overall profit.
3) Not really checked yet vialibity of this idea: utilize the following fact. Base class can declare protected method so all friend classes we control may be
extended from that base class keeping our methodToSetSomethingFromFriendClass mehod marked as protected being effectively protected from external code, but callable from "friend" class. Technically this allows protection, but requires friend classes to inherit from common base class, drawbacks of such are well known.
Do you know anything better?
Links to the articles are appreciated as well as sharing experience on this topic research.
I'm writing a bunch of generic-but-related functions to be used by different objects. I want to group the functions, but am not sure if I should put them in a class or simply a flat library file.
Treating them like a class doesn't seem right, as there is no one kind of object that will use them and such a class containing all these functions may not necessarily have any properties.
Treating them as a flat library file seems too simple, for lack of a better word.
What is the best practice for this?
Check out namespaces:
http://www.php.net/manual/en/language.namespaces.rationale.php
Wrapping them in a useless class is a workaround implementation of the concept of a namespace. This concept allows you to avoid collisions with other functions in large projects or plugin/module type deployments.
EDIT
Stuck with PHP 5.2?
There's nothing wrong with using a separate file(s) to organize utility functions. Just be sure to document them with comments so you don't end up with bunchafunctions.php, a 20,000 file of procedural code of dubious purpose.
There's also nothing wrong with prefixes. Using prefixes is another way to organize like-purpose functions, but be sure to avoid these "pseudo-namespaces" already reserved by the language. Specifically, "__" is reserved as a prefix by PHP [reference]. To be extra careful, you can also wrap your function declarations in function_exists checks, if you're concerned about conflicting functions from other libraries:
if (!function_exists('myFunction')) {
function myFunction() {
//code
}
}
You can also re-consider your object structure, maybe these utility functions would be more appropriate as methods in a base class that all the other objects can extend. Take a look at inheritance: http://www.php.net/manual/en/language.oop5.inheritance.php. The base class pattern is a common and very useful one:
abstract class baseObject {
protected function doSomething () {
print 'foo bar';
}
public function getSomething () {
return 'bar foo';
}
}
class foo extends baseObject {
public function bar () {
$this->doSomething();
}
}
$myObject = new foo();
$myObject->bar();
echo $myObject->getSomething();
You can experiment with the above code here: http://codepad.org/neRtgkcQ
I would usually stick them in a class anyway and mark the methods static. You might call it a static class, even though PHP actually has no such thing (you can't put the static keyword in front of a class). It's still better than having the functions globally because you avoid possible naming conflicts. The class becomes a sort of namespace, but PHP also has its own namespace which may be better suited to your purpose.
You might even find later that there are indeed properties you can add, even if they too are static, such as lazy-loaded helper objects, cached information, etc.
I'd use classes with static methods in such case:
class Tools {
static public function myMethod() {
return 1*1;
}
}
echo Tools::myMethod();
EDIT
As already mentioned by Chris and yes123: if the hoster already runs PHP 5.3+, you should consider using namespace. I'd recommend a read of Matthew Weier O'Phinney's article Why PHP Namespaces Matter, if you're not sure if it's worth switching to namespaces.
EDIT
Even though the ones generalizing usage of static methods as "bad practice" or "nonsense" did not explain why they consider it to be as such - which imo would've been more constructive - they still made me rethinking and rereading.
The typical arguments will be, that static methods can create dependencies and because of that can make unit testing and class renaming impossible.
If unit testing isn't used at all (maybe programming for home/personal use, or low-budget projects, where no one is willing to pay the extra costs of unit testing implementations) this argument becomes obsolete, of course.
Even if unit testing is used, creation of static methods dependencies can be avoided by using $var::myMethod(). So you still could use mocks and rename the class...
Nevertheless I came to the conclusion that my answer is way too generalized.
I think I better should've wrote: It depends.
As this most likely would result in an open ended debate of pros and cons of all the different solutions technically possible, and of dozens of possible scenarios and environments, I'm not willing going into this.
I upvoted Chris' answer now. It already covers most technical possibilities and should serve you well.
Treating them as a class does give you the benefit of a namespace, though you could achieve the same thing by prefixing them like PHP does with the array_* functions. Since you don't have any properties, that basically implies that all your methods are static (as Class::method()). This isn't an uncommon practice in Java.
By using a class, you also have the ability, if necessary, to inherit from a parent class or interface. An example of this might be class constants defined for error codes your functions might return.
EDIT: If PHP 5.3+ is available, the Namespace feature is ideal. However, PHP versions still lag in a lot of hosts and servers, especially those running enterprise-stable Linux distributions.
I've seen it a few different ways, all have their warts but all worked for the particular project in which they were utilized.
one file with all of the functions
one file with each function as its own class
one massive utilities class with all of the methods
one utils.php file that includes files in utils folder with each
function in its own file
Yes, it's OK formally... As any class is methods + properties. But when you pack in class just some functions -- it`s become not ideal OOP. If you have bunch of functions, that groupped, but not used some class variables -- it' seems, that you have somewhere a design problem.
My current feeling here is "Huston, we have a problem".
If you use exactly functions, there one reason to wrap them in static class - autoloader.
Of course, it creates high coupling, and it's may to be bad for testing (not always), but... Simple functions are not better than static class in this case :) Same high coupling, etc.
In ideal OOP architecture, all functions will be methods of some objects. It's just utopia, but we should to build architecture as close as we can to ideal.
Writing a bunch of "generic-but-related" functions is usually bad idea. Most likely you don't see problem clear enough to create proper objects.
It is bad idea not because it is "not ideal OOP". It is not OOP at all.
"The base class pattern" brought by Chris is another bad idea - google for: "favor composition over inheritance".
"beeing extra careful" with function_exists('myFunction') is not but idea. It is a nightmare.
This kind of code is currently avoided even in modern javascript...
A word before my question to say I am pretty new to OOP in PHP, and I'm very grateful to the site, and you all for reading - and sometimes answering beautifully (as you can see here or here, or even here) and helping big time my late (sort of) improvement dealing with classes.
All my previous questions lead me today to this one:
In a class extending PDOStatement, how can I trigger a default action each time one of the parent public methods is called?
I can do this:
class genc_query extends PDOStatement{
public function rowCount(){
$this->myDefaultAction();
return parent::rowCount();
}
}
But as I need to change in the same way almost all of the native methods, I wonder if there's no way to trigger a function like __call() as if these methods were private (as it's not possible to make them private).
as it's not possible to make them private
Indeed, this seems to be the case.
ReflectionMethod can let you change the accessibility of a method, but it seems that it either doesn't work on internal methods (i.e. not user-defined) or it won't set public methods to protected/private. It seems designed to make protected/private methods public instead.
It looks like your copy-and-paste boilerplate inside each method is going to be necessary. Besides __sleep and __wakeup, there are only about three dozen methods, so it should only take you a few minutes.
For the sake of clear code, extend every method (means: overwrite and call parent::method() there), that you wants to have additional behaviour. Else there will be some day, where you or someone else may get really confused on what happens there.
I remember reading that in Doctrine 2 models, I should not set properties/fields public. How then would you expose these fields? The sandbox used get*() & set*() methods. Is that the best idea? Its very cumbersome. Using magic methods __get() __set() will make things similar to setting fields public?
Whats your recommendation?
Here's why you can't use public properties: How can public fields “break lazy loading” in Doctrine 2?
You are correct that __get() and __set() can make accessing the protected/private fields easier.
Here's a simple example:
public function __get($name)
{
if(property_exists($this, $name)){
return $this->$name;
}
}
Of course that gives access to all the properties. You could put that in a class that all your entities extended, then define non-assessable fields as private. Or you could use an array to determine which properties should be accessible:$this->accessable = array('name', 'age')
There are plenty of ways to keep all properties protected and still have a reasonably easy way to get/set them.
Personally, I don't like boilerplate code with trivial purpose - it makes the code ugly and tiresome to read. Therefore, I strongly prefer __get/__set. That said, they do have a few drawbacks:
they are significantly slower than normal function calls, though not so much that it should make a difference in practice, as database access is several orders of magnitude slower
__get/__set only gets called when the field is not visible; if you access properties in the code of the entity class, they do not get called, and the proxy has no chance to load itself. (Doctrine tries to avoid this by instantly loading the proxy as soon as one of its public methods are called, but there are some exceptions such as __construct or __wake where that would not make sense, so you can get into trouble by e.g. reading a field in the constructor.)
PHP has some confusing behaviors related to magic methods - e. g. empty($entity->field) will not invoke __get (and thus it will break proxy behavior if used)
If some info should be made public, define a getter for it.
If it's modifiable, add a setter (even better, add a fluent setter!).
API's are cleaner this way, with no magic involved.
I don't like magic in my code.
Just my two cents :)
By "fluent setter" I meant one implementing the fluent interface pattern.
Yes getter and setter methods are the way to access your data. They are a little cumbersome which is why some people do not like doctrine2 or hibernate. But you only need to do it once for each entity and then they are very flexible to produce the output formatting you are hoping for. You can use the cli to do some of this for you. But when you get them rolling I don't find it to big a deal. Especially since you only do this to the properties you need.
Cheers
Rather than having seperate getter and setters, or even using the magic functions.. Is there problem with having something like this in the class
public function Set($attrib, $value)
{
$this->$attrib = $value;
}
public function Get($attrib)
{
return $this->$attrib;
}
It makes it much easy to access the attributes and means they be dynamically set from key-pair arrays.. any comments? or alternative suggestions?
Doctine 2 provides a [command line tool][1] to generate basic entity classes
use the following to get a basic Entity class definition from your mapping, complete with getter/setter functions for each property:
path/to/doctrine_cli orm:generate-entities --generate-methods=true path/to/entities/
You're still responsible for modifying each getter/setter to ensure that they are the proper datatype, as the getter/setter methods generated for the Entity don't do any type casting/converting.