Need some guideline to refactor my php code in OOP concept - php

I wrote a wordpress plugin that works fine. However, it just works but there is no OOP here because at that time it was necessary to build something asap. I read some literature and found that php do not support multiple inheritance due to diamond problem.
Current scenario:
Flickr
--pic importer
----1. sql.php
----2. javascript.php
----3. call to show database contents
--photoset importer
----1. sql.php
----2. javascript.php
----3. call to show database contents
Here, I have created 2 class: picImporter and photosetImporter. Both classes share common contents from (1. sql.php and 2. javascript.php) but point-3 (implementation of showing database content is differnt for them).
So, my idea is: I should create another class Global and photosetImporter, picImporter class should extend this class. In the Global class there should be an abstract class that child class must define. So the design becomes:
Class Global{
//$sql comes sql.php,
//$javacript comes javascript.php,
abstract protected function showDatabaseContents();
}
Class picImporter extends Global{
protected function showDatabaseContents() {
//implementation using **$sql** from base
}
}
Class photosetImporter extends Global{
protected function showDatabaseContents() {
//implementation using **$javascript** from base
}
}
Before I proceed, I just want to know if I am on right track or not and further instruction if possible.
Thanks,
-S.

There's no particular "right" way to do what you're looking for (though there are wrong ways). Hard to know what method I would use without understanding what your javascript class does.
Typically, I create a single global DB abstraction class (what I assume your sql class is) and just access it from the global scope wherever I need it. Global scope isn't evil, especially for things like database access which aren't inherent to whatever other classes you're creating but are needed pretty much everywhere. The same may be true for your javascript class.
That said, if you need this sort of abstraction to maintain a consistent design in your application, then I see no problem with what you're doing here, this seems like a logical approach.
If you're looking for what might be a best practice, run a search for "PHP design patterns", but in general my approach with PHP is to keep it simple and accessible. That may mean using a design pattern, or it may mean a more basic approach, depending.

Related

Multiple inheritance, traits and properties, how to do this the best way?

I have some classes to interact with the different types of databases. Each db-class needs to extend some general classes.
Like:
<?php
mysql\SelectSql extends common\SelectSqlAbstract
mysql\SqlComposer extends common\SqlComposerAbstract
?>
The problem is that SelectSql should also extend the SqlComposer-classes.
This is not possible in PHP because it would need multiple-inheritance.
So I am trying a workaround and rewriting SqlComposer as a trait. (I also tried to use SelectSqlAbstract as trait) Then the structure is:
<?php
class mysql\SelectSql extends common\SelectSqlAbstract{
use mysql\SqlComposerTrait
}
abstract class common\SelectSqlAbstract extends common\SqlComposerAbstract{
protected $sqlType = 'select';
}
abstract class common\SqlComposerAbstract{
protected $sqlType;
protected $dbType;
}
trait mysql\SqlComposerTrait{
protected $dbType = 'mysql';
}
?>
This is really not best practice and it will give a fatal error.
But how else can I do this? I don't want to get the properties by an function which extract it from the classnames/namespace.
And is there a better way to get this structure when you need 2 types of levels:
specificNS\SpecificClass
extends commonNs\SpecificClass
extends specificNs\CommonClass
extends commonNs\CommonClass
Composition wont really help. Because most of the functions will be in de commonNs. Only a few functions will be overridden bij the specificNs
It won't help to alias classes (I think) because I need to use more types of databases in one script...
Whether using ORM is the only best practice or staying with one's own code is the way to go is a totally different debate and I am sure there are as many opinions on this as are the number of developers out there.
As you have been with your code for years now, that means it works and you know every bit and piece of your code by now, so stick with what you have and make it better gradually by refactoring.
Now coming to the question, if you are trying to rewrite your DB access logic from scratch and all you want to do is be able to switch databases easily later on without having to modify a pile of classes, I would recommend to have a look at the design patterns other than the one you are stuck with.
For example in your case, try strategy pattern, or builder pattern where you can decide the logic at runtime.
for PHP specific use cases, check https://github.com/domnikl/DesignPatternsPHP
Composition should definitely help, and rather it will produce more elegant and readable code that the one you are trying to achieve via multiple inheritance.

Should Helper Functions be in a Class?

In my efforts to rewrite a past project of mine with OOP in mind, I have broken my code up into classes such as Devices, Facilities, etc.
Before moving to a more object oriented approach, I just stuck all of my helper functions in an included "functions.php" file. Using Devices as an example, would it be best to have a Devices class for my object specific properties/methods, then have a DeviceManager class to store functions like getDeviceByName, getDeviceByID, etc?
From what I am understanding, OOP is more about readability/manageability than anything else, why I assume the purpose would just be to have something like DeviceManager::GetDevice("Computer1") in place of GetDeviceByName("Computer1")
If you are thinking of using a class as a namespace then you can just as well use an actual namespace:
namespace MyCollectionOfFunctions;
function printMyName($name) {
echo $name;
}
And then you can use the functions like this:
use MyCollectionOfFunctions as fn;
echo fn\printMyName('Brett Powell');
There is nothing wrong with functions. Do not let anyone tell you that they belong is a class, as static methods. It can be done that way, but since we got namespaces there really is no reason for it.
In a OOP languages like C# or Java, you simply can't have functions outside a class, so there's no issue. That doesn't mean you're doing OOP, which is a mindset.
In PHP you can either put the relevant functions into a nampespace or within a class (inside a namespace). It's up to you, there's no right or wrong approach. Personally, I'd put them into a class because that's how I'm doing it in C# and it'll help a bit with productivity: I group related functionality in one place (class). It's easier to manage.
But strictly from a programming point of view, there's no difference, your code won't be cleaner/decoupled or more OOP because you've put functions into a class or namespace
A few advantages when using Namespace or Class for static functions.
Namespace and Class Name helps distinguish functions. You can avoid naming conflicts.
DPDate::FirstDayOfMonth() is better than FirstDayOfMonth() when you want to take advantage of auto suggestion of the IDE.
It is really all about cohesion and decoupling.
You must following this rules:
In OOP you MUST ALWAYS use a CLASS
Your method must have a single responsability
Avoid generic helper classes, classes must have a simple and specific responsability
Don't use static methods, use strategy (pass the object throw the param) to call a method, this way you can create a Mock to test your methods.
Avoid private methods, this make dificult to test your classes
Keep this things in mind, and you will gona make a clean code. =)
Answering Eric about item 4: This code it will use static method:
public function myFunction() {
$deviceId = DeviceManger::getDeviceId('computer 1');
// Rest of code using the device id
}
This way i cant mock the return of Device ID, this way i can:
public function myFunction(deviceManger) {
$deviceId = deviceManager->getDeviceId('computer 1');
// Rest of code using the device id
}
The code with mock in test function:
$deviceManager = $this->getMock('DeviceManager');
$deviceManager->method('getDeviceId')->returnValue(1);
myFuncion($deviceManager);

PHP workaround to extend classes of the same name?

I know extending a class with the same name is not possible, but I was curious if anyone knew of a way to load a class then rename it, so i can later extend it with the original name. Hopefully like something below:
<?php
//function to load and rename Class1 to Class2: does something like this exist?
load_and_rename_class('Class1', 'Class2');
//now i can extend the renamed class and use the original name:
class Class1 extends Class2{
}
?>
EDIT:
Well, I understand that this would be terrible practice in a basic OOP environment where there are large libraries of class files. But i'm using the CakePHP MVC framework and it would make great sense to be able to extend plugin classes in this way since the framework follows a well established naming convention (Model names, view names, controller names, url routes (http://site.com/users), etc).
As of now, to extend a CakePHP plugin (eg: Users plugin) you have to extend all the model, view, and controller classes each with different names by adding a prefix (like AppUsers) then do some more coding to rename the variable names, then you have to code the renamed url routes, etc. etc. to ultimately get back to a 'Users' name convention.
Since the MVC framework code is well organized it would easily make sense in the code if something like the above is able to be implemented.
I'm trying to work out why this would be necessary. I can only think of the following example:
In a context that you have no control over, an object is initialised:
// A class you can't change
class ImmutableClass {
private function __construct() {
$this->myObject = new AnotherImmutableClass();
}
}
$immutable = new ImmutableClass();
// And now you want to call a custom, currently non existing method on myObject
// Because for some reason you need the context that this instance provides
$immutable->myObject->yourCustomMethod();
And so now you want to add methods to AnotherImmutableClass without editing either Immutable class.
This is absolutely impossible.
All you can do from that context is to wrap that object in a decorator, or run a helper function, passing the object.
// Helper function
doSomethingToMyObject($immutable->myObject);
// Or decorator method
$myDecoratedObject = new objectDecorator($immutable->myObject);
$myDecoratedObject->doSomethingToMyObject();
Sorry if I got the wrong end of the stick.
For more information on decorators see this question:
how to implement a decorator in PHP?.
I happen to understand why you would want to do this, and have come up with a way to accomplish what the end goal is. For everyone else, this is an example of what the author may be dealing with...
Through out a CakePHP application you may have references to helper classes (as an example > $this->Form->input();)
Then at some point you may want to add something to that input() function, but still use the Form class name, because it is through out your application. At the same time though you don't want to rewrite the entire Form class, and instead just update small pieces of it. So given that requirement, the way to accomplish it is this...
You do have to copy the existing class out of the Cake core, but you do NOT make any changes to it, and then when ever you upgrade cake you simply make an exact copy to this new directory. (For example copy lib/Cake/View/Helper/FormHelper.php to app/View/Helper/CakeFormHelper.php)
You can then add a new file called app/View/Helper/FormHelper.php and have that FormHelper extend CakeFormHelper, ie.
App::uses('CakeFormHelper', 'View/Helper');
FormHelper extends CakeFormHelper {
// over write the individual pieces of the class here
}

Is it ever okay to have a class as a collection of methods and no properties?

I'm writing a bunch of generic-but-related functions to be used by different objects. I want to group the functions, but am not sure if I should put them in a class or simply a flat library file.
Treating them like a class doesn't seem right, as there is no one kind of object that will use them and such a class containing all these functions may not necessarily have any properties.
Treating them as a flat library file seems too simple, for lack of a better word.
What is the best practice for this?
Check out namespaces:
http://www.php.net/manual/en/language.namespaces.rationale.php
Wrapping them in a useless class is a workaround implementation of the concept of a namespace. This concept allows you to avoid collisions with other functions in large projects or plugin/module type deployments.
EDIT
Stuck with PHP 5.2?
There's nothing wrong with using a separate file(s) to organize utility functions. Just be sure to document them with comments so you don't end up with bunchafunctions.php, a 20,000 file of procedural code of dubious purpose.
There's also nothing wrong with prefixes. Using prefixes is another way to organize like-purpose functions, but be sure to avoid these "pseudo-namespaces" already reserved by the language. Specifically, "__" is reserved as a prefix by PHP [reference]. To be extra careful, you can also wrap your function declarations in function_exists checks, if you're concerned about conflicting functions from other libraries:
if (!function_exists('myFunction')) {
function myFunction() {
//code
}
}
You can also re-consider your object structure, maybe these utility functions would be more appropriate as methods in a base class that all the other objects can extend. Take a look at inheritance: http://www.php.net/manual/en/language.oop5.inheritance.php. The base class pattern is a common and very useful one:
abstract class baseObject {
protected function doSomething () {
print 'foo bar';
}
public function getSomething () {
return 'bar foo';
}
}
class foo extends baseObject {
public function bar () {
$this->doSomething();
}
}
$myObject = new foo();
$myObject->bar();
echo $myObject->getSomething();
You can experiment with the above code here: http://codepad.org/neRtgkcQ
I would usually stick them in a class anyway and mark the methods static. You might call it a static class, even though PHP actually has no such thing (you can't put the static keyword in front of a class). It's still better than having the functions globally because you avoid possible naming conflicts. The class becomes a sort of namespace, but PHP also has its own namespace which may be better suited to your purpose.
You might even find later that there are indeed properties you can add, even if they too are static, such as lazy-loaded helper objects, cached information, etc.
I'd use classes with static methods in such case:
class Tools {
static public function myMethod() {
return 1*1;
}
}
echo Tools::myMethod();
EDIT
As already mentioned by Chris and yes123: if the hoster already runs PHP 5.3+, you should consider using namespace. I'd recommend a read of Matthew Weier O'Phinney's article Why PHP Namespaces Matter, if you're not sure if it's worth switching to namespaces.
EDIT
Even though the ones generalizing usage of static methods as "bad practice" or "nonsense" did not explain why they consider it to be as such - which imo would've been more constructive - they still made me rethinking and rereading.
The typical arguments will be, that static methods can create dependencies and because of that can make unit testing and class renaming impossible.
If unit testing isn't used at all (maybe programming for home/personal use, or low-budget projects, where no one is willing to pay the extra costs of unit testing implementations) this argument becomes obsolete, of course.
Even if unit testing is used, creation of static methods dependencies can be avoided by using $var::myMethod(). So you still could use mocks and rename the class...
Nevertheless I came to the conclusion that my answer is way too generalized.
I think I better should've wrote: It depends.
As this most likely would result in an open ended debate of pros and cons of all the different solutions technically possible, and of dozens of possible scenarios and environments, I'm not willing going into this.
I upvoted Chris' answer now. It already covers most technical possibilities and should serve you well.
Treating them as a class does give you the benefit of a namespace, though you could achieve the same thing by prefixing them like PHP does with the array_* functions. Since you don't have any properties, that basically implies that all your methods are static (as Class::method()). This isn't an uncommon practice in Java.
By using a class, you also have the ability, if necessary, to inherit from a parent class or interface. An example of this might be class constants defined for error codes your functions might return.
EDIT: If PHP 5.3+ is available, the Namespace feature is ideal. However, PHP versions still lag in a lot of hosts and servers, especially those running enterprise-stable Linux distributions.
I've seen it a few different ways, all have their warts but all worked for the particular project in which they were utilized.
one file with all of the functions
one file with each function as its own class
one massive utilities class with all of the methods
one utils.php file that includes files in utils folder with each
function in its own file
Yes, it's OK formally... As any class is methods + properties. But when you pack in class just some functions -- it`s become not ideal OOP. If you have bunch of functions, that groupped, but not used some class variables -- it' seems, that you have somewhere a design problem.
My current feeling here is "Huston, we have a problem".
If you use exactly functions, there one reason to wrap them in static class - autoloader.
Of course, it creates high coupling, and it's may to be bad for testing (not always), but... Simple functions are not better than static class in this case :) Same high coupling, etc.
In ideal OOP architecture, all functions will be methods of some objects. It's just utopia, but we should to build architecture as close as we can to ideal.
Writing a bunch of "generic-but-related" functions is usually bad idea. Most likely you don't see problem clear enough to create proper objects.
It is bad idea not because it is "not ideal OOP". It is not OOP at all.
"The base class pattern" brought by Chris is another bad idea - google for: "favor composition over inheritance".
"beeing extra careful" with function_exists('myFunction') is not but idea. It is a nightmare.
This kind of code is currently avoided even in modern javascript...

Functions outside the class

I just want to tell you that I am newbie to OOP and it is quite hard to me, but here is my code:
class functions
{
function safe_query($string)
{
$string = mysql_escape_string(htmlspecialchars($string));
return $string;
}
}
class info
{
public $text;
function infos($value)
{
echo functions::safe_query($value);
}
}
Is there any way to make this sentence : echo functions::safe_query($value); prettier? I can use extends, than I could write echo $this->safe_query($value);, but is it a best way? Thank you.
edit: and maybe I even can to not use class functions and just make separate file of functions and include that?
Yes, just define your function outside of a class definition.
function safe_query($string){
return mysql_escape_string(htmlspecialchars($string));
}
Then call it like this
safe_query($string);
Using a functional class is perfectly fine, but it may not the best way to design your application.
For instance, you might have a generic 'string' or 'data' class with static methods like this (implementation missing, obviously):
class strfunc{
public static function truncate($string, $chars);
public static function find_prefix($array);
public static function strip_prefix($string);
public static function to_slug($string); #strtolower + preg_replace
etc.
}
The point of a class like this is to provide you with a collection of generic, algorithmic solutions that you will reuse in different parts of your application. Declaring methods like these as static obviates their functional nature, and means they aren't attached to any particular set of data.
On the other hand, some behaviors, like escaping data for a query, are more specific to a particular set of data. It would probably be more appropriate to write something like this, in that case:
class db_wrapper{
public function __construct($params); #connect to db
public function escape($string);
public function query($sql);
public function get_results();
}
In this case, you can see that all of the methods are related to a database object. You might later use this object as part of another object that needs to access the database.
The essence of OOP is to keep both the data and its relevant behavior (methods) in one place, called an object. Having behavior and data in the same place makes it easier to control data by making sure that the behavior attached to the data is the only behavior allowed to change it (this is called encapsulation).
Further, having the data and behavior in one place means that you can easily pass that object (data and behavior) around to different parts of your application, increasing code reuse. This takes the form of composition and inheritance.
If you're interested in a book, The Object-Oriented Thought Process makes for a decent read. Or you can check out the free Building Skills in Object-Oriented Design from SO's S.Lott. (Tip: PHP syntax is more similar to Java than Python.)
Functions outside a class litter the global namespace, and it's an open invitation to slide back to procedural programming. Since you're moving to the OOP mindset, functions::safe_query($value); is definitely prettier (and cleaner) than a function declared outside a class. refrain from using define() too. but having a functions class that's a mix of unrelated methods isn't the best approach either.
Is there any way to make this sentence
: echo functions::safe_query($value);
prettier?
Not really. IMO having a functions class serves no purpose, simply make it a global function (if it's not part of a more logical class, such as Database) so you can do safe_query($value); instead.
and maybe I even can to not use class
functions and just make separate file
of functions and include that?
Create files for logical blocks of code, not for what type of code it is. Don't create a file for "functions", create a file for "database related code".
Starting with OOP can be a real challenge. One of the things I did was looking at how things were done in the Zend Framework. Not only read the manual (http://www.framework.zend.com/manual/en/zend.filter.input.html, but also look at the source code. It will take some effort but it pays of.
Looking at the context of your question and the code example you posted, I would advice you to look at some basic patterns, including a simple form of MVC, and the principles they are based upon.

Categories