I'm a bit lost here because I want to do something that is very easy in Java but seems a bit complicated in PHP.
We are building an SDK for our product and in Java, we have this one class that must not (!) be instantiated by the user (i.e. the coder), since there are several constraints regarding it's integrity. So we've built that as a nested class "X" inside of the "XFactory" and you will get an instance of X by calling XFactory.buildMeMyX(); - Easy...
Now PHP does not support nested classes at all, and I wonder how to apply the same here. In Java, X's constructor is hidden (private), so only XFactory can call it.
In PHP, it looks like I will have to make __construct() public and move the nested class X out of XFactory. Hence, the user will be able to create an instance without the Factory.
Now - I COULD move the factory functionality to X itself and move all the stuff there, but this would kind of break the design of the SDK. Is there a useful way to do such things in PHP after all?
For PHP 5.x you already described your options, there are no private/protected classes or inner classes at all, so there is no further way to restrict instantiation.
However, with PHP 7 this is going to change.
There are still no nested classes (although we might get them in the future, see: https://stackoverflow.com/a/31454435/664108), but you could instantiate an anonymous class and only provide the consumer with its interface like this:
class XFactory
{
public function buildMeMyX()
{
return new class() implements XInterface {
public function doWhatEverAnXCanDo()
{
// X X X
}
// ...
};
}
}
interface XInterface
{
function doWhatEverAnXCanDo();
}
As the others have said, there currently is no clean way to implement this behavior in PHP. In my opinion, the only valid use case for private constructors are factories inside the class that implement that factories.
Whenever you try to get around that use case it gets messy. No one should ever try to invent clever ways to bypass PHP's language limiations.
I just violated that rule by myself just to prove it is indeed possible. But please refrain from using that in production, or better: using it anywhere. I will try to find some bulletproof arguments for that suggestion and edit the answer afterwards.
<?php
class Dependency {}
class SomeClass {
protected $dep;
private function __construct(Dependency $dep)
{
$this->dep = $dep;
}
public function doSomething()
{
var_dump($this->dep);
echo "Doing Stuff and even having dependencies";
}
}
class SomeClassFactory {
public function buildSomeClass()
{
return $this->instantiateSomeClassWith(new Dependency);
}
protected function instantiateSomeClassWith()
{
$reflectionClass = new ReflectionClass('SomeClass');
$someClass = $reflectionClass->newInstanceWithoutConstructor();
$constructor = $reflectionClass->getConstructor();
$constructorClosure = $constructor->getClosure($someClass);
call_user_func_array($constructorClosure, func_get_args());
return $someClass;
}
}
$factory = new SomeClassFactory();
$someClass = $factory->buildSomeClass();
$someClass->doSomething();
?>
Output: object(Dependency)#2 (0) { } Doing Stuff and even having dependencies
The theory is simple. The constructor of the class that will be built via the Factory is made private. We make use of reflection within the factory to create an instance of the class without invoking the constructor.
Once we have an instance, we grab the closure of the constructor and invoke it via call_user_func_array(). That way you can make use of Dependency Injection just as you would if the constructor was public.
As I said before. That way is a single smell. By creating an object without invoking it's constructor, there is no real way to validate an objects state upon creation
This is a proof of concept, but the concept sucks.
There is no native way to do so, yet. However, if you really want to "enforce" that your class is only created from your factory class, there is a little "hackish" way to do so limiting the instantiation by inistantiating class.
class X
{
function __construct()
{
new Y();
}
}
class Y
{
function __construct()
{
$trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
if (!isset($trace[1]['object']) || !($trace[1]['object'] instanceof X)) {
throw new \RuntimeException('This is a private class');
}
}
}
new X(); // All is fine
new Y(); // Exception
Please note that there is no "real" way to protect the class from being instantiated from elsewhere even using this approach - it still can be done via reflection by bypassing the constructor, or simply modifying your source.
I am confused whether to use static method or just simple method.
Lets me give an example, I am using Zend framework 1 project.
I have class like
class Example1
{
public static function getVariable() {
return is_numeric(Zend_Registry::get('config')->Variable) ? Zend_Registry::get('config')->Variable : 0;
}
public function calculateSome($param1, $param2) {
$response = array();
if($param2 == 0) {
$response = number_format(($param1 * self::getvariable()) /100);
} else {
$response = $param1;
}
return $response;
}
}
Usage :
Currently i'm getting variable value like Example1::getVariable() in whole project.
And Calculating like first instantiating a class $class1 = new Example1(); and then calling the function like $class1->calculateSome(1, 0);
I am confused whether it is good to change calculateSome() to public static and call like this Example1::calculateSome(1, 0) or left as it is.
I Have found link when to use static =>
When to use static vs instantiated classes
But I can't understand what it says.
You can find the long answer here: How Not To Kill Your Testability Using Statics
The TL;DR version of it is:
A static method is nothing more than a namespaced function, Foo::bar() does not significantly differ from foo_bar().
Whenever you call a static method, or a function for that matter, you're hardcoding a dependency. The code that reads $bar = Foo::bar(); has a hardcoded dependency to a specific Foo class. It is not possible to change what Foo refers to without changing that part of the source code.
An object is a "soft" dependency. $bar = $foo->bar(); is flexible, it allows room to change what $foo refers to. You use this with dependency injection to decouple code from other code:
function baz(Foo $foo) {
$bar = $foo->bar();
...
}
You can call Foo::bar() anytime from anywhere. If Foo::bar has some dependency it depends on, it becomes hard to guarantee that this dependency is available at the time you're calling the method. Requiring object instantiation requires the object's constructor to run, which can enforce requirements to be set up which the rest of the methods of the object can depend on.
Constructors together with dependency injecting objects into other functions are very powerful to
create seams in your codebase to make it possible to "take it apart" and put it together in flexible ways
put checks into strategic places to ensure requirements are met for certain parts of the code (at object instantiation time the constructor enforces a sane state of its little part of the world, its object), which makes it a lot easier to localise and contain failures.
Think of it like compartmentalising your app and putting firewalls between each compartment with a supervisor in charge of each one; instead of everyone just running around in the same room.
Any time you write new Class, you may as well write Class::staticMethod(), the hardcoded dependency is the same.
So the decision comes down to:
What are the requirements of this class? Does it need to ensure certain preconditions are met before any of its code can run (e.g. a database connection needs to be available), or are all methods just self-contained little helper methods?
How likely are you to maybe want to substitute this class for another class? Does this class produce side effects (e.g. writing to a file, modifying some global state) which may not always be desirable and hence a different version of it may be useful under some circumstances?
May you need more than one instance of this class at the same time, or is the nature of the class such that there are no individual instances needed?
Start using unit tests, which require you to take your app apart and test each little part individually to ensure it works, and you'll see where the advantage of object instantiation and dependency injection lie.
When the method involve instance-based properties/changes u should keep it non-static.
If its a method that is needed for the whole type then use static.
For example u can keep tracks of created instances by this snippet:
class Product {
static $count;
private $name;
public function __construct($name) {
$this->name = $name;
self::$count++;
}
public function getName() {
return $this->name;
}
public static function getCount() {
return self:$count;
}
}
$productA = new Product('A');
$productB = new Product('B');
echo $productA->getName(). ' and ' . $productB->getName(). '<br />'. PHP_EOL;
echo 'Total made products :' . Product::getCount();
With regards to using class objects within another class what is the best practice? To pass the class objects in the class _construct statement or create a new class object?
Example 1:
class Foo {
private $bar;
public function __construct($bar){
$this->bar = $bar;
}
}
Or Example 2 :
class Foo {
private $bar;
public function __construct(){
$this->bar= NEW bar;
}
}
I'm aware that obviously it's taken for granted that the class file must already be included somewhere else, and in the first instance a class object of this type would need to exist already, but I want to know what the advantages are each method are, as I have a lot of classes I need to code that use a database object and I need the best way to pass this into the classes. Is there a third option that's better than these two?
From what I can understand, the advantage of the first one could be a few less lines of coding and in the case of a DB, not having a new connection created. The second one might be better however because it's more self contained? Anyhow I thought I'd ask the experts.
The first. (This approach is called Dependency Injection).
The constructor asks for whatever the object in questions needs in order to work. This way, it's pretty clear from the methods alone (what they need, and what they return), what it does. Without even looking at the source code.
A way to improve your code would be to introduce type hinting into your method:
class Foo {
private $bar;
public function __construct(Bar $bar){
$this->bar = $bar;
}
}
So that only Bar objects may be passed in.
Advantages of Dependency Injection
Very readable.
Ability to tell the method's dependencies without viewing the source code.
Makes Unit Testing possible.
*Saves kittens from God's wrath.
* Disclaimer: No kittens were harmed during the manifestation of this answer
You should go for option 1, as this is the simplest form of dependency injection.
In option 1:
classes are independent of each other
classes can be tested independent, using a mock for the bar class
In general, I'd chime in with the DI crowd for reasons outlined in How to Think About the “new” Operator with Respect to Unit Testing:
But the reason why Dependency Injection is so important is that within unit-tests you want to test a small subset of your application. The requirement is that you can construct that small subset of the application independently of the whole system. If you mix application logic with graph construction (the new operator) unit-testing becomes impossible for anything but the leaf nodes in your application.
Separating your code into creator graphs and collaborator graphs will help to keep your code maintainable and testable. Even better, code against interfaces and it will be very easy to swap out concrete implementations against other ones. This makes changing your code simple, because you don't have to wade through your code hunting for hardcoded dependencies.
For instance, assuming your Bar requires a Logger, you'd do
class Foo
{
private $logger;
public function __construct(LogInterface $logger)
{
$this->logger = $logger;
}
}
And then you pass in any concrete implementation implementing that LogInterface, like a Database Logger or a StdOutLogger or maybe a Composite Logger holding both of these. Another example would be a Database object. You can create that once in your bootstrap and then pass it to the objects making use of it.
When in doubt, go with Dependency Injection.
However, you don't always have to inject stuff. It depends whether the object (your Bar) is an Injectable or a Newable. To quote Misko Hevery:
An Injectable class can ask for other Injectables in its constructor. […] Injectables tend to have interfaces since chances are we may have to replace them with an implementation friendly to testing. However, Injectable can never ask for a non-Injectable (Newable) in its constructor. This is because DI framework does not know how to produce a Newable. […] Some examples of Newables are: Email, MailMessage, User, CreditCard, Song. If you keep this distinctions your code will be easy to test and work with. If you break this rule your code will be hard to test.
In a nutshell, when you have something that cannot be reasonably injected, because it is based on user-supplied or runtime information, you can new it. This is especially true for Value Objects and Data Types:
class Foo
{
private $storage;
public function __construct()
{
$this->storage = new SplObjectStorage;
}
}
There is no point in injecting SplObjectStorage. It's just a data type.
Others have already answered your question - definitely go with the first approach, which uses Dependency Injection.
I just wanted to chip in with another popular alternative you may not be aware of: using a Dependency Injection Container.
A great, simple example of this is Pimple; developed by Fabien Potencier, the man behind the Symfony frameworks.
Example 3:
# In a bootstrap file...
require_once '/path/to/Pimple.php';
$container = new Pimple();
$container['bar'] = function ($c) {
return new Bar(/** If bar has dependencies, put them here **/);
};
$container['foo'] = function ($c) {
return new Foo($c['bar']);
};
# You'd still inject the service using DI, because it's not good
# practice for your objects to rely directly on the container
class Foo {
private $bar;
public function __construct($bar){
$this->bar = $bar;
}
}
# The difference would be how you call Foo...
$foo = $container['foo'];
# So now your code doesn't need to know about the dependencies, and it's easy
# to change them at any time by making a single change in your configuration
Symfony2 uses a more robust Container, which is also available as a standalone compenent. But Pimple is probably your best bet unless you're developing a large-scale application.
I'd say use the 1st option. While doing so, I'd say programming to abstractions is a better idea than programming to an implementation.
Your first option is a form of aggregation while the second is that of composition. The benefit you would get with abstractions is that your client class that uses class FOO will be able to get FOO to do some activity based on a particular implementation of the interface it decides to send into the constructor..
A C# example below
class Foo {
private IBar bar;
public Foo(IBar obj){
this.bar = obj;
}
public void myFooMethod()
{
bar.ExecuteMethod();
}
}
The class calling FOO
public class MyCallingClass
{
public void CallFooMethod()
{
IBar bar1Obj = new BAR1();
Foo fooObject = new Foo(bar1Obj);
fooObject.ExecuteMethod();
//or
IBar bar2Obj = new BAR2();
fooObject = new Foo(bar2Obj);
fooObject.ExecuteMethod();
//or
IBar bar3Obj = new BAR3();
fooObject = new Foo(bar3Obj);
fooObject.ExecuteMethod();
}
}
Now my calling class can pass any implementation of IBar to the FOO class.
Hope this helped.
Ok, Dependency Injection is wonderful, and helpful and saves kittens, so I'm not going to discuss it in detail.
Instead, I'm going to suggest you implement both solutions:
class Foo {
private $bar;
public function __construct($bar = null){
$this->bar = isset($bar) ? $bar : new Bar();
}
}
That way, you can use the default class by default, and if you need to change the functionality, you can do that too.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Could this be classified as correct OOP programming?
class Greeting {
public $greet = array('Hi','Hello', 'Howzit', 'Ola', 'Whats up');
function __construct($name) {
$this->name = $name;
shuffle($this->greet);
}
}
$hi = new Greeting('INSERTNAMEHERE'); /*NAME OF PERSON GOES HERE*/
echo $hi->greet[1] .' '. $hi->name;
For the sake of Keeping it Simple, I'd say it's okay. It's not too proper OOP though, nor is it particularly easy to understand code. Having working code is better than having no code at all though.
Let's go through your code:
1 class Greeting {
2
3 public $greet = array('Hi','Hello', 'Howzit', 'Ola', 'Whats up');
4
5 function __construct($name) {
6 $this->name = $name;
7 shuffle($this->greet);
8 }
9 }
Line 1: says this class represents the concept of a Greeting. What is a Greeting? I'd say something like "Hello John" or "Hi John" or "Howdy John" is a greeting. And in fact, you seem to agree because in …
Line 3: … you do have a list of similar greetings, just without a name. But that property warrants the question why your class is named Greeting, when it really encapsulates multiple greetings already. Shouldn't the class be called Greetings (mind the plural) then?
Line 3: Naming the property "greet" wasn't a too good idea either. It's a property, so dont give it the name of a verb. Verbs are for methods.
Line 3: Although there is people who will tell you different, making the property public is rarely a good idea. Properties are about internal state and that state should not be accessible directly, but only through methods.
Line 5: Your constructor then tells me a Greeting has to have a name. If I wouldn't be looking at the source code already, I'd falsely assume this to be the name of the Greeting. But you really mean a Person's name. The argument should reflect that and be named something more indicative, like $greetedPersonsName.
Line 6: Assigning properties on the fly is a boo boo. If I look at the class definition, I want to see the properties immediately. Discovering them inside some method makes the code hard to understand. This will also not getting picked up when generating API docs. Avoid it.
Line 7: The shuffle is another unexpected thing. It's a non-obvious side-effect. If I was to instantiate a new Greeting, I'd expect the greetings to appear in the order they are listed. It's against the Principle of Least Astonishement to shuffle them in the ctor. The shuffling should happen from a public method that does nothing but shuffling, e.g.
public function shuffleGreetings()
{
shuffle($this->greetings);
}
Assuming the idea of the class was really to be a single Greeting that just initializes itself with one of the default possible values, we can also add a Getter like this:
public function getGreeting()
{
return $this->_greetings[0] . ' ' . $this->name;
}
This is better than doing
echo $hi->greet[1] .' '. $hi->name;
because it hides the implementation details. I don't need to know that the Greeting object has an array of possible greetings. I just want to get the Greeting combined with the set name. It's still far from perfect though, because you still would use it like
$hi = new Greeting('John'); // A Greeting named John? Why $hi then?
$hi->shuffleGreetings(); // Shuffling Greetings in a Greeting?
echo $hi->getGreeting(); // Why is it "Hello John" all of a sudden?
As you can see, the API is still pretty much full of WTF. A developer will still have to look at your source code to understand what's going on.
More on Side-Effects
While it may be tempting to put the shuffle into getGreeting you should not do so. A method should return the same thing for the same input. When I call getGreeting twice in a row, I can expect it to return the same result. You would expect 1+1 to return 2 always, so make sure your methods do too.
Likewise, if you want to have a single method to return a random item from the greetings property, dont shuffle the greetings array. If you would use the shuffle method instead, you would also change the greetings property. That ripples to any function reading from the property, e.g. when you do
public function getRandomGreeting()
{
$this->shuffleGreetings();
return $this->getGreeting();
}
a developer will experience something like this:
$hi = new Greeting('John');
$hi->shuffleGreetings();
echo $hi->getGreeting(); // for example "Hello John"
echo $hi->getRandomGreeting(); // for example "Hi John"
echo $hi->getGreeting(); // for example "Howdy John" <-- WTF!!
Use an implementation that doesnt change the property, e.g.
public function getRandomGreeting()
{
$randomKey = array_rand($this->greetings);
return $this->greetings[$randomKey] . ' ' . $this->name;
}
That is free of side-effects:
$hi = new Greeting('John');
$hi->shuffleGreetings();
echo $hi->getGreeting(); // for example "Hello John"
echo $hi->getRandomGreeting(); // for example "Hi John"
echo $hi->getGreeting(); // still "Hello John". Expected!
The API is still far from pretty though. If I think about the properties of a Greeting, I just dont think "Person's name". Just saying "Hi" oder "Hello" is still a valid greeting. It doesn't require a name. How about
public function greetPerson($personName)
{
return $this->getGreeting() . ' ' . $personName;
}
and then we can do
$hi = new Greeting;
$hi->shuffleGreetings();
echo $hi->greetPerson('John');
And to finally hide that our Greeting contains an array that needs to be shuffled, let's move our shuffleGreetings method back to the ctor and rename the class to RandomGreeting.
class RandomGreeting …
public function __construct()
{
$this->shuffleGreetings();
}
This might seem counterintuitive at first, because I told you not to shuffle in the ctor. But with the class renamed to RandomGreeting, it is much more to be expected that there is something happening behind the scenes. We just don't need to know what exactly. To reflect that, we should also make the shuffleGreetings method protected now. We just hide it from the public interface completely. Now our code reads like this:
$hi = new RandomGreeting;
echo $hi->greetPerson('John'); // ex "Howdy John"
This doesn't give you any WTFs because your code clearly communicates you'll get a random greeting. The classname clearly communicates what it does.
This is a little bet better now and we could end here, but one could still argue that a Greeting should not be able to greet on it's own, but is rather something that is done by a Person instead.
Improving it
Our findings should lead us to the conclusion that a Greeting should rather be a dumb Type encapsulating the Greeting message and nothing else. All it should do is return that message. Since the Greeting doesn't have any real behavior next to storing the message string, the easiest would be to create a Value Object, e.g. an object that is equal to another object by value of a property:
class Greeting
{
protected $value;
public function __construct($value)
{
$this->value = $value;
}
public function getValue()
{
return $this->value;
}
}
The other way to do it would be to make the various available greetings into separate types. There is very little gain to do that when your objects don't have behavior. You only need that if you want to take advantage of Polymorphism. However, having concrete subtypes does draw a few additional things to consider later on, so let's just assume we need it.
The proper way to do that in OOP would be to define an interface
interface Greeting
{
public function getGreeting();
}
that defines a class that wants to behave like a Greeting has to have a getGreeting method. Since interfaces dont implement any logic, we also add an abstract type that contains the greeting property and the logic to return it:
abstract class GreetingType implements Greeting
{
protected $greeting;
public function getGreeting()
{
return $this->greeting;
}
}
When there is an abstract class, there also needs to be concrete classes derived from the abstract class. So let's use Inheritance to define our concrete Greeting types:
class HiGreeting extends GreetingType
{
protected $greeting = 'Hi';
}
class HelloGreeting extends GreetingType
{
protected $greeting = 'Hello';
}
class HowdyGreeting extends GreetingType
{
protected $greeting = 'Howdy';
}
It's not absolutely necessary to have an Interface and an Abstract implementing the interface. We could have made our concrete Greetings not extend from the GreetingType. But if we had just reimplemented the getGreeting method on all the various Greeting classes, we would be duplicating code and were much more prone to introducing errors and should we ever need to change something, we'd have to touch all these classes. With the GreetingType it's all centralized.
The other way round is true as well. You dont necessarily need an interface. We could have used just the abstract type. But then we would be limited to the GreetingType whereas with an interface, we could potentially add new Types with much more ease. I admit I can't think of any right now, so it is probably YAGNI. But it's so little to add that we can just as well keep it now.
We will also add a Null Object that returns an empty string. More on that later.
class NullGreeting extends GreetingType
{
protected $greeting = '';
}
Object creation
Because I do not want to litter new classname all over my consuming classes and introduce coupling, I will a use simple Factory instead to capsule object creation:
class GreetingFactory
{
public function createGreeting($typeName = NULL)
{
switch(strtolower($typeName)) {
case 'hi': return new HiGreeting;
case 'howdy': return new HowdyGreeting;
case 'hello': return new HelloGreeting;
default: return new NullGreeting;
}
}
}
The Factory is one of the few pieces of code where you actually can use a swich/case without having to check if you can Replace Conditional with Polymorphism.
Responsibility
With object creation out of the way, we can finally start to add our Greetings class:
class Greetings
{
protected $greetings;
protected $nullGreeting;
public function __construct(NullGreeting $nullGreeting)
{
$this->greetings = new ArrayObject;
$this->nullGreeting = $nullGreeting;
}
public function addGreeting(Greeting $greetingToAdd)
{
$this->greetings->append($greetingToAdd);
}
public function getRandomGreeting()
{
if ($this->hasGreetings()) {
return $this->_getRandomGreeting();
} else {
return $this->nullGreeting;
}
}
public function hasGreetings()
{
return count($this->greetings);
}
protected function _getRandomGreeting()
{
return $this->greetings->offsetGet(
rand(0, $this->greetings->count() - 1)
);
}
}
As you can see, Greetings is really just a wrapper for an ArrayObject. It makes sure that we cannot add anything else but objects implementing the Greeting interface to the collection. And it also allows us to pick a random Greeting from the collection. It also makes sure that you always get a Greeting from the call to getRandomGreeting by returning the NullGreeting. This is awesome, because without that you would have to do
$greeting = $greetings->getRandomGreeting();
if(NULL !== $greeting) {
echo $greeting->getMessage();
}
in order to avoid a "Fatal Error: Trying to call method on non-object" when the getRandomGreeting method did not return a Greeting object (when there is no Greeting in the Greetings class yet).
The class has no other responsibility than that. If you are unsure if your class is doing too much or has methods that should better be on some other object, look at the methods in that class. Do they work with a property of that class? If not, you should probably move that method.
Getting it done
Now to finally put all that code to use, we add our Person class now. Since we want to make sure we can call a getName method on it, we create an interface before doing so
interface Named
{
public function getName();
}
We could have named that interface IPerson or whatever but it only has one method getName and the most fitting name is Named then, because any class implementing that interface is a named thing, including, but not limited to our Person class:
class Person implements Named
{
protected $name;
protected $greeting;
public function __construct($name, Greeting $greeting)
{
$this->name = $name;
$this->greeting = $greeting;
}
public function getName()
{
return $this->name;
}
public function greet(Named $greetable)
{
return trim(sprintf(
'%s %s',
$this->greeting->getGreeting(),
$greetable->getName()
));
}
}
Our Person has a required name and we demand it to have a Greeting as well. All it can do besides returning it's name is greet another Named thing, likely another person. And that's it.
To put that all together now:
$greetings->addGreeting($greetingsFactory->createGreeting('Hi'));
$greetings->addGreeting($greetingsFactory->createGreeting('Howdy'));
$greetings->addGreeting($greetingsFactory->createGreeting('Hello'));
$john = new Person('John Doe', $greetings->getRandomGreeting());
$jane = new Person('Jane Doe', $greetings->getRandomGreeting());
echo $john->greet($jane),
PHP_EOL,
$jane->greet($john);
Live Demo on Codepad
Granted that's quite a lot of code for a very simple thing to do. Some will call it overengineered. But you asked for correct OOP and while I am sure there is still room for improvement, it's quite proper and SOLID in my book. And it's easy to maintain now, because the responsibilities are closer to where they should be.
Hmm, two things:
shuffling that array and accessing it from the outside, and having the outside call rely on the array being shuffled, doesn't feel right. It would be nicer to have a method that returns the result of an array shuffling, and maybe also the name straight away.
It would be good style to declare all object properties beforehand so it can be documented later. So if you use $this->name, you should declare it.
Both points implemented could look like this:
class greeting
{
protected $greet = array('Hi','Hello', 'Howzit', 'Ola', 'Whats up');
protected $name = null;
public function __construct($name)
{
$this->name = $name;
}
public function greet()
{
shuffle($this->greet);
return $this->greet[1]." ".$this->name;
}
}
from a beginners point of view it would be yes, but as this is a single object it cannot be orientated like you could with several objects.
True OOP is when you separate the individual entities of your application into objects / dependencies.
for example, a simple website would include the following:
Database
Error Handling
Sessions
Security
these are called entities and should not interact directly with each other, that's why there separate.
so if we wanted to interact Sessions and Security to make shore that the session is safe, we would add a method to the session object to return a PHP standard result such as array or string, this way many objects can interact with each other without relying on the actual object too much.
Looking at your attempt at a greeting class I would look at something like so:
class User
{
protected $data;
public function __construct(array $user_data)
{
$this->data = $user_data;
}
public function getUsername()
{
return $this->data['username'];
}
}
class Greeting
{
private $message = "welcome to mysite %s";
public function __construct(string $to_greet)
{
$this->message = sprintf($this->message,$to_greet);
}
public function getGreeting()
{
return $this->message;
}
}
the following would be used like so:
$User = new User(array(
'id' => 22,
'username' => 'Robert Pitt'
));
$Greeting = new Greeting($User->getUsername());
echo $Greeting->getGreeting();
now i have mentioned that objects do interact directly with each other but if they do that they should be encapsulated so that all the database objects such as Database,Result,DB_Error would only interact with each other.
this allows for code to be transportable to other projects without having to much of an issue, also known as libraries.
if the objects are closley related ina way that there all bundled together you could do something like this:
$User = new User(/*..From DB ..*/);
$Greeting = new Greeting($User);
echo $Greeting->getGreeting();
It would probably be better to have a greet method. The idea is that the user doesn't need to know that $this->greet is an array.
So:
class Greeting {
protected $greet = array('Hi','Hello', 'Howzit', 'Ola', 'Whats up');
protected $name='You';
function __construct($name) {
$this->name = $name;
}
function greet(){
shuffle($this->greet);
echo "{$this->greet[0]} {$this->name}!";
}
}
$hi = new Greeting('INSERTNAMEHERE');/*NAME OF PERSON GOES HERE*/
$hi->greet();
I have to disagree with [Edit: Some of] the other answers you've gotten. Making greet private and adding a getter does little to increase encapsulation.
Regardless of that, however, I think it's pretty poor OO design. An object should represent some thing (dare I say, some actual obect?) IMO, the "objects" here would really be the people (or whatever), one of whom is greeting the other. The greeting itself should be a message passed from one of those objects to the other. We might write a "greeting" class to hold the text of the greeting, but even if we do the greeting object itself should be independent of the source or target of the greeting.
It's a bit off the mark, actually. First of all, public variables are generally bad. You shouldn't be accessing class's variables directly from the code. You should try to encapsulate functionality provided by the class into the class itself.
First, let me show you how a good kind of OOP code could look like based on your example:
<?php
class greeting
{
private static $greets = array('Hi','Hello', 'Howzit', 'Ola', 'Whats up');
private $name;
function __construct ($name)
{
$this->name = $name;
}
function doGreeting ()
{
$i = array_rand(self::$greets);
return self::$greets[$i] . ' ' . $this->name;
}
}
$hi = new greeting('INSERTNAMEHERE');/*NAME OF PERSON GOES HERE*/
echo $hi->doGreeting();
Now, let's talk about the differences here.
First, the greets are stored in a static variable. Since these texts probably do not vary instance by instance, it's simply more efficient to store them in a static variable that is shared by the entire class, so every instance do not have their own copy of the array. You will also notice that it's private. This is encapsulation. The code outside does not need to know about the inner workings of the class, like the variable names. Outside code does not need to know about the array, since it should only be used within the class itself.
Another minor detail, is that the name is also declared there as private, since all class variables should be private in general for encapsulation. If they need to be accessed, that should be done via setter and getter functions, which can provide additional validation for values, if needed.
The code flow is also a bit different. Instead of using the class variables directly from the outside code, we get the class itself to produce the greeting and return it as a string. This way, the outside code does not need to know how the greeting texts are produced or where the name is stored. It jsut needs to know the API, i.e. the functions, their parameters and return values. How they actually work should be left for the class itself.
Additionally, since this is obviously functionality that is intended for the greeting class, it makes the code more reusable as the functionality is coded into the class. Part of the point of OOP is to create good reusable code that can be used where it is needed. When the class functionality is in the class itself, the same code does not needed to be coded elsewhere.
Remember encapsulation and reusability. These are two important points of OOP.
One of the basic ideas behind OOP is that you have objects that have responsibility over certain data structures in your code. what you have written above is really just a data structure, not really a full on object, it holds the data for the greeting, but doesn't really have responsibility over handling it and providing it for other objects.
A "better" object would look something like this:
class greeting {
protected $greet = array('Hi','Hello', 'Howzit', 'Ola', 'Whats up');
protected $name;
function __construct($name) {
$this->name = $name;
}
public function greet() {
return $this->greet[rand(0,5)] . ' ' . $this->name;
}
}
$hi = new greeting('INSERTNAMEHERE');/*NAME OF PERSON GOES HERE*/
echo $hi->greet();
Now your greet object is in total control of the greeting and your application code doesn't have to care about how that object is set up, it just has to care about the few functions it can use to get the greeting. If you wanted to eventually internationalize or change the greeting in some way, all you'd need to do is change that one object to do it.
Also, just to note, using objects does not make your code OOP. It needs to be object oriented, which means using objects to define discrete tasks that your application will need to perform and not making every other piece of the application have total access to all of it's data to do with what it will. Then, you're just building data structures.
its is not completely correct OOP because the $greet variable is not encapsulated.
to make it 'more correct' (whatever that means), you would have to make the $greet param private and create some get and set methods for it (same goes for the $name variable -- which also should be declared before it is used).
in php a get method is like so:
if i want to get the var:
$hi = new greeting('INSERTNAMEHERE');/*NAME OF PERSON GOES HERE*/
echo $hi->__get('greet') .' '. $hi->__get('name');
the get is created inside the greeting class:
function __get($var){
return $this->$var;
}
and set is the same:
function __set($var, $val){
$this->$var = $val;
}
I would probably use getters/setters for $greet, instead of making it public. I don't see why it wouldn't be considered OOP though.
http://en.wikipedia.org/wiki/Object-oriented_programming
For dependency injection, I understand that I have to pass an instance of one class to the main instance instead of the main class creating it's own instance, like so (php):
class Class_One {
protected $_other;
public function setOtherClass( An_Interface $other_class ) {
$this->_other_class = $other_class;
}
public function doWhateverYouHaveToDoWithTheOtherClass() {
$this->_other_class->doYourThing();
}
}
interface An_Interface {
public function doYourThing();
}
class Class_Two implements An_Interface {
public function doYourThing() { }
}
class Class_Three implements An_Interface {
public function doYourThing() { }
}
// Implementation:
$class_one = new Class_One();
$class_two = new Class_Two();
$class_three = new Class_Three();
$class_one->setOtherClass( $class_two );
$class_one->doWhateverYouHaveToDoWithTheOtherClass();
$class_one->setOtherClass( $class_three );
$class_one->doWhateverYouHaveToDoWithTheOtherClass();
This is all fine. I know that since both Class_Two and Class_Three both implement An_Interface, they can be used interchangeably in Class_One. Class_One wouldn't know the difference between them.
My question is, is it ever a good idea to, instead of passing an instance to setOtherClass, pass a string such as "Class_Two", and have Class_One's setOtherClass method actually create the instance itself like so:
class Class_One {
...
public function setOtherClass( $other_class_name ) {
$this->_other_class = new $other_class_name();
}
...
}
Does this sort of defeat the purpose of Dependency Injection, or is this completely valid? I thought this type of set up may help me with configuration, where a user can specify which class he wants to use in a string earlier on and this can later be passed to the Class_One..
Actually, writing this out has made me think that it's probably not a good solution, but I'll still post this in case someone can give me some good feedback on why I should/shouldn't do this.
Thanks =)
Ryan
That theoretically defeats the purpose of dependency injection; you are telling Class_One, which depends on An_Interface, which concrete implementation of that interface it should instantiate. That requires Class_One to know how to instantiate ANY An_Interface implementation, tightly coupling Class_One to ALL An_Interface implementations. If you add a new An_Interface Class_Four, you have to go back and tell Class_One how to instantiate a Class_Four.
In PHP, you get away with this AS LONG AS all An_Interface implementations have a parameterless constructor. However, if any implementation needs OTHER dependencies injected, you're screwed; you can't tell Class_One to just new up a Class_Four if a Class_Four needs a Class_Five that Class_One doesn't know about.
Pass an object that's specified by an interface. Otherwise how will you always know with 100% accuracy what it will take to construct the object?
public function __construct(MyInterface $object) {
}
That way, it doesn't matter how you create the object, you just need to know if you can use it how you need to (the interface you're programming against)...
Either way is technically equivalent IMO. The main test to tell if you are doing dependency injection right is to see if you are using any constant strings with "new" or with static method calls. Your code looks good, as long as in the implementation section, the classes can be changed via configuration or some other mechanism. The only downside with passing a string name of a class is that you can't be sure that it implements an specific interface or extends some other object. The checking for this could get messy. However, if your application can handle this issue gracefully, then you should be alright. Passing an actual instantiated object though is the best technique.