Abstract class calling a method from the wrong child class - php

I have an abstract class that is extended by several other classes, each with an abstract method called child_save_changes().
One of the methods in the template class is called on_save_changes(), and whenever the user clicks 'Submit', this method is called from another page.
The on_save_changes() method first sets some class variables required for validating/saving, then calls child_save_changes(), and then finally handles redirection back to the referring page.
The problem is, because I'm calling on_save_changes() via a callback from another page, it doesn't know which child class to call the abstract method child_save_changes() from, and thus it's just picking the first one it finds.
It seems inefficient to repeat code in each child_save_changes() method, so I'm wondering if anyone has come across a similar scenario in the past, and what actions they took to fix the issue? Thanks.

It sounds to me like you are using static methods. Otherwise the problem you describe cannot reasonably occur.
You wrote, "on_save_changes() does not know which child class to call the abstract method child_save_changes() from". But ordinary (i.e., non-static) methods are not called from classes, they are called from objects. And every object knows exactly which class it belongs to, and thus there can never be confusion about which method is meant to be called.
Static methods, on the other hand, are not designed to work with inheritance hierarchies like that. I would personally recommend refactoring your code and turn them into non-static ones, but if you do not want to do that, you may be able to make it work using late static binding.

Related

Should I (and if so, how can I best) enforce private abstract like method in php?

Looking for a little guidance here.
I know that private methods are not polymorphic and so it doesn't make sense make abstract functions of them, but I do want to somehow enforce that a child class of a base class always declares a private method.
Am I doing something wrong or is this okay? I know you can't do multiple inheritance so maybe traits are the way to go, but I don't know if I can enforce them in Php.
I was thinking, maybe I can have an abstract base class have an abstract protected method, and then have that class be final since the function has to be protected? The only downside is that I could go farther with this though.
I just want a child class to always have a base method that only it can access, but I'm not sure how to do that without making it final.
EDIT:
Situation context is I have a child classes that are like flyweights that inherit from a base abstract that do type checking (because php is dynamic) and also want to do a final check for required variables. Every child class has to do this and does it the same way, but it should be called by anything else.
EDIT Idea:
I was thinking I could just write an interface for the base class with a function to do the final function (in this case render), and inside function, I could call the error checking. The problem with this is that I could not access new attributes that I newly create in the extended functions because the base class function wouldn't know about them. Then I'd be stuck with putting them in an array or something which defeats the purpose of making the child class anyway. Also, if I did that, I couldn't be sure that the function didn't get redefined without making it final so that I could no longer extend it. Idk here. Please help if you have ideas.

OOP factory method vs constructor

I have one top class, let's say School.
And a couple of classes extending the School class.
Normally, if I had to call one of the child classes I would use:
new Math('aaa'), or new English(array('foo'));
Every child class has different parameters.
Now, what is better:
1) Creating factory method in the School class, so :
School::Factory('aaa') would return Math('aaa') class based on the given parameters to the Factory() method
2) Or simply calling each child classes directly?
EDIT: I have only two child classes, my problem is that I don't know if doing this is worth a bit of simplicity in production code. I would just check which parameters were passed to the Factory method, and based on this information I'd call one of these two classes. What do you think?
On one side I'll be able to write simpler code.
On the other every time I'll need to add new child class (though there are very little chances to do that), I'll need to change Factory() method either, so I have a dependency here.
1) Creating factory method in the School class, so :
You say that you have 2 classes extending School. Therefore, School should not act as a factory. The parent class shouldn't know anything about its children/subclasses.
2) Or simply calling each child classes directly?
Or you could have a "CourseFactory" or "LectureFactory" with createMath( aaa ), for example. Or depending on the case, maybe createLecture("math").
However, it makes no sense in your example that Math or English extend School (unless you mean MathSchool and EnglishSchool, but I understood it as MathCourse and EnglishCourse)

PHP: is there an instance of class in use?

I've caused a circular loop between a class and it's parent class.
The only way I can think of to fix the problem is to test if there are instances of the child class in use. Is there anyway to test for that?
So I took a break and came back the issue. The loop was caused by the __construct method in a class that deals with routing input to the appropriate logic. This class is then inherited by other classes so that if I need to do something automatically that would normally be done by the user I can implement it easily.
What I didn't see happening was that each time a child class was called, this constructor was activated to reroute the user to the right code. Since the input was identical, it was sent back to child class, setting up the loop. I have solved the issue by taking out the constructor and calling the methods needed in the site index instead, so that child classes, no longer attempt to call themselves.
Well, you should adjust your code to avoid the loop. It sounds like a bad thing what you did and it's likely to cause troubles in the future. So my suggestion is to redesign your code so you avoid the loop instead of fixing it.
You could use instanceof to check if it's an instance of a class. Or is_subclass_of to check if it extends a class.
If you post your code maybe someone can suggest a better design, the loop can probably be avoided.

Why people use singletons in their PHP framework

Ok guys I am struggling to understand why there is a need of singleton.
Let's make a real example: I have a framework for a my CMS
I need to have a class that logs some information (let's stick on PHP).
Example:
class Logger{
private $logs = array();
public function add($log) {
$this->logs[]=$log;
}
}
Now of course this helper object must be unique for the entry life of a page request of my CMS.
And to solve this we would make it a singleton (declaring private the constructor etc.)
But Why in the hell a class like that isn't entirerly static? This would solve the need of the singleton pattern (that's considered bad pratice) Example:
class Logger {
private static $logs = array();
public static function add($log) {
self::$logs[]=$log;
}
}
By making this helper entirely static, when we need to add a log somewhere in our application we just need to call it statically like: Logger::add('log 1'); vs a singleton call like: Logger::getInstance()->add('log 1');
Hope someone makes it easy to understand for me why use singleton over static class in PHP.
Edit
This is a pretty nice lecture on the singleton vs static class for who is interested, thanks to #James. (Note it doesn't address my question)
Many reasons.
Static methods are basically global functions that can be called from any scope, which lends itself to hard to track bugs. You might as well not use a class at all.
Since you cannot have a __construct method, you may have to put an init static method somewhere. Now people in their code are unsure if the init method has been called previously. Do they call it again? Do they have to search the codebase for this call? What if init was somewhere, but then gets removed, or breaks? Many places in your code now rely on the place that calls the init method.
Static methods are notoriously hard to unit test with many unit testing frameworks.
There are many more reasons, but it's hard to list them all.
Singletons aren't really needed either if you are using DI.
A side note. DI allows for your classes not to rely on each other, but rather on interfaces. Since their relationships are not cemented, it is easier to change your application at a later time, and one class breaking will not break both classes.
There are some instances where single state classes are viable, for instance if none of your methods rely on other methods (basically none of the methods change the state of the class).
I use singletons, so I can tell you exactly why I do it instead of a static function.
The defining characteristic of a singleton is that it is a class that has just one instance. It is easy to see the "just one instance" clause and forget to see the "it is a class" clause. It is, after all, a normal class object with all the advantages that that brings. Principly, it has its own state and it can have private functions (methods). Static functions have to do both of these in more limited or awkward ways.
That said, the two complement each other: a static function can be leveraged to return a singleton on the same class. That's what I do in the singleton I use the most often: a database handler.
Now, many programmers are taught that "singletons are bad, mm'kay?" but overlook the rider that things like are usually only bad when overused. Just like a master carver, an experienced programmer has a lot of tools at his disposal and many will not get a lot of use. My database handler is ideal as a singleton, but it's the only one I routinely use. For a logging class, I usually use static methods.
Singletons allow you to override behavior. Logger::add('1') for example can log to different devices only if the Logger class knows how. Logger::getLogger()->add('1') can do different things depending on what subtype of Logger getLogger() returns.
Sure you can do everything within the logger class, but often you then end up implementing the singleton inside the static class.
If you have a static method that opens a file, writes out and closes it, you may end up with two calls trying to open the same file at the same time, as a static method doesn't guarantee there is one instance.
But, if you use a singleton, then all calls use the same file handler, so you are always only having one write at a time to this file.
You may end up wanting to queue up the write requests, in case there are several, if you don't want them to fail, or you have to synchronize in other ways, but all calls will use the same instance.
UPDATE:
This may be helpful, a comparison on static versus singleton, in PHP.
http://moisadoru.wordpress.com/2010/03/02/static-call-versus-singleton-call-in-php/
As leblonk mentioned, you can't override static classes, which makes unit testing very difficult. With a singleton, you can instantiate a "mock" object instead of the actual class. No code changes needed.
Static classes can have namespace conflicts. You can't load 2 static classes of the same name, but you can load 2 different versions of a singleton and instantiate them under the same name. I've done this when I needed to test new versions of classes. I instantiate a different version of the class, but don't need to change the code that references that class.
I often mix singletons and static. For example, I use a database class that ensures there is only 1 connection to each master (static) and slave (singleton). Each instance of the db class can connect to a different slave, if a connection to the same slave is requested, the singleton object is returned. The master connection is a static object instantiated inside each slave singleton, so only 1 master connection exists across all db instantiated objects.

Extending a class with common functionality

I have three classes which basically do very similar things;
Store a record of an uploaded file.
Move and upload the file.
Set the status of the record to active or revoked.
One of the classes has an additional update method. Each class references a different table in the database because although some of the fields are common, there are a couple of fields extra in some of the tables.
As quite a lot of the functionality is common I think it may be best to extend a base class rather than duplicating a lot of the functionality.
My only quarrel is the construct function on the base class. As some of the fields in each table are additional I'm concerned this will prevent a base class.
I have thought of using an abstract class as this will allow me to extend on functionality whilst maintaining most of the things in one place. But it's the problem with the construct. Can I have an abstract class with no construct?
Any ideas?
If I understand you: You can have any class without __construct(). And you can always overwrite every method (except methods, that are declared as final) of a parent class in a child class.
I am sorry but I guess I do not completely understand your question. Anyway in inherited class you can always override the constructor and within it invoke the superclass constructor plus further stuff if needed.

Categories