Procedural or Object Oriented - The PHP Project Guide (2014)

The PHP Project Guide (2014)

8. Procedural or Object Oriented?

A lot of people start learning PHP using procedural code. This is perfectly acceptable because it introduces the language in a way that feels more natural. On the other hand, it’s important to grasp Object Oriented Programming (OOP) with PHP because it makes for more maintainable, reusable code. OOP within PHP can be confusing and complicated at first, but building this way can ease development into the future.

8.1 What is Object Oriented Programming?

OOP was introduced with PHP 4 and is often confused as extended features. I’ve often heard it referred to as an add-on, plugin or extension. Let’s take a quick overview of the fundamental parts of OOP.

OOP is a style of programming that takes away from the procedural and functional nature of programming. It makes programming modular and assists in separating business logic and views by allowing for better patterns to exist. In short, OOP isn’t extended functionality in terms of what a language can do, it just allows for code to be written in a particular way. An inexperienced programmer could mix the two styles of writing which would be incorrect. Writing object oriented code can be as simple as separating functionality of your website into classes and just having properties and methods, or could be as advanced as it allows, creating very powerful easy to manage code.

Classes are object definitions, that become objects when instantiated (used). These contain properties (variables) and methods (functions). If you had a class called User, you would instantiate this, and would perhaps make use of methods like login, or createUser. Or perhaps you had a Database class, could have several properties - host, username, password and database. On instantiation of this class, you could pass arguments to then set properties within the object. Another method, connect, may then make use of these properties to connect to a MySQL database. This class would provide functionality to query your database tables and retrieve results. Basic OOP really is as simple this, with a host of additional functionality that allows you to proceed into advanced OOP programming.

At least, it’s good to start with basic classes, methods and properties. The reason for this is that in the future you can quickly expand on what you’ve built initially without having to rebuild your entire website.

8.2 Tips for learning and retaining

If you’ve already tried to learn OOP, you’ll probably have already seen examples that relate to everyday objects that can have properties and methods. These are often presented as real world things like cars or animals. There is a massive problem with the bridge between learning OOP and examples like this, because as with any technical subject, it doesn’t give you the practical benefits as you’re learning. Sure, you can learn that an animal can be an object, it can have different properties, inherit from a superclass species and can contain functions like meow when you create a Cat class, for example. However, when it comes to setting up a Database class, how is this helpful? You’d now need to apply this knowledge to your actual application but have absolutely no idea what you’re supposed to do with a Database class. The answer is simple, but harder in practice - and that is to practice! As with anything, practice can make perfect, and working with OOP in a real application will help you understand how everything should tie together. Of course, you can still grasp the many techniques from these resources that teach OOP in relation to real world objects, but can then logically apply the thinking towards your application.

For example, let’s say you need to create a registration and login system. If you start to think of each user as an object, you can start to apply this. You’d go ahead and create a class User, which could then be instantiated and you’d then make use of the many methods you may create within it, for example, login. But, what happens when you then need to create a slightly different variation of this class, for example for administrators? You may like to keep a separate Administrator class so you can instantiate this for when administrative functions are required. So, you would then be able to apply what you’ve learned in a practical way and create an Administrator class, which would inherit all properties and methods from your User class. You could then create additional methods within this, serving additional functionality to the administrator that wasn’t previously available within the main User class.

If you’re unsure about inheriting in OOP, it’s a fairly simple concept. Creating a class without declaring it as final means you can create additional classes and inherit properties and methods from that class. The class from which your inheriting is then a superclass and the recently created class is a subclass. This sounds complicated, but simply put, you’re creating a class that’s taking properties and methods from another class as long as the properties and methods are not declared as private (which means only the class they’re defined in can have access to them). Similarly, learning about encapsulation can be made difficult simply due to its name.

Encapsulation is basically the practice of setting visibility modifiers (again, a slightly more complicated sounding term) to your properties and methods. These can either be public, protected or private. The difference is simple - public properties can be accessed from anywhere, by referencing the class on the page where it’s instantiated or within a subclass. Protected properties can be access within any subclass, but not from outside of the class and private properties can only be accessed from within the class they were defined in.

These rules, and the ability to define classes, properties and methods in these ways can sound rather odd. The key is to understand that this is rarely to alter functionality. You’re not writing code that will directly affect how your website will function, but instead you’re writing this code by design and conforming to a standard. This makes it a lot easier to reuse code and for different developers and yourself to work more efficiently on your website by giving clearly defined code, separated by logic.

8.3 But what about functions?

Functions can and should be used for their original purpose - providing functionality that can be used again and again. Although methods within classes are technically functions, you can define a file containing functions that you may commonly use that aren’t related to any particular class. For example, you may have a function that calculates the VAT for a particular item’s price based on a global configuration value, or something more general like calculating the area of a circle. Of course, these can be embedded within your defined classes, however bear in mind that it wouldn’t make sense to say $user->calculateCircleArea($radius);

PHP has been criticised as not being a truly object oriented language because of its use of functions. Of course, PHP started purely as a procedural language and of course cannot remove functions that already exist for backwards compatibility.

8.4 Is it ok not to use OOP?

Procedural code is fine. If you still prefer to use procedural code then this won’t affect the way your application works as long as you’ve carefully designed it and haven’t made a mess of the source code so it’s either unreadable or hard to work with. It’s argued that because PHP isn’t a purely object oriented language that it’s not always necessary.

Let’s take an example. You have a website that searches your database for articles. The user is presented with an interface and types some keywords, and is then forwarded to a page where they see a list of results. The files involved here would most likely be the landing page (index.php) and the results page (results.php). From this, we can pass keywords from an HTML form to our results page and pick up these keywords with the $_POST array. All that’s required here is a simply call to the database (after some sanitisation and splitting of keywords, of course) and then the results are returned as, perhaps, an array. You then have a predefined template to display results and the associated information and you simply loop through this list. You may decide to add pagination or a dropdown list so the user can specify how many results they see and this would be passed from a form and picked up and applied to either the query or the code you’re using to loop and display results. If you’re working with simply functionality like this you may not benefit from using OOP.

Of course it’s ok to not use an Object Oriented approach when programming, however moving forward you’ll see a lot more code written in this style. You also may find it harder to move to another language that depends on this style if you don’t at least learn the basics. Remember that this style of programming is and should feel natural.

8.5 Examples in practice

Let’s look at a couple of examples where you may want to apply this. The first will be a registration and login application and the second will be a generic database handler to return data quickly and easily. These are both useful and would more than likely apply to any website.

Database handler

What do we need to do here? The first is to create a skeleton outline of our class. Doing this initially makes it easier to grasp what you need to start doing within each of the properties and methods you need to create.

1 class Database {

2 private $_link, $_result;

3 public $count = 0;

4

5 public function __contruct($server, $username, $password, $db) { }

6 public function query($sql) {}

7 public function result() {}

8 public function count() {}

9

10 }

We could add more functionality, but let’s keep this short. When we instantiate this Database class we want to pass in the server, username, password and database. This could come from a configuration file and would then establish a connection to our server. We also have three properties, link (the link to our database connection), result (the result of the last query performed so we can access this from other methods) and count, which is simply the number of rows returned by the last query.

1 class Database {

2 private $_link, $_result;

3 public $count = 0; // can be accessed by subclasses and outside of the class if \

4 required

5

6 public function __contruct($server, $username, $password, $db) {

7 $this->_link = mysqli_connect($server, $username, $password);

8 mysqli_select_db($db);

9 }

10

11 public function query($sql) {

12 $this->_result = mysqli_query($sql, $this->_link);

13 $this->count = mysqli_num_rows($this->_result);

14 }

15

16 public function result() {

17 if ($this->count >= 1) {

18

19 $rows = array();

20

21 for($x = 1; $x <= $this->count; $x++) {

22 $rows[] = mysqli_fetch_assoc($this->_result);

23 }

24

25 return $rows;

26

27 } else {

28 return false;

29 }

30 }

31

32 public function count() {

33 return $this->count;

34 }

35

36 }

This is generic functionality to connect, query, count results and return rows. Obviously it’s an example, but looking carefully it should make perfect sense. Anything larger than this may be difficult to absorb, but don’t worry, it’s unlikely to relate to your website. Remember that starting small and building up as you go is fine. If it works, you’re on the right track and can improve and tweak as you go.

warning

Warning!

Remember working with OOP doesn’t excuse you from security. You need to implement security as you would at any other time.

8.6 User class

You may need something to handle users and then expand this to add different functionality for special users, like admins. This is extremely easy and makes a lot of sense using an object oriented approach. Let’s look at an example class:

1 class User {

2 protected $_id;

3 public $data;

4

5 public function set($id) {

6 // identify user so we can use $id in other methods

7 $this->_id = $id;

8 }

9

10 public function get_data() {

11 // get user data from database and store in $data property

12 }

13

14 }

A short snippet that doesn’t do much, but that’s ok, it’s only an example. If we wanted to create an admin we may want to add special functionality to an additional class to allow other methods, but keeping the original methods. We still need to access admin data! The reason we used a protected property is so we can access this $id within any sub classes.

So, we could do:

1 class Admin implements User {

2 public function get_users_banned() {

3 // return the amount of users this admin has banned

4 }

5 }

We can also access get_data, etc. by doing something like:

1 $admin_data = $admin->get_data();

2 echo $admin_data['username'];

This is due to the fact that all public and protected properites and methods are available to us as we’ve inherited the User class.

8.7 Grasping OOP

It can be difficult to grasp the concepts of object oriented programming in PHP due to the time most PHP programmers have spent writing procedural code. If you’re experienced in something like Java, writing object oriented PHP code shouldn’t be too much of a struggle.

The best way to grasp this style of writing code is simply to do it. Think to yourself that the next application you build will be written like this and you can find help and support along the way to improve and extend the functionality. A great way to practice is to look at any classes you’re currently implementing within your project if any. Let’s say you have a class that allows you to read Excel files. Open it up, have a scan and see how it’s written, but of course don’t rely on looking at other’s code.

It’s also a good idea to look at some popular, well-built and expressively written frameworks and look at how they work.

8.8 Recommended reading

Although this book extends into very advanced topics, I highly recommend PHP Object-Oriented Solutions by David Powers. This gives a good basic overview of the fundamental parts of OOP in PHP and extends to more advanced topics.

The PHP manual is obviously somewhere that can be useful when learning OOP with examples and information about the structure of the language.