I what cases do I declare static methods/variables in PHP? - php

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.

Related

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.

I have a class with 14 static methods and 4 static properties - is that bad?

I have been writing a PHP class that is exactly 450 lines long and it contains 14 static methods and 4 static properties as well as 6 constants (and private __construct() and __clone()).
I am wondering here is that am I doing something wrong, is my class evil?
When you use the class, you always call a single method like:
MyClass::coolMethod();
and then you leave it alone altogether so it feels that it would be stupid to make it constructable?
There's really not much point in constructing objects out of it, because it is more like a tool that contains a few methods that you can just call directly.
Actually, out of those 14 methods, 7 of them are public -- the rest are private for the class to use.
You should avoid static as much as global.
Statics give you the same disadvantages globals give you. Whenever you are using any class methods, you are hardcoding a dependency on that class into the consuming code. The result is less maintainable tightly coupled code. This can easily be avoided by avoiding statics altogether and a disciplined use of Dependency Injection.
You cannot inject and pass around static classes, so for instance when you have to unit-test them, you cannot mock them (or at least only with some effort). It's just plain painful. Static methods are death to testability.
Also, keep in mind that classes should do only one thing. They should have a single responsibility. Go through your class to see if there is stuff in there that's better placed somewhere else to avoid writing a God Class.
It depends on the purpose of this class. If the methods are mostly incoherent in terms of data, this is a perfectly valid solution of grouping functions (now methods). This is a very bad idea if you need to share values between functions, since that would be more than a simple list of functions, grouped under a common name. Namespaces are another option, but if you're using a PHP-version lower than 5.3, this is probably the best solution.
This is like saying, "I have a house with four bedrooms. Is that bad?"
Static methods are neither good nor bad. Having fourteen methods is neither good nor bad. Having fourteen static methods is, by extension, neither good nor bad.
If in your fourteen methods you're going to great lengths to simulate object instances, or to simulate inheritance, then something has gone horribly wrong. PHP will let you create instances, and supports inheritance, so it would be silly to try to simulate them any other way.
But if you're just using your class essentially like a namespace, where the functions and data all work together but there are no individual instances of the class to contend with, there's absolutely nothing wrong with that.
Not bad. However, with all those static props, you might want to consider making this a singleton.
Here is some singleton code I am using in the framework I am building. You can tear it apart and make it the sole public method for your class that returns the one version of itself.
class ClassName {
function getInstance()
{
static $instance;
if (!isset($instance))
{
$instance = new ClassName();
}
return $instance;
}
}
You would use this, then, by doing ClassName::GetInstance()->othermethod();
The class can then have tons of private values and otherwise gain all the nice things you have with an object.
I would say that no, it isn't bad. In fact that was the only way to fake certain behavior before. It was for instance a way to fake namespaces. One could encapsulate functions in static classes instead of having them "out in the free". So allot of php developers are familiar with this and it won't actually confuse most people. What you SHOULD try to do nowadays though is to make use of PHP's "new" namespace feature and if needed combine it with a singleton pattern if you actually need to store data in an object format. You could just as well have a "global" variable contained in your namespace and that could work fine at times to. But take a look at namespaces and see if that fits you in any way and after that see if singleton pattern might match your specific needs.

how to make functions global?

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.

OO PHP direct member access [closed]

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/ ).

correct use of 'construct' when designing classes

I am new to object oriented programming and writing some of my first classes for a PHP application.
In some of the simpler classes, I declare a function __construct(), and inside of that function, call certain class methods. In some cases, I find myself instantiating the class in my app, and not needing to do anything with the resultant object because the class's __construct() called the methods, which did their job, leaving me nothing left to do with the class.
This just doesn't feel right to me. Seems goofy that I have a new object that I never do anything with.
Again, I'll stress this is only the case for some of my more simple classes. In the more complicated ones, I do use class methods via the object and outside of __construct().
Do I need to rethink the way I coding things, or am I ok?
Well, the constructor is used to create a new instance of a class, and to do any necessary setup on that class. If you're just creating the class and leaving it, that does seem a bit of a waste. Why not, for instance, use static functions in the class as an organizational tool and just call them(or a function that calls them) instead of constructing a new instance that you'll never use?
This just doesn't feel right to me. Seems goofy that I have a new object that I never do anything with.
Yes, that should raise a red flag.
In general, you should not let constructors have any side effects; They are meant for initialising the state of the object - not for anything else. There are of course exceptions to this rule, but in general it's a good guide line. You should also abstain from doing any heavy calculations in the constructor. Move that to a method instead.
Side effects are many things - Changes to global variables or static (class) variables; output to the environment (For example calls to print(), header() or exit()); calls to a database or other external service and even changes to the state of other objects.
A side effect free function is also called a "pure" function - as opposed to a procedure, which is a function that has side effects. It's a good practise to explicitly separate pure functions from procedures (and perhaps even label them as such).

Categories