I’ve been creating WordPress plug-ins for some months now and I have developed a set of “base classes” (most are abstract classes but not all of them) that I use with the plug-ins (some are used with all plug-ins, others are used when a plug-in needs the specific thing the class provides – maybe an admin screen or a button on the visual editor or whatever).
This, of course, works great BUT if I update one or more base classes to add some new functionality then if someone has more than one of my plug-ins installed it is very possible for one or more of those plug-ins to crash.
This is because if a plug-in using an older version of the updated class(es) loads earlier then it “reserves” that name and the others that require the updated class don’t have the functionality/fix/etc.
I’ve tried “nice” solutions but the only thing I can get to work reliably is to change the actual base class names for each plug-in, which is far from ideal.
Namespaces obviously work but can’t be used because so many popular hosting companies are using 5.2x versions of PHP (probably why WordPress doesn’t require 5.3 either)
I tried to dynamically create the class names and to use class factories but they didn’t work or didn’t overcome the need to rename all the base classes. I even tried (although I didn’t expect it to work but you never know with PHP):
class childClassName extends $parentClassName
This situation can’t be that unusual (do people really rewrite everything from scratch everytime and/or use distinct class names) but I can’t find a solution and I can’t think of an elegant one. It isn’t even a WordPress issue, multiple applications using common base classes within a company would have the same problem.
I also can’t just force everyone to upgrade all their plug-ins every time because it may crash before they can and I’m not sure it’s reasonable for me require that of them or even that I can personally update and re-test, every time, every one of the what’s now almost 10 plug-ins with more in the future.
My currect best solution is to use factories to create all base classes and to put tokens in my base classes that I can do a global search and replace on so that the class names are unique for each plug-in; note the replaceable tokens alone would work.
Is there some PHP code that will allow me to achieve a simple, easy solution to this common class name conflict issue?
========================================
It doesn’t look like anyone knows how to do this in PHP, maybe it can’t be done, so I went with the way I mentioned above.
I thought I’d put it here because this is what I ended up with that works well, if not what I had hoped, and maybe it can help others:
- I added tokens to the base class names, for example:
class someBaseClass[TokenNameGoesHere] (I used [ReplaceWithVersionNumber])
also
class someChildClass extends someBaseClass[TokenNameGoesHere]
- I created a method called createNewClass and passed the class name (as a string) and any parameters to pass to the new class (in an array).
I also passed information like the token value being used in the application (version number in my case) and the namespace (to be used instead of the token value if I can use PHP 5.3 and above).
I then used reflection to create the class. While reflection is obviously slower I found that I didn’t have that many times when I needed to use createNewClass so the trade off of ease of remembering and increased clarity won out.
$reflectionOfClass = new ReflectionClass($desiredClassName);
$newObject = $reflectionOfClass->newInstanceArgs($ParametersToPass);
Where $desiredClassName is built from the class name and the other parameters: version and namespace in my case.
Then, everywhere I wanted to create a base class object I’d use:
$myNewObject = $this->createNewObject(“someBaseClass”, other parameters);
- When I copied the class library over for a new application I just did a massive search and replace of the token with what I wanted to replace it with in all the files. It could be version number or even an empty string if I don’t have to worry about clashing with other versions of my class library like I do with WordPress plug-ins.
It was pretty easy to do and works great although going back through and inserting the tokens in was tedious.
It all could, of course, be done with just tokens but I didn’t want to have to remember to do put suffixes on the names and which token name I was using and whatnot.
I hope that helps someone and if anyone has a better way (which to me means less code modification and more code clarity) I’d love to hear about it.
Not sure if you’ve found a proper solution to your question yet. I’m dealing with the same problem and my approach (not perfect, but does what I need) would be this one:
Create a class alias of your reusable class from a variable, like this:
Hope it helps!
Yes namespace is perfect solution.
If php could have provided way to unload / load classes problem could have be easily addressed. But again you need to relink / instantiate your other depended active plugins so as to used object of new classes, this involves deactivation and activation of existing plugins.
With same thought I can think of this solution, you very well know you have 1,2,3 .. n plugins using X class. 1 & 2 plugins are using older version of X and you are about to install / update plugin 3 with newer version of X. Deactivate all your plugins & first activate plugin (3) which has your latest features/version of class X, later activate all others.
*provided if its ok to deactivate / activate your plugins & you don’t modify signature of existing functions of class X, you can add new functions though.