PHP: is there an instance of class in use? - php

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.

Related

Abstract class calling a method from the wrong child class

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.

Load a particular version of a class when Autoload is used

Consider a large application which autoloads classes as such:
function __autoload($class)
{
require_once("/var/www/application/classes/{$class}.php");
}
There may be tens of files which use the class, all of which relied on a particular bug in the class. Now that I've fixed the bug, I need to update all the places where the class is called.
From within the class, I would like to whitelist known-fixed places where the class is called from where I have fixed the bug. For the un-whitelisted places, I would replicate the old behaviour and in the whitelisted places I would give the correct behaviour. Is there a clean way to do this?
I was thinking about adding a new constructor argument $useFixedVersion for the duration of the fix (which might take a few days), and then going back and removing that argument afterwards. However, this means that I need to go over each place twice and it seems a rather bad workaround. Is there a better way to detect from where the class is being called? Consider that both instance and static methods are affected.
Let us ignore the coupling and bad code design for a moment which means that I need to correct the calling code, and take this unfortunate fact as a given. Let us also ignore the unfortunate fact that I cannot simple branch off in Git, make my fixes, and then push to production!
There is a debug_backtrace() function, which would allow you to know where things are getting called from:
http://php.net/manual/en/function.debug-backtrace.php
That said, have you considered using namespaces for this? Something like:
namespace Foo\Bar;
class FixedBaz extends Baz {}
And then alias the classes as needed:
namespace Foo\Bar;
use FixedBaz as Baz;

How to use one object in another class : PHP framework

This is my current system for a framework that I'm making:
I create an object upon a request to access a non-existing property, that has the name of an existing class through the __get function defined in the Core class. The Core class extends every class.
So it works like this:
class Someclass extends Core
{
public function classmethod()
{
$this->otherclass->method();
}
}
This works exactly how I want it to work. However, I have no idea (after a lot of frustration) how to edit/create properties of the object, using this system.
So something like this would't work.
$this->view->somevar = "newvalue"; // this doesn't work.
I guess it has to do something with the __set function, but I failed to find out.
I received the following suggestions how to tackle this problem:
Dependency injection, Namespaces, Singleton pattern.
I would love to see how to implement what I'm trying to do using one of these patterns.
I have no idea which to choose in order to achieve my simple problem: Use objects in other classes, so i don't need to put anything into __construct's parameters or using global variables.
I am using __autoload.
I hope i can tackle this problem with your help.
First of all, the architecture you're attempting is extremly bad. Aparently you are using "magic" to create objects attached as properties to other objects. Which is bad, because if you use _get/_set, you will end up in problems sooner rather than later. Also extending from a common parent is a bad thing because it generates huge inheritance trees, and it allows most of the objects to have more than one responsability.
Before starting a framework, you might want to look over: SOLID
Now coming back to your question, if you use __get for getting a value, you can as well use __set for setting a value.
__construct method is there in order to allow you to initialize the object with all the data it needs in order to fulfill his sole purpose. Avoiding the __construct is kinda stupid, and defeats the purpose. You might want to pay attention to the D in SOLID in order to see what Dependency Inversion really is and to understand it.
Using __set loses completely the ability to typehint interfaces and so on. Therefore the code can become really buggy and ijcredibly hard to follow, since the flow is not so well defined, and the allocation is done in the back via magic. Also i can come up with 1 million other reason for which the architecture you are trying to use is wrong, but i will leave that for another time.

A group of related PHP functions: what is the most acceptable way to organize them?

This might be a stupid question but I have to ask:
I have a big group of related functions for a project I am doing. The functions need to access a few global variables, so I was thinking about putting them into a class and loading the class as needed. I suppose my other option is to just include them as unrelated functions in an included PHP file, but putting them into 1 class seems to make sense. Is this an acceptable practice? I have worked with people who did this but it always seemed to not quite be in the spirit of good OOP practices because the classes were almost never instantiated but the functions were still called. Or maybe I'm over thinking it.
Any input would be awesome, thanks a bunch.
A class does make the most sense. Whenever you can eliminate global variables, it is a good thing. Whether the class is instantiated or a static helper usually depends on the context. However, for future unit testing, instantiations allow dependency injection.
According to http://en.wikipedia.org/wiki/Class_%28computer_programming%29, a class defines constituent members which enable class instances to have state and behavior. If you will be providing only behavior (functions) and not state (properties), you should include your functions in an include file and forgo the overhead of a class.
Correct me if I'm wrong but this seems like you should create a class that acts as a static service, where no explicit instantiation is needed of the class, yet you will still call the methods contained within this class.
Now, if you're thinking of storing those global variables in the class, obviously that's no longer a static class because there would have to be some sort of lifetime for the object, and at which point you'd have to instantiate the class first and then make calls to those methods.
Regardless, if they're all related functions working on the same data, it certainly makes sense to group them within their own class.

Drawbacks of static methods in PHP

In a theoretical database access class, I found that there are quite a few helper functions that I use in the class, which have nothing to do the class's instance (and others, that could be manipulated to be unrelated to the class's instance using dependency injection).
For example, I have a function that gets a string between two other strings in a variable. I've been thinking of moving that to a String_Helper class, or something of the sort. This function has already been made static.
Also, I have a function that queries a database, query($sql). The connection details are provided by the instance, but I've been considering making it static, and using query($sql, $connection). Developers would then be able to call it statically and not need to instantiate the database class at all.
For me, the questions are:
Is it worth it to do something like this? Functions like the query function make me wonder if this is not just me trying to make everything as static as possible, without any real need to. Under what circumstances would you consider this useful?
I know static functions are harder to test, but if I make sure that their code is completely dependency free (or uses dependency injection where necessary), then they're just as easy to test as everything else, surely?
It isn't a concern at the moment, but if, in the future, I decided to extend the classes with the static functions, it would be impossible for me to make the current code use my extended functions. I've thought of Singletons, but the same problem arises: the code would be calling Singleton_Class::getInstance(), and not My_Extended_Singleton_Class::getInstance(). Dependency Injection seems to be the only way to solve this issue, but it might lead to a clunkier API, as every dependency has to be given to an object on __construct().
I have a container class, which holds certain pieces of information statically so that they can be accessed anywhere in the script (global scope). If I can't use static functions or singletons, a class that contained instances of different variables would be great. One could use for example Container::$objects['MyClass'] = $MyClass_object;, and then the rest of the code could just access Container::$objects['MyClass']. If I extended the MyClass class, I could use Container::$objects['MyClass'] = $MyExtendedClass_object;, and the code that used Container::$objects['MyClass'] would use MyExtendedClass, rather than MyClass. This is by far the best way to do it, in my opinion, but I'd like to know what you think about it.
Ok, let me answer these one by one...
1. Is it worth doing something like this
Yes and no. Splitting out the helper functions into their own classes is a good idea. It keeps the "scope" of each of the classes rigidly defined, and you don't get creap. However, don't make a method static just because you can. The query method is there to make your life easier by managing the connection, so why would you want to lose that benefit?
2. They are harder to test
They are not harder to test. Static methods that depend on state are harder to test (that access static member variables or global variables). But static methods in general are just as easy to test as instance methods (in fact, they can be easier since you don't need to worry about instantiation).
3. Extending the classes
This is a valid concern. If you put String_Helper::foo() in the class itself, you'll run into issues. But an option would be to set the name of the string helper as a class variable. So you could then do {$this->stringHelper}::foo() (note, PHP 5.3 only). That way to override the class, all you need to do is change the string helper class in that instance. The Lithium framework does this a lot...
4. Global Registry
I would stay away from this. You're basically just making every class a singleton without enforcing it. Testing will be a nightmare since you're now dependent on global scope. Instead, I'd create a registry object and pass it to classes via the constructor (Dependency Injection). You still accomplish the same thing since you have a store for the objects/classes, but you're no longer dependent on a global scope. This makes testing much easier.
In general
When you're looking at doing things like this, I like to stop when I hit questions like this. Stop and sit down and think *What actual problem am I trying to solve?". Enumerate the problem explicitly. Then pull our your supposed solutions and see if they actually solve them. If they do, then think about the future and if those solutions are really maintainable in the long run (Both from a bug fix standpoint, and with respect to feature additions). Only if you're happy with both of those answers should you even consider doing it. Oh, and also remember to keep it simple. Programming is not about making the most complex, most clever or most amazing solution. It's about making the simplest solution that solves the problem...
I hope that helps...
Good Luck!

Categories