Should I rewrite a simple function to a class? [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 5 years ago.
Improve this question
I am learning Classes and OOP and PDO and all that stuff ( I know legacy php, so, can write php 4.x scripts with messy code ^^ ).
So, started to transform over my base template system to the new code
so far so good, sessions and PDO are in classes , pagination system is in a class, users are in a class (basicaly everything).
Here's my question.
I use 2 functions to do a single thing
first function is to get the user rights and it looks like this
function u()
{
if ($_SESSION['loggedin'] == 1)
{
return true;
}
else
{
return false;
}
}
As you can see, it just return true or false based on session (code contains more but is for admin/staff ).
Should I also convert this to a class ? or is it useless ? and leave it as a function ?
Then my second function is to get some arrays ( used for group system)
function arr($string, $separator = ',')
{
//Explode on comma
$vals = explode($separator, $string);
//Trim whitespace
foreach($vals as $key => $val) {
$vals[$key] = trim($val);
}
//Return empty array if no items found
//http://php.net/manual/en/function.explode.php#114273
return array_diff($vals, array(""));
}
As this function is only used for the group update and to get info from what groups users are in is it in a function
So my question,
as far as i understand OOP does it mean that you write code to make things 'easier', so should I also make a class of those functions to make things easier or is it useless as it makes it harder ?
if (u())
{code code};
if (a());
{admin code}
vs
$u = new User;
if $u->rank(user){
code code
}
if $u->rank(admin){
admin code
}
Base code can be found here
it is to give a idea what I am rewriting to pdo.

Should i rewrite a simple function to a class?
Will this make your code maintenance easier?
Is this function occuring on more than one place in your project?
I can't give you an absolute answer, however generating an Object Class in PHP for a static simple function is overkill. It means you need to write more code, and your PHP processor has to do several magnitudes more work for the same - simple - outcome.
If your function occurs just once in your project then NO, you do not need to classify it in any way. This just adds overhead.
But, if you are using this function across multiple scripts and especially if there is a reasonable expectation that this function might need editing/extending in the future, then following Don't Repeat Yourself programming means you could put this function into a Static Class.
In the context of this question I will say more about Static Classes below but other options to remove repetition could be having functions in an include file at the top of your script, this essentially does the same thing as a Static class.
Follow DRY and you can happily copy/paste your function into a Static Class and call that class as required.
Static Classes are not instantiated, and can be used as containers for abstract functions such as the one you are describing, which don't fit neatly elsewhere.
however, there is no conclusive answer without us knowing what you're expecting to do with your project, are you maintaining and developing this or just updating a project without adding new functionality?
There seems a large minority of people obsessive that everything needs to be in a class, regardless of efficiency. Resist this temptation to wrap everything in classes, unless:
Does it make your data management easier to modularise?
Does it reduce/remove code repetition?
Does it make your code easier for you to understand?
Static Class Example:
class StaticClass {
public static function u() {
return $_SESSION['loggedin'] == 1;
}
}
Usage:
StaticClass::u(); ///returns boolean.
To be honest your function is so simple that in this specific instance you might as well just code the if statement directly:
if(u()){
// runs if u comparison returns true
}
becomes:
if($_SESSION['loggedin'] == 1){
// runs the same comparison as u() but avoids the
//function/class overheads
}

One day, suppose you decide that you wish to handle both session and token based authentication.
interface AuthInterface
{
public function isAuthenticated(string $credentials): bool;
}
class SessionAuth implements AuthInterface
{
public function isAuthenticated(string $user)
{
return $_SESSION['loggedin'] == 1;
}
}
class TokenAuth implements AuthInterface
{
public function isAuthenticated(string $token)
{
// validate token and return true / false
}
}
So in above example, using classes is very handy. You can now switch out your implementations super easy - and your code should still work.
Writing classes and programming to an interface - enables you to depend on abstractions, not on concretions. It should make your life easier.
If you have a few functions that are like helpers - e.g a custom sorting function - then go ahead and keep as a function. No point going overboard.

I think you should be consistent in what you do, but if a function is really just something like
function u()
{
if ($_SESSION['loggedin'] == 1)
{
return true;
}
else
{
return false;
}
}
or if you make it short:
function(u) {
return $_SESSION['loggedin'] == 1;
}
There is no reason to create a class for a one-liner. Also some inprovements for your arr() function: If you want to apply a callback to all Elements of an array, use array_map()
function arr($string, $separator = ',')
{
//Explode on comma
$vals = explode($separator, $string);
//Trim whitespace
$vals = array_map("trim", $vals);
//Return empty array if no items found
//http://php.net/manual/en/function.explode.php#114273
return array_diff($vals, array(""));
}

It's good to move things into classes, it enables reuse and also you can use an autoloader to only load in the classes you're actually using, rather than PHP parsing all the code. I'd put the first function in a User class or something (pass the session information in as a parameter, don't access that from inside your class) and the second one maybe in a Utils class or something like that?

Related

Check if an object has changed

Is there a more native way (e.x. a built-in function) with less userland code to check if an objects property values have changed instead of using one of those methods:
The serialize approach
$obj = new stdClass(); // May be an instance of any class
echo $hashOld = md5(serialize($obj)) . PHP_EOL;
$obj->change = true;
echo $hashNew = md5(serialize($obj)) . PHP_EOL;
echo 'Changed: '; var_dump($hashOld !== $hashNew);
Which results in:
f7827bf44040a444ac855cd67adfb502 (initial)
506d1a0d96af3b9920a31ecfaca7fd26 (changed)
Changed: bool(true)
The shadow copy approach
$obj = new stdClass();
$shadowObj = clone $obj;
$obj->change = true;
var_dump($shadowObj != $obj);
Which results in:
bool(true);
Both approaches work. But both have disadvantages compared to a non userland implementation. The first one needs CPU for serialization and hashing and the second one needs memory for storing clones. And some classes may not be cloned.
Doesn't PHP track changes at object properties? And does PHP not expose a method to make use of it?
What you are trying to do?
You are trying to compare object with itself, after some chain of "unknown" operations to check if the object has changed. If this is true, there are some logical points to observe. At first, if you want to compare object with itself, you've got only two options:
Remember the whole object state (for example hash, or just copy whole object)
Track changes over time
There is no other logical approach. Comparing memory allocations, real objects, copying objects, comparing hashes, is all in point one. Tracking changes, saving changes inside object, remembering meantime operations, inside point 2.
So in my opinion this question is sort of backing up data questions. In that case there are many, many solutions but none of them are hardcoded inside php as far as I'm concerned. Why?
The answer is simple. PHP guys have got the same problems you've got :). Because if this would be hardocded inside php, then php should run / use one of those mechanisms (1) or (2).
In that case every object that you create, and every operation you made should be written somewhere to remember every state / object / something and use them for comparison in the future.
While you need this solution, almost ~100% of websites don't. So hardcoding this inside php would made ~100% of websites work slower and your work faster ;).
PHP hypothetical solution?
The only solution (maybe built in php in the future) I can think of is making some kind of php config flag: track objects, and only if this flag is true, then run all the php mechanisms of tracking objects states. But this also mean a huge performance gap. As all the ifs (if tracking, if tracking, if tracking) are also procesor and memory time consuming.
There is also a problem, what to compare? You need to compare object with same object, but... Few minutes ago? Few operations ago? No... You must point exactly one place in code, and then point second place in code and compare object in those two places. So hypothetical auto tracking is... Kind of powerless, as there is no "key" in the object state ofer time array. I mean, even if you got magic_object_comparer function, what it should look like?
<?php
function magic_object_comparer() {} // Arguments??
function magic_object_comparer($object_before, $object_after) {} // you must save object_before somewhere...??
function magic_object_comparer($object, $miliseconds) {} // How many miliseconds?
function magic_object_comparer($object, $operations) {} // How many operations? Which operations?
magic_comparer_start($object);
// ... Few operations...
$boolean = magic_comparer_compare_from start($object);
// Same as own implementation...
?>
Sadly, you are left with own implementation...
After all, I would propose to implement some kind of own mechanism for that, and remember to use it only there, where you need it. As this mechanism will for sure be time and memory consuming. So think carefully:
Which objects you want to compare. Why?
When you want to compare them?
Does all changes need to be compared?
What is the easiest way of saving those states changes?
And after all of that, try to implement it. I see that you've got a huge php knowledge, so I'm pretty sure that you will figure out something. There are also many comments, and possible ideas in this question and discussion.
But after all maybe I explained a little why, there is no build in solution, and why there should not be one in the future... :).
UPDATE
Take a look here: http://www.fluffycat.com/PHP-Design-Patterns/. This is a great resource about php patterns. You should take a look at adapter, decorator and observer patterns, for possible elegant object oriented solutions.
While I too am looking for a very fast/faster approach, a variant of method 2 is effectively what I use. The advantage of this method is that it is (pretty) fast (in comparison to an isset()), depending on object size. And you don't have to remember to set a ->modified property each time you change the object.
global $shadowcopy; // just a single copy in this simple example.
$thiscopy = (array) $obj; // don't use clone.
if ($thiscopy !== $shadowcopy) {
// it has been modified
// if you want to know if a field has been added use array_diff_key($thiscopy,$shadowcopy);
}
$shadowcopy = $thiscopy; // if you don't modify thiscopy or shadowcopy, it will be a reference, so an array copy won't be triggered.
This is basically method 2, but without the clone. If your property value is another object (vobj), then clone may be necessary (otherwise both references will point to the same object), but then it is worth noting that it is that object vobj you want to see if has changed with the above code. The thing about clone is that it is constructing a second object (similar performance), but if you want to see what values changed, you don't care about the object itself, only the values. And array casting of an object is very fast (~2x the speed of a boolean cast of a bool) .. well, up until large objects. Also direct array comparison === is very fast, for arrays under say 100 vals.
I'm pretty sure an even faster method exists...
I can offer you another solution to the problem, In fact to detect "if an object has changed" we can use observer pattern design principles. May that way should be better for some people who want to get notify about changes in object.
Contracts/ISubject.php
<?php
namespace Contracts;
interface ISubject
{
public function attach($observer): void;
public function detach($observer): void;
public function notify(): void;
}
Contracts/IObserver.php
<?php
namespace Contracts;
interface IObserver
{
public function update($subject);
}
Subject.php
class Subject implements ISubject
{
public $state; // That is detector
private $observers;
public function __construct()
{
$this->observers = new \SplObjectStorage(); // That is php built in object for testing purpose I use SplObjectStorage() to store attach()'ed objects.
}
public function attach($observer): void
{
echo "Subject: Attached an observer.\n";
$this->observers->attach($observer);
}
public function detach($observer): void
{
$this->observers->detach($observer);
echo "Subject: Detached an observer.\n";
}
public function notify(): void
{
echo "Subject: Notifying observers...\n";
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
public function someYourLogic()
{
$this->state = rand(0, 10);
echo "Subject: My state has just changed to: {$this->state}\n";
$this->notify();
}
}
Observer1.php | Plus you are able to have as many ConcreteObserver as you want
class Observer1 implements IObserver
{
public function update($subject): void
{
if ($subject->state < 5) {
echo "Observer1: Reacted to the event.\n";
}
}
}
Clinet.php
$subject = new Subject();
$o1 = new Observer1();
$subject->attach($o1);
$subject->someYourLogic();
There is no built-in method, I'm afraid. The shadow copy approach is the best way.
A simpler way, if you have control over the class, is to add a modified variable:
$this->modified = false;
When I modify the object in any way, I simply use
$obj->modified = true;
This way I can later check
if($obj->modified){ // Do Something
to check if it was modified. Just remember to unset($obj->modified) before saving content in a database.
We can implement it without observer.
For pure php, we can use $attributes & $original to check what has been modified check this explanation if needed.
$modifiedValues = [];
foreach($obj->attributes as $column=>$value) {
if(!array_key_exists($column, $obj->original) || $obj->original[$column] != $value) {
$modifiedValues[$column] = $value;
}
}
// then check $modifiedValues if it contains values
For Laravel user, we can use the isDirty() method. Its usage:
$user = App\User::first();
$user->isDirty(); //false
$user->name = "Peter";
$user->isDirty(); //true

What is the difference between class and function in php? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I have used the following codes my self, both of them gave the same result. Then why we are using class instead of a normal function, and what is the difference between classes and functions.
<?php
class MyClass{
public $property = "This is My Class Property";
public function getProperty(){
echo $this->property."<br />";
}
}
$obj=new MyClass();
echo $obj->getProperty();
?>
<?php
function getProp(){
$prop="This is My Class Property";
echo $prop;
}
getProp();
?>
The PHP Language reference has details on what a function and class is:
http://www.php.net/manual/en/langref.php
It also explains most the other features of PHP. If want to learn PHP that is the best place to start.
Functions
The function is a grouping of statements (lines of code).
For example the following statements:
$name = 'mary';
$gender = 'girl';
if ($gender == 'girl') {
$line = $name . ' had a little pony.';
} else if ($gender == 'boy') {
$line = $name . ' had a little horse.';
}
echo $line;
Can be grouped together into a function so it can be reused:
getSentence('mary', 'girl');
getSentence('peter', 'boy');
function getSentence($name, $gender) {
if ($gender == 'girl') {
$line = $name . ' had a little pony.';
} else if ($gender == 'boy') {
$line = $name . ' had a little horse.';
}
echo $line;
}
Notice the two function calls:
getSentence('mary', 'girl');
getSentence('peter', 'boy');
These two statements run the whole block of code inside the getSentence function and pass it the variables $name and $gender.
With the first function $name = 'mary' and $gender = 'girl' and in the second $name = 'peter' and $gender = 'boy'.
So the main benefit of functions is that you have grouped code for reuse, allowing the passing of different values for the variables needed by the function. These variables are called the function parameters.
Another benefit of having the code grouped is easier readability. You are essentially naming the block of code, and giving them a specific purpose. Making it easy to read and remember it's use.
Another benefit is that redundancy is removed. You do not have to write the block of code more then once. You just define it once, and call it multiple times. This also makes editing of the function code affect all calls to that function - which reduces errors in having to edit multiple locations when changing just one aspect.
eg:
We can make sure the $name string has an uppercase first character.
function getSentence($name, $gender) {
$name = ucfirst($name);
if ($gender == 'girl') {
$line = $name . ' had a little pony.';
} else if ($gender == 'boy') {
$line = $name . ' had a little horse.';
}
echo $line;
}
We made just one change, and it affected every function call to getSentence(). In this case both:
getSentence('mary', 'girl');
and
getSentence('peter', 'boy');
Classes are a grouping of functions.
class Play {
function getSentence($name, $gender) {
$name = ucfirst($name);
if ($gender == 'girl') {
$line = $name . ' had a little pony.';
} else if ($gender == 'boy') {
$line = $name . ' had a little horse.';
}
echo $line;
}
function getSong($name) {
// code here
}
}
All we did was put
class Play { /** functions here **/ }
around a group of functions.
This offers the same benefits that functions do for statements except classes does it for functions.
Classes go further to build a programming methodology called Object Oriented programming (OOP), which you can read more about in link to PHP Language reference.
This defines classes as the template or definition of Objects. Objects being similar to real world objects, with the functions being called "methods" that can be called for the object.
So the class Play can be thought of as the object called "Play" with the methods "getSentence" and "getSong". These methods can then manipulate the properties of the object "Play" or return useful information about "Play". In this way, all the code inside Play becomes independent of code elsewhere in the program.
When the code inside Play requires some code elsewhere to function, it can be brought in using "inheritance", which is a major part of OOP. I will not go into detail about this as it is a very broad topic.
I would recommend getting a book on OOP and reading it to really understand why you should use classes and methods and when to use them.
Any function can be invoked as a constructor with the keyword new and the prototype property of that function is used for the object to inherit methods from.
functions are set of instructions or procedures for doing a certain task. for example, shooting a gun has a set of procedures to perform. raising your gun, taking aim, etc.
however, these procedures are dependent on each other. that is raising a gun means nothing alone.
in classes however you can create objects.
in objects , you can create for example, a gun. this gun has different functions associated with it like raising the gun, taking aim.
in effect the object can exist in its own and can be reused for later purposes.
class SimpleClass
{
// property declaration
public $var = 'a default value';
// method declaration
public function displayVar() {
echo $this->var;
}
}
so when you want to use the class object you need to declare
$objectSimple = new SimpleClass();
and when you want to use the class method than you need to declare
$objectSimple->displayVar();
as in your example
<?php
class MyClass{
public $property = "This is My Class Property";
public function getProperty(){
echo $this->property."<br />";
}
}
$obj=new MyClass();
echo $obj->getProperty();
?>
<?php
function getProp(){
$prop="This is My Class Property";
echo $prop;
}
getProp();
?>
yes you both will work. after reviewing your sample seems like you are asking for OOP vs procedural.
They don't really have pros and cons at all, IMO. They're simply different approaches to the same problems.
In a purely procedural style, data tends to be highly decoupled from the functions that operate on it.
In an object oriented style, data tends to carry with it a collection of functions.
In a functional style, data and functions tend toward having more in common with each other (as in Lisp and Scheme) while offering more flexibility in terms of how functions are actually used. Algorithms tend also to be defined in terms of recursion and composition rather than loops and iteration.
Of course, the language itself only influences which style is preferred.
You could say that a class is just a group of functions, but really it's so much more than that.
Think of a class as a group of functions that are used to manipulate the same amount of data.
Say you pull a user from the database. You would have to assign many variables accross multiple pages if you had any sort of complexity to your member system.
An easier way would be..
$user = new user(2)[/php) (assuming user is the class, and 2 is the userid it pulls from the databse, your contructor function would populate all of the users information, which is easily grouped together and used like...
[code=php:0]print "Hello ". $user->firstName . " welcome to thiswebsite. Your last login was " . $user->lastLogin
It's really a small and silly example, but if you let yourself think a little at the possibilities (and this isnt the only one, polymorphism is another GREAT feature of classes)
Usually when you use a function you intend to get information from it once, and then the function will forget the data it sent you (unless you're creating a site variable, or constant in it...)
A class you might want to create if you want to continue to use information. For example, a customer signs in, and wants to look through six different pages about their account. You'd probably want to create a class so that immediately when the customer signs in, you have information on that customer, that you don't have to continually make sql calls to get.
Maybe at the top of the screen you wish to put their status, and their billing info. You would get this information when they log in, and put in the constructor. Then no matter what page they go to, this information will be quickly available.

Using clousers to handle templates in PHP

There is like a million Template Engine for PHP (Blade, Twig, Smarty, Mustache, ...), and i just hate the idea of creating a new syntax and compiler to write PHP inside HTML! I think it's just not smart (but this isn't what i am here to discuss :) ), what is wrong with writing PHP+HTML the usual way - not for logic - you know, all the variables and loops and defines you wanna use without this {{% %}} or that {:: ::} ! At least for performance sake!
Now, i am using Laravel these days , and it's awesome; it offers (besides Blade and any other 3rd party engine) a plain PHP templates system that uses ob_start/include/ob_get_clean and eval. I was very happy to know that i can avoid learning a new syntax to write PHP inside HTML.
Here is what i am suggesting; what about instead of using ob_* functions with include, we use Closures ? Here is a simple class i put together just to make a point:
class Templates{
static public $templates = array();
static public function create($name, $code){
self::$templates[$name] = $code;
}
static public function run($name, $data){
if(!isset(self::$templates[$name]) || !is_callable(self::$templates[$name])) return false;
return call_user_func(self::$templates[$name], $data);
}
}
And here is how to use it:
Templates::create('test', function($data){
return 'Hi '.$data['name'].' ! ';
});
for($i =0; $i < 10; $i++){
print Templates::run('test', array('name' => 'Jhon'));
}
I think this way is much better, since i wont need to do any output buffering or use eval. And to "separate concerns" here, we can put the Templates::create code in a separate file to keep things clean, in fact this way things can become more simple and elegant; we can make another method to load the template file:
static public function load($name){
self::create($name, include($name.'.php'));
}
And the content of the template file will be as simple as this:
return function($data){
return 'Hi '.$data['name'].' ! ';
};
What do you think of this ? Is there any problems with the approach or the performance of such use of Closures ?
I do not think there are any problems besides that if you put all closure functions into array, that would possibly mean that functions are kinda doing basically the same stuff.
What I mean by this:
In your example you have your functions accepting only 1 parameter. So, not to create a mess all functions you create would accept the same set of parameters and return the same type of data.
However when declared apart, functions may be supposed to do something different and unique.
Why such a solution is suitable: when using some engines, there may be a lot of different functions declared already. To resolve the conflict, they can be "hidden" inside arrays.
Also, some people even say that anonymous functions can be generally better in case of performance. But we have to test that first: to call a function you:
Call a static function run
Check a function for existence
Check a function for callability
And then use call_user_func which returns the return of your function. So, 3x return.
Update
My recomendations for you code:
Make all possible checks only when creating a function. That will greatly buff performance.
static public function create($name, $code){
if (!isset(self::$templates[$name])){
if (is_callable($code)){
self::$templates[$name] = $code ;
} else {
//func is not callable, Throw an exception.
}
} else {
//function already exists. Throw an exception.
}
}
That way you just can have 2x increase in performance:
static public function run($name, $data){
if (isset(self::$templates[$name])){
self::$templates[$name]($data); //Just make a straight call
} else {
//throw new Exception(0, "The func is not defined") ;
}
}

php: procedural to objects - structure?

For years now I have been writing (on and off) at an office-management app. I need to rewrite it, because the code has become unmaintainable, so I will choose a PHP-framework and rewrite the business logic into classes.
Now I am stuck with this fundamentamental question: do I still need to return the result and if yes, how do I capture that result? Some pseudocode to make my question clear:
function a( $1, $2, $3 ) {
doThis( if ... return TRUE; if ... return FALSE; );
if ( doThis() != TRUE ) { return; }
doThat();
}
vs
class example {
private $1;
private $2;
private $3;
public function go() { $this->doThis(); $this->doThat(); }
private function doThis(){}
private function doThat(){}
}
$a = new example;
$a->go();
How can I stop the execution of the go()-method if the doThis()-method does not perform as expected? I presume I should not go about returning booleans and checking inside every method if a certain property is set to false? Or do I simply throw an Exception if something went wrong and don't do anything if everything is ok?
This is pretty basic, I know...
Thx!
Exceptions are for exceptional behaviour, so don't throw exceptions just because your code isn't in a preferred state. When it comes to writing OOP, some people still manage to write procedural while using a object oriented framework, obviously you'd want to avoid that, a simple rule of thumb is to not write God-objects.
Now what I'm guessing that you want to do is to call two functions that should be called in a specific order, and there are several ways to do this, and it actually boils down to, what kind of class you have. Lets say you have an object of the type Person then you might want to call different methods on that person from somewhere else:
$john = new Person();
$john->tryToWakeUp();
if($john->isAwake) {
$john->brushTeeth();
} else {
echo "John is still sleeping!";
}
On the other hand you might have an object of the type Engine which might want to do several stuff internally for certain actions, like start:
class Engine {
public function start() {
$this->checkFuel();
if($this->hasFuel()) {
try {
$this->initializeSomethingThatHasToDoWithEngineStartUp();
} catch (EngineException $ee) {
$this->engineState = BAD_ENGINE;
Logger::log("Engine did not start");
}
}
}
}
I'd recommend you to read up on object oriented design and play around with it before you try to convert all of your business rules, because It's likely that half way through you'll realize that you've designed everything wrong. Object Oriented Design is not easy, but it does make sense EDIT:( It should make sense ).

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