How to extend base class which is extended already by different class? - php

So I have a situation in an application where there is a CONSOLE app and WEB app.
Now if one knows Yii2 then he knows. There is
yiisoft/yii2/base/ErrorHandler.php
which is extended by
yiisoft/yii2/web/ErrorHandler.php
( FOR WEB in main.php config )
and
yiisoft/yii2/console/ErrorHandler.php ( FOR CONSOLE in main.php config )
Now here I want to override handleException function from yiisoft/yii2/base/ErrorHandler.php. Both ErrorHandler ( web and console ) do not override this method. This method is only in BaseErrorHandler.
So right now, I am extending both ErrorHandler from WEB and CONSOLE.
So I do have to make same changes in two different files/classes. For it to work.
What if I just want to extend BaseErrorHandler and do changes in new class ( ONLY ONE class ) there and make it available in both classes which extends base class.

You can not have a class extending two classes. You can achieve what you want however through the use of Traits. Traits by definition from the guide here is:
"a mechanism for code reuse in single inheritance languages
such as PHP. A Trait is intended to reduce some limitations of single
inheritance by enabling a developer to reuse sets of methods freely in
several independent classes living in different class hierarchies."
Practically what you need to do is create a trait containing the desired function with the desired behavior. Example:
trait handleExceptionMyWay {
public function handleException($exception) {
//Put here the desired functionality. Example:
return "Hello";
}
}
And then in each of your classes you should add the statement use handleExceptionMyWay; as such
class MyWebErrorHandler extends yii\web\ErrorHandler {
use handleExceptionMyWay;
}
This way the function that is defined in the trait is going to be used and not the original function from base\ErrorHandler

Related

make a static method for all classes in PHP using meta class Class?

How can I add a static method for all classes of my php using an class Class or class Object (meta class) like
class Object //meta class, all classes php henerit of it
{
static function test() { return 42; }
}
now if I make a new class like :
class User
{
}
I want to be abble to write :
User::test();
same with all classes I will write
PHP has no concept of metaclasses; the way in which classes themselves behave is essentially hard-coded into the language. (You could argue that internal classes written in C conceptually use a different metaclass than userland classes written in PHP, since they can implement a different set of hooks; but that's not a distinction that's visible in the language, and not really relevant to your example.)
It also has no universal base class; there is no "Object" or "Any" or "Mu" class which all other classes implicitly or explicitly inherit from.
More importantly, there is no way to add to an existing class; there is no way to "re-open" or "monkey-patch" a class, or add methods via "extension classes". So even if there was a default metaclass or universal base class, you wouldn't be able to change it. Any classes you wanted extra behaviour on would have to opt-in to being instances of a non-default metaclass, or inherit from a non-default base class.
It's not clear exactly what the use case is, but there are a number of things you can do:
Write your own base class which a large number of classes inherit from, to put your "universal" methods in.
Use traits which enable "horizontal code re-use", essentially by "compiler-assisted copy-and-paste".
You have to use the trait in each class where you want to "paste" its contents, but they will then be inherited from there, so you can have a handful of unrelated "base classes" all sharing a set of methods "pasted" from the same trait.
On the other hand, you might want to create a sub-class which takes an existing class and adds some methods using a trait.
More complex cases would require you to patch the source code of classes themselves. For instance, using a custom autoloader and https://github.com/nikic/php-parser to parse and manipulate class definitions before they are compiled. For instance, this just-for-fun sweary library installs as a Composer plugin and loads classes via a stream wrapper which removes restrictions such as "final".
Why not use a trait?
Unfortunately I haven't heard of anything like what you need in PHP.
<?php
trait Obj
{
static function test() { return 42; }
}
class User
{
use Obj;
}
echo User::test(); //prints 42
Hope this helps.

Using PHP traits to simulate multiple inheritance

For this question I want to present my current design and my idea of using a trait. I would like to know whether my understanding of traits is correct and whether my problem can be solved with another design not involving them.
My current class hierarchy in my framework looks like this:
interface IPage { /* ... */ }
interface IForm extends IPage { /* ... */ }
abstract class AbstractPage implements IPage { /* ... */ }
abstract class AbstractForm extends AbstractPage implements IForm { /* ... */ }
In my applications that are based on the framework I used to have the following:
abstract class AbstractBasePage extends AbstractPage { /* ... */ }
Thus I could add some more stuff to all pages for this particular application that is not common to the framework or other applications. This worked well until I implemented the separation into pages and forms as indicated in the first snippet. Now I ended up with something like this:
abstract class AbstractBasePage extends AbstractPage { /* ... */ }
abstract class AbstractBaseForm extends AbstractForm { /* ... */ }
Let's assume in one application there should be a variable for each page and form that indicates whether something special is displayed in the templates. I would need to introduce the same variable in AbstractBasePage and in AbstractBaseForm. Doing so would force me to keep both snippets in sync which isn't good at all.
I was thinking about creating a trait that exposes variables and functions to both classes which they can in turn refer to in the corresponding functions. Using such a trait would reduce the code duplication at least since I could introduce one publicly accessible method that gets called by both classes but other than that there is a decent abstraction, isn't it?
Is this what traits are supposed to help with? Is there a more suitable approach?
In this particular case I ended up introducing an interface (with functions used by the framework) as a contract that gets extended by IPage. Furthermore I had the particular implementation that is identical for pages and forms in a trait which then in turn got used in the framework classes AbstractPage and AbstractForm.
The mentioned implementation was inside the framework itself to have a concise design which then in turn is used to do that in my applications as well. For the applications I introduced a trait which holds the variables and functions that are identical in both pages and forms once again which then gets used in the AbstractBasePage and AbstractBaseForm classes.
For this scenario I needed a what is essentially a language assisted copy and paste feature since I wanted to add something that is not as easily to be done using inheritance but something that can be introduced to classes that are part of different class hierarchies. Therefore I decided to use traits.

what is the best approach to use same functions in different classes using php

i have a service class written in php which called different classes to do same functions. In my each class, i am using the same functions for different clients. So every time a new client come to use my service, i just change the class name and the functions are remain same.
I have been trying to use the factory method pattern. But what i have figured out that if i use the factory method pattern, still i have to copy paste the same functions for different clients.
My scenario is i create a class to do the following.
For Client 1 functions are:
setClient()
process()
For Client 2 functions are:
setClient()
process()
I know i can use interface or abstract class. But still i feel there are some problems as the setClient() and process() functions do exactly the same things.
So what is the best approach to handle these type of scenarios?
I don't want to write or copy paste the same functions again and again in different classes for different clients for the same purpose.
advance thanks to all participants.
you can use an abstract class and then extend it in your client class. lets define the abstract class first.
abstract class base {
function common() {
echo "common code here";
}
}
then inherit it for each client.
class clienta extends base {
function clientAfunc() {
$this->common(); //call common
}
}

php application class structure guidelines

I am developing a php application using MVC architecture and i really need suggestions about the following design guidelines:
According to php class structure best practises, its noted that someone should minimize module dependencies, my application class inheritance is as followed:
some operations/methods are accessible by all classes
what i have done is i have created an HelperClass which will contain all these "global" methods like string manipulations, integer manipulations, array manipulations and then let the other classes which would like to use these methods extend the class.
Class organization:
interface StringHelper{
...
}
interface ArrayHelper{
...
}
class GeneralHelper implements StringHelper, ArrayHelper{
......
}
class NewClass extends GeneralHelper{
...
}
// user factory style to create object
class NewClassFactory{
public function create( $options ){
return new NewClass( $options );
}
}
The application has about 15 classes.
Is this approach suitable for this scenario or will i end up having big issues when maintaining my application?
Would appreciate for your help.
In most cases helper classes should always be static and no working class should extend it. Helpers are global and they have no role in the main scope of the working class. Think of helpers as Plumbers, Handymen etc . If you are writing a family class it shouldn't extend plumbers, Plumbers should come in when needed and out with no relation whatsoever to the family.
What you need is this:
class NewClass {
...
$some_string = declaration
$some_string = StringHelper::sanitizeString($some_string);
}

Real World Examples of Advanced OOP Features for PHP

I am trying to improve my knowledge of OOP in PHP and have been researching abstract classes and interfaces.
What I have learned
They are both classes that cannot be instantiated themselves but can olny be extended (implemented in the case of interfaces)
Abstract classes provide methods and properties for other classes that extend them.
If a class uses an abstract method then the class itself must also be abstract.
If an abstract method is defined within an abstract class, all child classes must define the details of that method. Methods not defined as abstract can be used in the same way as normal methods.
Interfaces define what methods a class that implements it must have. The functionality of the methods are not defined in the interface, the interface just offers a list of methods that must be included in the child class.
An interface does not define any properties.
Classes can implement as many interfaces as they want to but they must define a method for every one of the interfaces they implement
I think that covers the basics. Please feel free to add to that if you think there's anything I have missed.
What I would like to know is if there are any real world examples of implementation of these classes, especially the interface class. Does anyone know of any open source applications that use them that I can browse to better understand them and see where and when they are used effectively? I have come across book examples which use animals which fails to demonstrate the importance of these classes.
The final keyword prevents the class being extended by other classes, example:
class Parent
{
}
class Mother extends Parent
{
}
final class Brother extends Mother /* - This class cannot be extended - */
{
}
class Pet extends Brother
{
}
The Pet class will throw an error stating: Fatal error: Class Pet may not inherit from final class (Brother)
This is also available for methods, so if you do not want to allow the methods to be inherited causing the child class to have the same method acting as an override.
http://php.net/manual/en/language.oop5.final.php
Yo used that you would like some real world examples of what interfaces can be used for, well a database abstraction layer
You have 1 base class which provides the basic methods to iterate your database data, but that would use a sub class for the the database type, such as MySql,MsSql etc, each database type would have its own class, but for the base class to make sure that it has these methods they would all implement the same interface.
Example
interface IDatabaseLayer
{
public function connect();
public function query();
public function sanitize();
//...
}
So the base class knows that MySql and MsSql have the above methods, thus reducing errors and being more organized.
When passing in objects to classes you want to be sure that the Object is of a certain type, PHP5 allows you to define what type of object should be passed into the methods as params.
lets say you have 3 classes
DatabaseCredentials
DatabaseConnection
DatabaseQuery
you can specifically define in the constructuin of DatabaseConnection that you require a DatabaseCredentials class like so:
class DatabaseConnection implements Connectable
{
public function __construct(DatabaseCredentials $ConnectionDetails)
{
$this->Connect($ConnectionDetails->BuildDSN());
}
}
A good way to really get started is by reading here:
http://php.net/manual/en/language.oop5.php
Another feature of PHP5 you may wish to look at is name spaces, this will allow you to keep your code organized, have multiple objects with the same name, makes auto loading more efficiently
Small Example:
namespace Database\MySql
{
class Database{}
}
namespace Database\MsSql
{
class Database{}
}
And you can just use like:
use Database;
$Database = new MySql\Database();
PHP comes with few interfaces predefinded by default: http://www.php.net/manual/en/reserved.interfaces.php
PHP also contains Standard PHP Library (SPL), which defines more:
interfaces http://www.php.net/manual/en/spl.interfaces.php
classes, including abstract ones: http://www.php.net/manual/en/spl.datastructures.php
Zend Framework is also very good example where such concepts are used. http://framework.zend.com/
Not a real world example as such, but one Design Pattern where you usually encounter interfaces and abstract classes is the Command Pattern. See link for example code.
In general, "programming against an interface" is considered good OO practise, because it decouples concrete implementations and let you more easily change them for other implementations, e.g. instead of asking for a specific class
public function fn(ConcreteClass $obj)
{
$obj->doSomething()
}
you just ask that it provides a certain set of methods
public function fn(MyInterface $obj)
{
$obj->doSomething()
}
Interfaces also help teasing apart large inheritance structures. Because PHP supports only Single Inheritance, you'll often see hierarchies like this:
BaseClass -> Logger -> Auth -> User
where each of these contains specific aspects used inside these classes. With an interface, you just do
User implements Loggable, Authenticable
and then include that specific code via Strategy Patterns or Composition/Aggregation, which is ultimately much more maintainable.
For a list of predefined interfaces in PHP see my answer to:
where to find "template" interfaces?.
You may follow the "PHP patterns" series by Giorgio Sironi in dzone or directly in his blog, really interesting if you are interested patterns and OOP.
Also you could take a look to the Best PHP programming book in stackoverflow if you're in need of a good PHP book.
We can say that interface is purely 100% abstract class but abstract is not. Because many time we defines function in abstract class. But in interface class we always declare function.

Categories