i'm trying to follow DRY and i've got some functions i have to reuse.
i put them all as static functions in a class and want to use them in another class.
what is the best way to make them available to a class.
cause i can't extend the class, its already extended.
should/could i use composition?
what is best practice?
thanks!
If they are static then just call them from your second class.
First_Class::method();
Public class methods (vs instance methods, e.g. non-static) are always available from the global scope, so you could just call them statically where needed. But keep in mind that static methods are death to testability and hard couple using classes to the global scope and the used class. You want to avoid that, so it's better practise to get rid of the static methods in favor of instance methods and passing in the dependency/object instance through the constructor or a setter. Add an interface Type Hint if you want to make sure the passed instance has a certain set of methods.
Related
Just startet to feel the real usefulness for classes and methods (Object Oriented Programming) in PHP. However I still lack the understanding and experience declaring methods and variables the proper way.
I what cases should I declare a method/variable static VS declaring it non-static? What questions do I ask myself to answer this question?
Static means that you can access the functions without first creating an instance of the class. This makes it a lot like a normal function. You tend to make functions static if you want to group functions together that are related, but do not need a specific instance of the class to run.
Non-static members require an instance of the class. Typically you will use this.
If we have a class Circle and it has function area(), then it would be non-static as it needs a specific circle to find the area of. Now imagine we have a PrintText class with a printBold() function. We don't need an instance since it only depends on the inputs. However it is convenient to have the PrintText class because we could have printBold(), printItalics(), etc.
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.
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.
Why should I usefunction __construct() instead of function className() in PHP 5?
The __ magic methods/functions seem to be a consistent theme in PHP (for once!). One advantage of using __construct() over ClassName() as a constructor is if you change the name of the class, you don't need to update the constructor.
Because php5 wanted to be more like python.
I kid, I kid...
Having a standard method for standard actions, like construction, is a reasonable solution. It's the same reason that in C# classes, when you extend a class, you use base for calling base class constructors instead of a named object: it simplifies code and makes maintenance easier.
Because it has been unified with the __destruct() method and other special methods beginning with two underscores for example __get, __sleep, __serialize
http://us2.php.net/manual/en/language.oop5.magic.php
My guess would be that by the time object-oriented capability was being added to PHP, the designers were looking at Python.
By doing so always, you can invoke the constructor from the super (base-)class without having to know its name. This is very useful for class tree maintenance, because you don't want to have to update all your classes just because you re-arrange your class trees
and...just guessing.. if all classes name their constructors identically __construct(), in theory a constructor could be inherited from a superclass without any required definition. This makes sense in class trees where there are intermediate abstract classes, and in constructs like in objective C where default constructor behaviour is derived entirely from class metadata and therefore (in priciple!) would need no coding at all.
Old question, but I'll bite since no one has actually answered the actual question yet.
function className() is a PHP4-style constructor.
function __construct() is a PHP5-style constructor.
You should use the latter because the former is deprecated and may be removed from the language.
Also, the former may or may not ignore various PHP5 OO concepts, such as the public/private visibility operators. Not that you'd want to make the constructor private if you weren't using the Singleton or Factory patterns.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I always thought you should never set/get a member variable directly. E.g.
$x = new TestClass();
$x->varA = "test":
echo $->varB;
I thought you should always use object methods to access member variables.
But I've just been looking at __set and __get, which imply it's ok to access members directly.
There's no right answer here.
In the beginning, direct access to member variables was considered a bad idea because you lose the ability to make that access conditional upon some set of arbitrary programming logic. That's why we have the terror of getter and setter methods.
Having magic methods like __set and __get removes this concern. You can have users of your object access member variables all you want and then if you discover you need some programatic logic around that access, you can use the magic methods.
However, particularly in PHP, __set and __get aren't free from a performance perspective. Also, remember that __set and __get are only invoked when an inaccessible (private, protected, etc.) member variable is accessed. This means there's no way to invoke __set and __get from within a class, outside of removing the member variable from the class definition, which makes your class less clear.
Like most things PHP, there's no clear "best" way to handle this.
Not only in PHP but in object oriented programming in general, if a class has member variables for which it's not necessary to execute code when they are accessed, there's no need to make setters and getters, and the variables can be accessed directly.
Accessing properties (variables) of an object is OK if those are public.
If they are protected/private (which is something new in PHP 5, that didn't exist in PHP 4), you can't access them directly.
Doing this or going through accessors depends on what you need / want to do :
if you only want to access data, you do not need accessors
if you want to perform some actions when data is accessed (check for the correctness of a value, for instance), you should use accessors -- bet it maginc method __get/__set or not.
Using those two magic methods has the advantage that it is transparent for the user ; and you can add them whenever you want, without forcing your users to rewrite their code.
But note that using getters/setters is said to have a cost (it costs some CPU, when you speak about performance, as you have to call a method)
In the end, there is no "right way", not "best way" : there are two ways, and it's up to you to choose which one fits the best for your needs.
For my own projects, here's what I generally do :
when I don't need to check anything, I don't use getters/setters
when I need some special behaviour, I declare my variables as protected/private, and create a special getter/setter (like getName/setName)
this has the advantage of having a phpdoc for each method, and hinting in the IDE I use, btw
Prior to PHP 5, you could do that. With the introduction of PHP 5, you can declare private variables. So it's not unusual to see PHP 4 codes which access variables directly because there is no rules for private variables.
I think it's ok to access class variables directly. If you want to keep other classes from modifying those variables you can make them private. If you have a public getter and setter that strictly copies the value passed to class field I think that's just overcomplicated approach.
The only situation I can think of where you would want to use getter or setter is when you have to process the value somehow.
The right thing to do from a purist OO perspective is create your own setter/getter method (ideally by overloading PHP's) that makes the relevant data available. (PHP is effectively providing you with generic versions of this with __get and __set, but these will let you get/set anything, which most likely isn't ideal.)
You should also set all of the variables (and indeed methods) within a class to have the correct visibility (private, protected, etc.) hence forcing you to use the set/get methods.
Look at the manual:
http://us2.php.net/manual/en/language.oop5.magic.php
Magic Methods
The function names __construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state and __clone are magical in PHP classes. You cannot have functions with these names in any of your classes unless you want the magic functionality associated with them.
Caution
PHP reserves all function names starting with __ as magical. It is recommended that you do not use function names with __ in PHP unless you want some documented magic functionality.
Just do good OOP ( I suggest you to declare getters and setters against accessing variables directly..) and forget about __get and __set.. If I'm not wrong there is also a __call for calling arbitrary methods.They are MAGIC methods they aren't meant for ordinary operations.
You shouldn't be using __get and __set or __call unless you are writing very particular code (es some framework, or something for proxying calls to other objects like in the php library Javabridge http://php-java-bridge.sourceforge.net/ ).