Search code examples
phpoopstaticnamespacesprocedural-programming

Converting procedural PHP into object-oriented PHP


I currently have a fairly large application written entirely with procedural PHP. I am looking to further my PHP experience and recode a majority of my application using object-oriented techniques.

There are a lot of areas where OOP can help reduce the amount of code and make it easier to read. However, I have a few questions.

1) It is my understanding that one class is used as a blueprint for any number of objects, but any one class represents only one object, never more than one. So one class could represent a player, but never multiple players.

2) Since I will have quite a few different classes to include, do I use a "Loader" class to load them all using spl_autoload_register or do I just use spl_autoload_register in the program files for my application?

Edit: So my autoloader would be a class that I then create an instance of to start the autoloading or simply a php file with the function and the spl_autoload_register that I would include to avoid repeating the same code in multiple files?

3) Some of my classes depend on other classes. I've never encountered this before, so I honestly do not know the answer. If I include all the classes in my main program file, but my player class does not include the class which it needs to function, will the player class work since the main program has included the class which player depends on?

Edit: So even though one class may instantiate an object of type Player, and the Player class is not directly included by this class, it will still work because the controller class does include the Player class?

4) There are multiple cases where I will need to work on the objects I am creating. I am wondering how I should do that. For example, in my Player class I will sometimes need to send something from one Player to the other Player. So, do I implement a static method in the Player class that takes two Players as parameters and does the transfer or do I do something else?

Edit: Okay, so avoid static methods. Now I have a serious problem: I have methods that are ran multiple times in my application, but I cannot implement them as static methods. Am I supposed to implement them as instance methods? For example, sending from one Player to another. Would I create an instance method that takes a Player object and sends either to it or from it?

5) I have a lot of methods that don't really belong to any one instance of a class nor are they really appropriate as static methods. Should these be declared in their own class as static methods as Common or similar? What is the done in practice in this situation?

Edit: Would these methods belong in the specific application file for which they are used or perhaps stored in their own "functions.php" file?

6) I'd like to learn how to use namespaces, but my code will never be used by others and I will never use anyone else's code in my application. Are namespaces an unncessary addition in my application or would it be a good idea to learn how to use them? Regardless, does one application have one namespace (the application name?) or does each class belong to it's own namespace?

7) Lastly, is it common to have one class for database connections and also a class for network methods? My application needs both. I think the main problem I am having with converting my code to use object-oriented techniques is determining which methods to put where, as currently they are all in one monolithic file.

Thanks for any help and insight you can provide.


Solution

  • 1) It is my understanding that one class is used as a blueprint for any number of objects, but any one class represents only one object, never more than one. So one class could represent a player, but never multiple players.

    Typically, you will also have classes that represent collections of objects, e.g. a class "Players" that can be used to retrieve a single player from the collection of all players:

    $players = new Players();
    $john = $players->findByName("john");
    

    2) Since I will have quite a few different classes to include, do I use a "Loader" class to load them all using spl_autoload_register or do I just use spl_autoload_register in the program files for my application?

    That pretty much depends on the complexity of your project. A simple autoloader function will typically be good enough but you may take a look at the Zend Framework Autoloader class.

    3) Some of my classes depend on other classes. I've never encountered this before, so I honestly do not know the answer. If I include all the classes in my main program file, but my player class does not include the class which it needs to function, will the player class work since the main program has included the class which player depends on?

    Yes. However, with autoloading you do not need to worry about this at all. If you do not use autoloading, it's a good idea to include the required classes in the file that defines the class (using require_once() to avoid including the same file more than once).

    4) There are multiple cases where I will need to work on the objects I am creating. I am wondering how I should do that. For example, in my Player class I will sometimes need to send something from one Player to the other Player. So, do I implement a static method in the Player class that takes two Players as parameters and does the transfer or do I do something else?

    Static methods are almost always the wrong approach. Normal methods belong to an instance (i.e. the specific player) and static methods belong to the class, i.e. the general "idea" of a player. If you need to transfer stuff from one player to another, why not implement this like this:

    class Player {
        public function transferMoney(Player $recipient, $amount) { ... }
    }
    
    $tom = new Player("tom");
    $marc = new Player("marc");
    
    $tom->transferMoney($marc, 500);
    

    5) I have a lot of methods that don't really belong to any one instance of a class nor are they really appropriate as static methods. Should these be declared in their own class as static methods as Common or similar? What is the done in practice in this situation?

    I cannot reasonably answer this. However, there are still plain functions in PHP which seem to be the best method for such cases. Yet, if you do OOP right, you will most likely never encounter such problems. It's usually a problem with your class design which makes you thing that these methods do not belong to any object.

    6) I'd like to learn how to use namespaces, but my code will never be used by others and I will never use anyone else's code in my application. Are namespaces an unncessary addition in my application or would it be a good idea to learn how to use them? Regardless, does one application have one namespace (the application name?) or does each class belong to it's own namespace?

    Namespaces are great but your code will probably turn out just fine without them. As namespaces can be nested, you will usually have a top-level namespace and sub-namespaced per component.

    7) Lastly, is it common to have one class for database connections and also a class for network methods? My application needs both. I think the main problem I am having with converting my code to use object-oriented techniques is determining which methods to put where, as currently they are all in one monolithic file.

    This depends on how you model your actual situation. If database connection and "network" are two different things for you, two classes are the way to go.