PHP - Doctrine, specify interfaces in YAML - php

Does anyone know if it is possible to specify an interface for a Doctrine model to implement within YAML?
I cannot find anything within the documentation.
Thanks

I don't believe there is a way to do that. However, you can implement an interface in you model by extending the doctrine-generated model, and implementing the interface in the subclass. In my opinion, no value is lost by having to do this extra step, because once you declare you are implementing an interface, you have to actually enter the code to do so.
You are better off implementing the interface in a subclass of the generated class, so that if you re-generate the class, none of your changes are lost.

Related

What boot() method do in laravel?

there is register() method in Service Provider which is used for bind the classes but i don't know what boot() method's do ? can you please explain it.
Interfaces by themselves are not very useful. But when implemented by concrete classes you see that it gives you the flexibility to have one or more implementations.
The bonus is that the object using the interface do not need to know how the details of the actual implementation go - that's called encapsulation...
Also It's difficult for me to imagine clean, object-oriented code without the use of interfaces. You use them whenever you wish to enforce the availability of certain functionality without forcing classes to inherit from a specific base class, and this allows your code to have the relevant level of (low) coupling.
What i can tell you is that Interfaces can be used in such situations where you want users to mandate to use defined methods in every inherited class. Such as when you define user login check method in your interface you can inherit to classes which are required to use this method to perform this method.
One noticeable problem with Interfaces is that once if you add a new method to your Interface it effects all its child classes as they might not have declared the new method in them. So it breaks and throws an error.

Extending/Modifying AddressInterface

I'm working with sylius/sylius-standard. I'm also creating my own bundle with some new entities and models. One of the requirements is to extend/modify the current Sylius Address model, but I've noticed that the AddressInterface has several methods that I don't want to use, like all those related to FirstName, LastName and Company. As far as I understand OOP and PHP interfaces, my new class or interface should implement all the methods declared in the interface (according to the official documentation).
Is there a way that I could make use of all the functionality that the Sylius Address model provides but with my own CustomAddressInterface?
I think the root of your issue is the misunderstanding of what interfaces are.
Interface is a contract. If a class is declared to expects an instance, with as specific interface, it means, that this class is written with intention to use methods from that interface.
If you are using a library, where some code requires a specific interface, then you have to implement all of the methods, that it contains. Otherwise your custom class instance will not be able to fulfill the declared contract.
NOTE: if you are seeing code, that declares to require an interface,
but does not actually use all of the methods in that interface, that codebase is violating Interface Segregation Principle.
Edit
I guess I have to spell it out:
Is there a way that I could make use of all the functionality that the Sylius Address model provides but with my own CustomAddressInterface?
No.

When is it appropriate to use a trait in PHP?

I've been reading up about PHP's traits. Specifically I came across this article. They probide an example involving objects that need to implement a shareable interface. The following argument is presented:
Does it make sense to duplicate the share() method in every class that implements the Shareable interface?
No.
Does it make sense to have an AbstractShare class that objects who implement the Shareable interface extend?
No.
Does it make sense to have the share() method implemented as part of an AbstractEntity class, but then blocked out for the Message object?
No.
Does it make sense to implement a ShareableTrait that fulfils the interface contract and can therefore be easily added to only objects that require it?
Yes!
I can understand the first and third points. But the second one confuses me. What exactly is wrong with having an abstract class called AbstractShareable or something like that which contains the functionality to share something, and then extending from it?
An interface is specifically designed to create reliable, well, interfaces, independent of the implementing class. Meaning:
function (Shareable $sharable) {
$shareable->share();
}
You can be assured that this code will always work (any object being passed in having a share() method), due to your interface declaration.
You can achieve the same thing using a class hierarchy; i.e. if you require a certain class, you can be sure that all of its children will also have the same methods the parent has. But: this imposes a strict class hierarchy on your classes. All classes have to extend one specific base class. And they can only extend that one specific class. You couldn't use a class hierarchy for both an AbstractSharable and an AbstractLoggable, say. That's why the class hierarchy solution is too inflexible. It would only allow you to implement one "trait". Or you'd have to mash all your various "traits" together into the same base class. Then you have a giant monolithic base class.
Separating characteristics into small individual interfaces keeps your code simple and flexible. Traits provide a flexible implementation analogue to an interface's specification.

CModel subclass in yii

I am a 4 days old yii fan and I like it so much.
I have a special database table that can't be used by CActiveRecord directly. My solution is to subclass CModel to have my own logic for listing, creating, saving and deleting records. My new CModel subclass cant not instantiated; it seems that CModel requires more methods to be defined to allow creating an instance from it.
My question is: Is this the right approach to go or there are better ways? If yes, what are the missing methods to define to make my new class complete; not abstract
Thanks
I usually create my own classes to handle the so called 'logic' of the webapp that I'm building.
I place it in another folder (usually the logics folder) and auto import the directory from the config. The logic classes doesn't subclass from any Model
public class ProfitLogic { ... }
where inside the class(es) I implement functions that instantiates and use any ActiveRecord(s) that I need.
The reasoning for this is that when prototyping I often refine my database design, and I need to regenerate the ActiveRecords again :p
Your approach is fine generally speaking, and would be fine even if you were not "forced" to adopt it. I use a CActiveRecord subclass as the base for my models to provide additional custom functionality.
As for your other question, you only need to implement attributeNames() to be able to instantiate objects of your class.
However, why do you not subclass CActiveRecord directly instead of CModel? You can still override any and all methods you choose to. Is your database so dramatically different from the usual schemas that you won't be able to reuse any of the logic?
I'm fairly new to Yii as well, but have found that extending CForm, as in the default ContactForm model can be useful.
Not the best for having lots of heavy business logic, but it touches on your point of breaking out of the typical workflow.

Correct Implementation of Virtual Functions in PHP?

at my working place (php only) we have a base class for database abstraction. When you want to add a new database table to the base layer, you have to create a subclass of this base class and override some methods to define individual behaviour for using this table. The normal behaviour should stay the same.
Now I have seen many new programmers at our company, who just override the method for the default behaviour. Some are so "nice" to put in all the default behaviour and just add there individual stuff where they like it, others kill themself trying to use the baseclass and their inheritor.
My first thought to solve this problem, was thinking about abstract methods that should be overriden by inheriting classes. But beside other arguments against abstract methods, "abstract" just does not show why the baseclass can't be used by its own and why these function should be overriden.
After some googling around I didn't find a good answer to implementing "real" virtual functions in php (just that there is a virtual function, that nearly kills all hope of a concrete implementation).
So, what would you do with this matter?
In PHP all public and protected functions are "virtual". You can prevent functions from being overriden by prepending the final keyword. (Or by making them private, but this is probably a bad idea).
In the design of the baseclass I would think of behaviors that subclasses would want to affect.
I would for example create empty functions like before_update() and after_insert().
function after_insert() {
// Virtual
}
Which the baseclass will call when an update/insert event occurs.
Maybe an is_valid() function which always returns true in the baseclass, and use the commentblock to describe what the consequences are when a subclass return false.
Hopefully this would give you some inspiration.
You can always use the "final" keyword to prevent some of the classes functions from being overridden if people are using the class in the wrong way.
It sounds to me like they are unable to acheive certain functionality hence overriding the methods. You may need to take a look at the design of your classes.
Without an example of the implementation of your base class, it's hard to give concrete info. But a few things come to mind:
Database abstraction is complex stuff to begin with. I understand that you want to keep it lean, clean and mean, but I think it's pretty darn difficult. You really have to take a thorough look at the specs of different DB engines to see what parts are general and what parts need specialization. Also; are you sure you don't have DB abstraction mixed up with the Table Data Gateway pattern, as you are talking about adding DB tables by extending the base class?
The methods of your current base class might be doing too much and/or are not general enough to begin with, if the extended classes are bending over backwards too keep it clean. Maybe you should break the base class interface methods up in smaller protected methods that are general enough to be reused in the overriding methods of the extended classes? Or vice versa: maybe you should have hooks to overridable methods in your interface methods.
Following from point 2: What's wrong with having an abstract class with some general implemented methods, and let your vanilla class (your base class) and other classes inherit from that?
Lastly, maybe you should just enforce an interface to be implemented, in stead of extending the base class?

Categories