Multiple definitions (versions) of a class without conflicts - php

So recently I came up with this idea to store some very common functions needed for PrestaShop modules in my own extended version of a class:
class MyModule extends Module { ...
There are lot of functions / common code lines / missing functionality that can be stored in an extended class. What I would like to do is to keep this class, add and refine it with the functionality that I need to speed up module development. So later I can just pop it in (the newest version of this class) and dramatically reduce the amount of code lines:
require_once('core/classes/MyModule.php');
class MyModuleName extends MyModule { ...
However, I also realized that I won't be able to do this if the application (PrestaShop) has two or more modules that use this class, because there will be a class definition conflict. PrestaShop does have override functionality, but it is not an option, because if it detects a method that is already overriden, it throws an error (does not allow conflicts). We make a lot different modules, some of them we update, some of them we don't so we don't know how many of our modules the client PrestaShop system will have and which versions they will. Each module should be standalone, but should not conflict with other modules (if the exists and use the extended class).
PHP Fatal error: Cannot redeclare class
Is there any way I can make this happen (using namespaces or something else)?
Is it bad practice to have multiple definitions of a class?
Would it affect performance by much ?
In MyModule case, I need to have access to Module object ($this) to define most of my extended functions.
I also would like to have MyTools class with static methods, but naturally it faces the same problem. Do you think that defining helper functions like this would be the way to go ? :
if(!function_exists(myFunctionName)){
function myFunctionName(){
}
}

In my opinion, the best way to achieve this is to duplicate your class in every module you use, for this reason : your module have a dependency with an external class who will change in the time, so if you change something in your helper class for Module A, there will be no impact on Module B since Module B use its own helper. This is already how PrestaShop do with some modules to keep a compatibility between 1.4 and 1.5 version, with a backward_compatibility/ folder on each module.

Related

factorize a php object separate the methods for a joomla component

I am currently creating a component for joomla, so I use PHP in POO with the MVC model of joomla! For my component I end up with a huge code of more than 3800 lines, I would like to factorize / separate this code so that it is more readable later.
To do this I would therefore like to separate the methods in a separate file in order to recall them in the code.
I tested several solution but which does not work, I mi a method in a file methode.php, I then used include ('methode.php'); but I have the impression that it does not work in an object.
I also tested the require and require_ once. as well as a joomla! : jimport ('method.php');
I think there is a relatively accessible solution to this problem, however I can not find a solution with my research.
Joomla loads classes, the method declarations need to be in the class that Joomla imports. I am not sure how the autoloader interferes with requires and imports. I would go about using inheritage. Build a base class that inherits from the appropriate joomla class and inherit a few times with incresing functionality. Not the intuitive way, but that's how I see Joomla do it.

How can I have my trait extend a class

I understand that by definition, a trait cannot extend a class, however I'm wondering if there's some kind of workaround.
My situation:
I created the package revisionable, which in its first incarnation was a class that you extended from your model which itself extended Laravels base Eloquent class, however over time there were plenty of requests to change this into a trait, so people could use revisionable, and be able to extend their own base class.
Currently, the only that I can think to allow for both an extendable class, and a trait, is to offer both as a whole files, which means I'm repeating the entire code in two files which could easily lead to trouble down the road.
I'm wondering if anybody knows of some solution where I can have one file that is god, and the other file relies on it.
Rules
The existing class cannot use a trait, as existing users of the package on php 5.3 will not have access to traits.
There's absolutely no way to accomplish what you want.
Since Laravel itself (in 4.2) has now abandoned PHP 5.3, it's time to move on too.
Tag a new release that drops the class, add a PHP 5.4 requirement to your composer.josn file, and add this information to your docs.
Anyone still stuck on 5.3 can always just composer require your previous version.
Php 5.3 is a problem.
Back in when it was popular, the programming style was all about include/require files into another files. If you can split your functionality into functions that may be included in trait and in class - it may be a solution. But it depends of the functionality.
Modern way would be decoupling and dependency injections, in other words think units and unittesting.
Problem of a trait as well as the problem of the child-class is that you cannot unittest the pure functionality of what you have done without touching the parent class functionality. You cannot mock parent class, you can only mock injected class, right?
Think modern. Create a class, inject Eloquent object there. And then use this class in traits and some parent class for laravel models.
And forgive Taylor for the fact that you cannot mock the Eloquent. He may be able to fix it in new versions of Laravel. But you'll have to move to PHP7 because it is a requirement for latest laravel releases.

Calling Models in Module in Zend Framework

I have a structure that is
application
application/modules
application/modules/default
application/modules/default/models
application/modules/admin
application/modules/admin/models
When calling controllers in admin I understand they must be named like Admin_TestController. This works fine, but my models in my admin module don't seem to be able to load. I have tried naming them and the files in all kinds of ways but it just doesn't seem to want to be able to load them. How should I name the file and model class in a module to be able to use it? I use autoloading.
What do your bootstrap files look like? That is the most import part of problem.
It is very important (in order for the namespaces to autoload) that you you have a bootstrap in each module (located # application/modules/admin/bootstrap.php) that should contain, at the very least:
class Reports_Bootstrap extends Zend_Application_Module_Bootstrap
Notice that it extends Zend_Application_Module_Bootstrap. This does the heavy lifting of registering the namespaces for the MVC of the module.
As Fatmuemoo states the bootstrap for the module should extend Zend_Application_Module_Bootstrap also you should include
resources.modules[] =
In your config. This is in the docs for Zend_Application_Resource_Modules
It seems you need to include a bootstrap class that extends Zend_Application_Module_Bootstrap for the modules you want to use. Check this forum post about a similar issue to see if it helps point you in the right way. Seems you may need more than one to load separate modules.

Having the option of customized classes but a unified class name

Suppose you are building a web application that is going to be a packaged product one day, one that users will want to be able to extend and customize.
It comes with a core library consisting of PHP files containing classes:
/library/
/library/frontend.class.php
/library/filesystem.class.php
/library/backend.class.php
Now, suppose you want to keep a clean core that users can't patch. Still, you want the user to be able to customize every nut and bolt if need be.
My current idea is to create an autoloading mechanism that, when a class is instantiated, first loads the core include:
/library/frontend.class.php
then, it switches to the user directory and looks whether there is an include of the same name:
/user/library/frontend.class.php
if one exists, it includes that as well.
Obviously, the user include must contain a class definition that extends the definition in the core include.
Now my question is, how would I instantiate such a class? After all, I can always be sure there is a definition of:
class frontend_core
but I can not be sure there is a
class frontend_user extends frontend_core
However, I would like to be able to rely on, and instantiate, one class name, regardless of whether there was a custom extension to the class or not.
Is there a clever way, idea, or pattern how to achieve this?
Of course, I could write a simple factory helper function that looks for the user class first and then for the core class and returns an initialized object, but I would really like to keep this as clean and simple as possible, because as I said, it is going to be a packaged product.
I am looking for a smart trick or pattern that uses as little code, and introduces as little new functionality, as possible.
Why don't you follow the approach as used by Propel? You generate your base classes and already provide an empty User class (extending the base class) where your users can put their overrides/specific implementation details, and in your code you always refer to the User classes. So basically you just use the inverse of the logic you described.
If the explanation above isn't clear, check out http://propel.phpdb.org/trac/wiki/Users/Documentation/1.4/QuickStart#a6.UsingtheGeneratedSQLandOMFiles and generate code for a small database. The base classes are in the om folder, the (by default empty) user classes are in the root folder.
I would implement hooks in the core, so users dont have to hack the core, but are still able to extend the core using hooks
I'd go with using the constructor of the core class to determine the user class to load, and then implement a factory method in the core class to generate instances of the user class. By making the constructor of the user class protected, and having the user class extend the core class you can be sure that code elsewhere cannot instantiate the user class.
C.
I think it's more complicated with a single filename when you want to use inheritance as well. Basically class user_frontend extends core_frontend has to know where to find both classes. Both must be included.
If you just want to do new Frontend you could use PHP5.3's class_alias to point Frontend to the main class to use. Below 5.3. you could use a ServiceFinder, that knows how to map Service Names to Classes and then get the Frontend with $service->get('frontend') or use a Dependency Injection framework.
Edit I removed the Loader code given before, because it was suffering from exactly this problem.
You could have a loader class that will decide which class to instance:
Loader::instance()->load('Frontend')

Plugin Architecture in PHP

I am planning on doing a research on how to implement a plug-in architecture in PHP. I have tried searching the web for possible references, but I thought that maybe my search for a good reference would be faster and more relevant if I asked here.
Has anyone here tried using plug-in architecture for web projects?
Thanks,
Erwin
I have written wordpress plugins and the magic that they rely on is "Variable Function Names". For instance this is valid php, in which the function call phpinfo() will be called:
$func_name="phpinfo";
$func_name();
This allows developer to "Hook" function calls, as in override them with their own functions without having change the rest of the application. Linux Kernel modules are all about "hooking", they wouldn't work without this behavior.
Unfortunately for PHP variable function names are a disgusting hack that consumes a lot of resources. All functions in a name space are put in a list and this list has to be searched though before the function is called, this is O(log2(n)). Also keep in mind that Variable Function Names can not be accelerated properly in HipHop although the code will still be transformed into valid C++. A better approach would be to re-declare functions like you can in python which would be O(1) complexity, but the PHP development team HATES this idea (Yes, I've asked for this feature!).
Good luck!
There are a lot of concepts that can be considered a 'plugin'. You can write a plugin system using:
Event dispatchers (see the Symfony Event Dispatcher)
Middlewares (see Silex middlewares)
Observer OO pattern (see Google / Wikipedia)
And many others
You could take a look at how Zend Framework implemented their Plugin Loader component.
Basically you set path´s to where plugins are stored and the loader tries to load the first plugin found in a LIFO way.
What about these two classes
Plugin Handler/Loader
Plugin
and there are some rules
Plugin Handler/Loader is a singleton class and manages all child clases of Plugin Class.
Any plugins should have to be inherited from Plugin Class.
Plugin Class would have pre-defined properties and methods which can be overwritten by its child classes, so alternate method to hook system (but i am not sure of any major difference in results).
For example say Plugin class has a property of url_routes with default value of an empty array, the child class can then overwrite and add any required urls in this array.
Plugin Handler/Loader will then add these url routes from child class to underlying system.
don't forget about function __autoload. you can dynamically load components.
like:
SomeModule::test();
function __autoload($class)
{
$class = preg_replace('/^\W/', '', strtolower($class));
include 'modules/'.$class.'.php';
}

Categories