A few PHP questions (echo / OO PHP) [closed] - php

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 7 years ago.
Improve this question
I learning a bit of OO PHP but the docs I came across showed a couple of methods of the following examples. I am confused as to why both work, and which should be used exclusively.
I know that #1 is not OOP but I was still curious about the second method of echo, and if it should be used or not.
Both of the echo's below print "Lansana", but one initializes $name before the echo whereas the other initializes it after (or during) the echo.
<?php
$name = "Lansana";
echo $name;
echo $name = "Lansana";
?>
Notice how there is a public property $name with no value in the first example, and no public property in the second, yet both still work the same.
class Pets
{
public $name;
public function __construct($name) {
$this->name = $name;
}
}
$dog = new Pets("Buddy");
echo $dog->name;
class Pets
{
public function __construct($name) {
$this->name = $name;
}
}
$dog = new Pets("Buddy");
echo $dog->name;
What is the preferred method in #1 and #2, and why? I don't know why the docs showed the first class method because I don't see the need for a public property there, but then again what do I know.

Thought I should give a little more context to what I outlined in the comments above.
For the First example try not to mix assignment and output in the same statement. Although it is syntactically correct it doesn't immediately indicate the intent of the statement.
For the second example as I stated in the comments explicitly defining properties is always preferable. The advantages are:
Most IDE's will auto-complete defined properties for you minimizing the risk of mistyping a property.
It clearly indicates to someone reading the code what properties are available on the object.
It allows for you to set the visibility of the property so you can control more how your class is used which promotes encapsulation.
One of the most common bugs that you see with OO PHP is when you silently create a property for example something like:
class A {
public function setUserId($id){
$this->userId = $id;
}
public function getUserId(){
return $this->userid;
}
}
The intent is clear here but you have to be paying pretty close attention to the fact that the referenced properties are cased differently. If becomes much harder if you throw in another 50 lines of code and the two property references aren't on the screen at the same time.
On of the uses for PHP's magic __get and __set method are to help eliminate this problem earlier in development. Example:
class A {
public $foo;
public $bar;
public function __set($prop, $val){
throw new Exception ($prop." does not exist on this object");
}
public function __get($prop){
throw new Exception ($prop." does not exist on this object");
}
}
This makes it where if you attempt to access an undefined property the class will throw an exception letting you know exactly what happened and where.

I think #1 is just a shortcut. #2 is because of overloading, where class variables are created dynamically.
http://www.php.net/manual/en/language.oop5.overloading.php
As for preferred methods, with #1 'echo $name = 'Something'` more of a short cut than a different method. The end outcome is the same in either case.
With #2, dynamically created variables are not usually a good idea as it can generate some unexpected results but they do have their place. Check the link above for some example of code using overloading. The first method is favored.

1
echo $name = "Lansana";
PHP interprets it as
echo ($name = "Lansana");
echo sort of works like a function, because of that php interprets everything on the right side of the echo before sending it to standard out.
2
The first one is definitely the best way. Because PHP is a dynamic language (as opposed to a static language like C# or Java) it allows one to create and set variables without declaring them first. It is the best to always declare class variables--it makes the code easier to read and maintain.

Related

Should Class Properties be Stored as Variables or in an Array [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 8 years ago.
Improve this question
I've been using php for a while now, and I always wondered which is the best way to store properties in a class.
The first method is to store the data as properties.
class Foo{
private $id;
private $name;
function __get($var){
return $this->$var;
}
}
The other method is to store the data in one array, and then use magic methods to retrieve it as a regular variable in the class.
class Bar{
private $data;
function __get($var){
return $this->data[$var];
}
}
Since both methods will achieve the same goal, which one is better, and why?
It all depends on what you are trying to acchieve. Storing all properties in an (associative) array will make life easier for you if you wish to implement any of the Traversable interfaces, though there are ways to do this, too, with predefined properties.
If by best, you mean fastest: defining each property beforehand will make your classes more performant as I explained here already
There are, of course, a lot more reasons why the first approach is the better one I've listed them here
Basically, what you need to know is that PHP's "overloading" of objects is slow (O(1) for declared properties vs O(n) for overloaded properties). The same goes for magic methods, like __get and __set. They're slow. Consider this:
class Declared
{
private $foo = 123;
public function setFoo($val)
{
$this->foo = (int) $val;
return $this;
}
public function getFoo()
{
return $this->foo;
}
public function __get($name)
{
$name = 'get'.ucfirst($name);
if (method_exists($this, $name))
{
return $this->{$name}():
}
//return null or throw exception
throw new RuntimeExcpetion('attempted to access non-existing property using '.$name.' in '.__METHOD__);
}
public function __set($name, $val)
{
$mname = 'set'.ucfirst($name);
if (method_exists($this, $mname))
{
return $this->{$mname}($val):
}
throw new RuntimeException($name.' is an invalid property name');
}
}
Not only can I be certain that, at no point, new properties will be added, but because I'm using custom getters and setters, I can also ensure that the type of each property is what I want/expect it to be. In this example, I need $foo to be an integer, so in the setter, I cast whatever value that is being passed as an argument to an int. You can do that in a magic __set method, too, but the more properties you're dealing with the messier that method will become (tons of if's and else's).
Compare this, now, to this class:
class NotDeclared
{
private $data = array('foo' => 123);
public function __get($name)
{
return isset($this->data[$name]) ? $this->data[$name] : null;
}
public function __set($name, $value)
{
$this->[$data] = $value;
}
}
Now, this class does look a lot shorter, so I can see why this would appeal to anyone. Yet, let's compare both in terms of usage:
$declared = new Declared;
$notDeclared = new NotDeclared;
echo $declared->foo;//ok
echo $declared->getFoo();//ok
echo $notDeclared->foo;//ok
$declared->foo = 34;//fine
$declared->setFoo($declared->foo*2);//just fine
echo $declared->fo;//TYPO => exception
echo $notDeclared->fo;//no errors show, but echoes nothing: invisible bug?
//Worse, still: 2 mistakes in one go
$notDeclared->fo = 'Typo, meant foo, but assign string to expected integer property';
$declared->fo = 'asd';//throws excpetion at once
//singe $notDeclared->fo didn't throw excpetions, I'm assuming I reassigned $foo, yet
echo $notDeclared->foo;//ecoes old value
Because I'm restricting the usage of __set, by throwing excpetions when the user attempts to assign non-existing properties, any typo will throw an excpetion immediatly. If you don't do so, you might end up having to back-track an instance of your object, in order to spot a single, silly typo, like the example I have shown here with fo
What's more: You have to think about when the magic methods are called:
$instance->newProperty;
What is going on behind the scenes?
check object instance for a public property called newProperty
check object for method called newProperty (syntax error)
check object for __get method
invoke __get method
lookup data property ($this->data)
check array for newProperty key (isset)
return result of ternary (ie null)
This means that $instance->newProperty requires PHP to lookup newPropery, then the __get method, then the $data property, then lookup the newPropery key in that array, and then return null, or the value. that's a lot of searching on one object.
That's why I'll always recommend the first option.
This is more an OO paradigm question.
Magic get function is used more as a lazy way to write a getter. So you don't have to write a getter for each of your members.
The alternative would be to write a getter, like get_name(), get_id() for each function.
The second method isn't really comparable because all you have done is put all your members into an array. This is no doubt slower because at some level php has to iterate over your structure to find the appropriate key when you call $this->data[$var]
In summary. The top method is better as it more properly models what you class is supposed to represent. The second forfeits the point of classes, why have a class at all if your only member is an associative array?

Should I or should I not use getter and setter methods? [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 9 years ago.
Improve this question
Okay, this is really bugging me and I'm starting to think it all comes down to personal choice rather than a particular way of being more efficient or writing better code: Should I or should I not use getter/setter methods within a PHP project? The answers so far that I've read are rather conflicting and not entirely suited towards PHP, which is not a compiled language. For example, take this question on Stack Overflow ("Why use getters and setters?"). There's a number of good reasons presented as to why I should use them within my code, yet all the child comments mention how Accessors are evil and should be avoided, interspersed between a few more disturbing comments which mention that they should be avoided entirely because it "mucks up your code".
All I'm getting is conflicting answers, none of which are relevant to a interpreted PHP environment. Can someone shine some light on why/why not they should be used within PHP, and their rationale behind that decision? Does it really matter if we can simply define a property as private or protected and, anyway:
The encapsulation getters and setters offer are laughably thin
... quoted from "sbi" (Why use getters and setters?)
Personally, I still don't see how:
Class Foo {
public $bar;
function setBarType($val) {
$this->bar = $val;
}
}
$fee = new Foo();
$fee->setBarType(42);
is superior to this:
Class Foo {
public $bar;
}
$fee = new Foo();
$fee->bar = 42;
The blog post you linked to starts with a crucial sentence (emphasis added) :
Every getter and setter in your code represents a failure to encapsulate and creates unnecessary coupling.
Encapsulation is the most important idea of Object Oriented Programming. It essentially boils down to hiding complexity by wrapping it neatly inside classes. In an ideal world, when you use a class, you shouldn't have to know anything whatsoever about its inner workings or its state. Some people (like this blog author) will argue that having getters and setters is already way too much information about the insides of the class. In their view, a class should only have methods that enable us to tell an object to do something, never mind how it does it or what state it is in. Using a setter is not "telling the object to do something", it is mucking with the object's state from outside.
Instead of doing this :
$a = myObject();
// Querying object state, making a decision outside the object, and changing its state
if ($a->getWarbleFizz() < 42) {
$a->setYourWarbleFizzTo(42);
}
// Gee, I hope I made the right decision...
$a->nowDoSomethingUseful();
You should be writing code like this :
$a = myObject(42);
$a->doStuff();
Or this :
$a = myObject();
$a->doStuff(42);
Related reading : Tell, don't ask.
Because if the implementation of how the value is set changes (to a db), you don't have to change the callers. Another example is that you may need to do some checking on the value before setting it.
Having a method lets you intercept the setting/getting of that variable, doing it when it doesn't seem like you need it makes your code more change friendly.
Property getters
Languages like C# and recent versions of JavaScript allow you to intercept property reading and writing, so you can just use properties in languages that support it.
Object watchers
Some languages allow you to intercept the reading/setting of all JavaScript's Object.watch, or inaccessible properties with PHP's __get. This allows you to implements getters and setters but you get a performance hit because of the overhead they create for every property access. This answer talks about other problems with getters and setters. Best practice: PHP Magic Methods __set and __get
Getters and Setters are OK, but...
Just making boilerplate getters and setters is better, but is almost as bad as public properties. If anybody can change your object's state (specially with multiple properties), it won't be well encapsulated. http://cspray.github.io/2012/05/13/stop-calling-them-getters-setters.html
A great profit of using a getter and setter is, whenever you need to make changes you only have to modify the getter and setter.
I'll try to explain with an example:
protected $date;
public function getDate(){
return $this->date;
}
public function setDate($date){
$this->date = $date;
}
Imagine there is a reason the date should always be incremented with one day. You will have to search in your entire project where you accessed your class member.
But by using getters and setters you could change the code to:
protected $date;
public function getDate(){
return $this->date;
}
public function setDate($date){
$date = new DateTime($date);
$date->modify('+1 day');
$this->date = $date;
}
One OOP principe is encapsulation. A class is responsible to all variables that are contained inside this class.
By setting a public variable, you are breaking that principe.
By creating an accessor (setter), you're indirectly breaking that principe by giving a chance for that value to be changed outside of the class.
The advantage of a getter is that the calling method don't need to care about how the data is retrieved. It only know that it will get the expected data and that's all. Here the encapsulation principe is respected.
The advantage of a setter is that the class have the chance to check the new value before applying it. In a perfect world, there is no need for accessors because a class can fully manage all his variables. In the real world, sometimes you need to set a value or get it from the outside.
The best way to approach the perfect world is to limit accesors only to the very few variables that have to be modified. And check setted values if possible.
About your example, the second solution is better because you save one level in the php stack. Your accessor is useless because you variable is public anyway (so, no encapsulation) and don't perform any additionnal check. But when possible, you SHOULD use accessor to check the data. If the data isn't needed anywhere else in your application, then, don't do any accessor.
If you don't use getters and setters in a language like PHP, which is not type safe, then how are you going to ensure the type of the object's property is correct?
I may be missing the point completely, but if you need access to a property from outside of the object, I think it's still the best option to use accessors...
Also, as Juon Mendes mentions: some languages offer you to intercept when the properties themselves are being addressed. This may also be coming to PHP
You could even have a public setter, and a protected getter:
class TimePeriod {
protected $Seconds = 3600;
public $Hours {
get { return $this->Seconds / 3600; }
set { $this->Seconds = $value * 3600; }
}
// This property is read only as there is no setter
public $Minutes {
get { return $this->Seconds / 60; }
}
/* public getter, protected setter */
public $Milliseconds {
get { return $this->Seconds * 1000; }
protected set { $this->Seconds = $value / 1000; }
}
}
The choice is up to you. Other important features of PHP 5 to consider are magic getter/setters:
http://www.php.net/manual/en/language.oop5.overloading.php#object.set
http://www.php.net/manual/en/language.oop5.overloading.php#object.get
The magic of this is that you are able to do something like the following and decide where to get/set variables without having to declare them beforehand:
Class Foo {
private $data = array();
function __set($name,$val) {
$this->$data[$name] = $val;
}
function __get($name) {
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
else {
return null;
}
}
Voila, something like this now happens automagically:
$fee = new Foo();
$fee->bar = 42;
IMO using getters and setters is a good practice and increases code readability too.
Apart from checking the value while setting, there is another example, consider if u call getMoviesList(). Now this get method can be implemented in anyway, it can get movies list from the local db, get it from the online web service and so on... So the code making the decision maybe inside this function. Wherever u call it from, u don't care about the location and how it gets it. U just get the movies list.

Is this correct object oriented programming in php? [closed]

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

PHP5. Two ways of declaring an array as a class member [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
When declaring an array as a class member, which way should it be done?
class Test1 {
private $paths = array();
public function __construct() {
// some code here
}
}
or
class Test2 {
private $paths;
public function __construct() {
$this->paths = array();
// some code here
}
}
Which one is better in terms of good practices and performance? What would you recommend?
I'd suggest doing this when declaring a class variable. A constructor can be overriden in extending classes, which might result in E_NOTICEs or even E_WARNINGs if any of your functions depend on this variable being an array (even an empty one)
If you are going to populate your array dynamically during initialization, do it in the constructor. If it contains fixed values, do it in the property declaration.
Trying to populate an array dynamically (e.g. by using the return value of a certain function or method) within the declaration results in a parse error:
// Function call is not valid here
private $paths = get_paths();
Performance is not a real concern here as each has its own use case.
In general, because I write mostly in other languages besides PHP, I like to declare my instance variables outside of the constructor. This let's me look at the top of a class and get an idea for all properties and their access modifiers without having to read the code.
For example, I really don't like methods like this
// ...
// whole bunch of code
// ...
public function initialize() {
$this->foo = array();
// some other code to add some stuff to foo
}
Now, if I just look at the class, I can't be sure there is a variable foo even available. If there is, I don't know if I have access to it from anywhere outside the instance.
If instead I have:
public $foo = array();
at the top of my class, I know that foo is an instance property, and that I can access it from elsewhere.
There are no performance implications. Stop obsessing over things that don't matter - concentrate on performance problems that ARE there: measure first, optimize only the top offenders.

What's the best way to store class variables in PHP? [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 currently have my PHP class variables set up like this:
class someThing {
private $cat;
private $dog;
private $mouse;
private $hamster;
private $zebra;
private $lion;
//getters, setters and other methods
}
But I've also seen people using a single array to store all the variables:
class someThing {
private $data = array();
//getters, setters and other methods
}
Which do you use, and why? What are the advantages and disadvantages of each?
Generally, the first is better for reasons other people have stated here already.
However, if you need to store data on a class privately, but the footprint of data members is unknown, you'll often see your 2nd example combined with __get() __set() hooks to hide that they're being stored privately.
class someThing {
private $data = array();
public function __get( $property )
{
if ( isset( $this->data[$property] ) )
{
return $this->data[$property];
}
return null;
}
public function __set( $property, $value )
{
$this->data[$property] = $value;
}
}
Then, objects of this class can be used like an instance of stdClass, only none of the members you set are actually public
$o = new someThing()
$o->cow = 'moo';
$o->dog = 'woof';
// etc
This technique has its uses, but be aware that __get() and __set() are on the order of 10-12 times slower than setting public properties directly.
If you're using private $data; you've just got an impenetrable blob of data there... Explicitly stating them will make your life much easier if you're figuring out how a class works.
Another consideration is if you use an IDE with autocomplete - that's not going to work with the 2nd method.
If code is repetitive, arrays and (foreach) loops neaten things. You need to decide if the "animal" concept in your code is repetitive or not, or if the code needs to dig in to the uniqueness of each member.
If I have to repeat myself more than once, I loop.
Use the first method when you know you need that variable.
Use the second method (an array collection of variables) when you have dynamic variable needs.
You can combine these 2 methods, so some variables are hardcoded into your class, while others are dynamic. The hardcoded variables will have preference compared with magic methods.
I prefer the first method, for a few reasons:
In a good IDE, the class properties show up, even if private/protected
It's easier to see what has already been defined, reducing the chance you store the same information twice.
If the proverbial bus hits you on the way home, it's a lot simpler for another developer to come in and read your code.
And while it doesn't apply to private var, it does to protected vars, in classes that extend this class, you really should try to avoid the second method for pure readability.
Also, as a side note, I almost always choose protected over private unless I have a very specific reason to make it private.
The only time I'd probably use the second method was if I was storing a collection of many of one kind of thing.

Categories