OOP Style coding – PHP

  php

Q(Question):

hi guys,

I’ve recently begun working with OOP concepts, and I grasp the class/method setup well enough, however, my code hasn’t followed my brain, and tends to be still very static and inflexible.

for example (not a real example):

class sqlstuff{
function insert($vals){
$sql="insert $vals[1],$vals[2],$vals[3] into tblname col1,col2,col3";
$action=sql_query($sql);
}

using the example, could you point me in the right direction?

A(Answer):

hi guys,

I’ve recently begun working with OOP concepts, and I grasp the class/method setup well enough, however, my code hasn’t followed my brain, and tends to be still very static and inflexible.

for example (not a real example):

class sqlstuff{
function insert($vals){
$sql="insert $vals[1],$vals[2],$vals[3] into tblname col1,col2,col3";
$action=sql_query($sql);
}

using the example, could you point me in the right direction?

What do you want to do exactly??
Do you want to make your INSERT statement flexible??

Regards,
RP

A(Answer):

Hi,

first of all, your class seems to be missing a constructor, which must be a function which has the same name as the class. But maybe you just are not showing this in your example.

After you create a class, there are two ways to use it: by instantiating (creating) an object assigned to a php variable, or by directly calling the class function. In the latter case, you cannot use the $this within the function you are calling, but this allows you to use a class function without creating an object, and is a good way of "namespacing" your code.

Like if you have a class called "myclass" and in it is a function called "myfunction" with let us say no arguments but returns a value, you can call it like this without creating an object:


$result = myclass::myfunction();

But what you really want to do most of the time is to create an object as a PHP variable like with:


$myobject = new myclass();

where here for an example the constructor does not take any arguments (but it can if you make it so).

This way, if there are any class member variables, they can be accessed within the class as $this->membervariable and externally to the class as $myobject->membervariable (this is why PHP is so flexible). And you access class functions in a similar fashion.

This is just a few words to get you started. Look up what I am writing about in the PHP class documentation.

No time to write more. Hope this helps a little.

A(Answer):

ok, the example was just that, an example, but I’ve not looked into constructors… maybe what I’m doing isn’t really OOP…

as for what I am trying to do, in the example you are correct, it would be attempting to make that function more flexible, but it was more of a leading question into learning more about OOP as all of the resources I can find already assume knowledge of OOP or are EXTREMELY basic (aimed at people who have never written a line of code in their lives).

Thanks for the pointers so far!

A(Answer):

Heya, Tarantulus.

This should get you started — or get you more confused. Either way, enjoy the journey.

When you develop for OOP, you will want to think in terms of objects (generally known as ‘models’ when they relate to database records), rather than tasks or functions.

For example, suppose you had a program to fetch and edit customer data. In procedural style, you might come up with something like this:


function fetchCustomer( $customerID )
{
global $db;
$res = mysql_query("SELECT * FROM `Customers` WHERE `CustomerID` = '{$customerID}' LIMIT 1", $db);
return mysql_fetch_assoc($res);
}
function saveCustomer( $name, $title, $phone, $customerID = null )
{
global $db;
mysql_query("REPLACE INTO `Customers` SET `Name` = '{$name}', `Title` = '{$title}', `Phone` = '{$phone}', `CustomerID` = '{$customerID}'", $db);
}

Let’s change this up and make it object-oriented. So we have a Customer, which has certain properties, such as an ID, title, phone number, etc. The Customer can do certain things, such as saving its properties to the database. We can also do certain things related to Customers, such as fetching one from the database.

The distinction between those last two is important because saving a Customer requires that we already have an existing Customer, whereas fetching a Customer requires that we don’t.

A skeleton of our Customer object might look something like this:


class Customer
{
public $myCustomerID;
public $myName;
public $myTitle;
public $myPhone;
// Yada yada....
public function __construct( $customerID, $name, $title, $phone )
{
}
public function save( )
{
}
public static function load( $customerID )
{
}
}

Here’s the class with its methods implemented:


class Customer
{
public $myCustomerID;
public $myName;
public $myTitle;
public $myPhone;
// Yada yada....
private $_myDB;
public function __construct( $db, $customerID, $name, $title, $phone )
{
$this->myCustomerID = $customerID;
$this->myName = $name;
$this->myTitle = $title;
$this->myPhone = $phone;
$this->_myDB = $db;
}
public function save( )
{
mysql_query("REPLACE INTO `Customers` SET `Name` = '{$this->myName}', `Title` = '{$this->myTitle}', `Phone` = '{$this->myPhone}', `CustomerID` = '{$this->myCustomerID}'", $this->_myDB);
}
public static function load( $db, $customerID )
{
$res = mysql_query("SELECT * FROM `Customers` WHERE `CustomerID` = '{$customerID}' LIMIT 1", $db);
if( $row = mysql_fetch_object($res) )
{
return new Customer($db, $row->CustomerID, $row->Name, $row->Title, $row->Phone);
}
else
{
return false;
}
}
}

This is a very, VERY basic implementation, and I promise you that in five years, your DB models will look nothing like this, but it is a good start.

Let’s look at a common situation: Changing a customer’s name.

Here’s how you would do it using procedural code:


$customerID = 5;
$newName = 'Frank Thomas';
// Fetch the customer's info.
$customerInfo = fetchCustomer($customerID);
// Change the info.
$customerInfo['name'] = $newName;
// Save the info.
saveCustomer($customerInfo, $customerInfo['Title'], $customerInfo['Phone'], $customerID);

Here’s how you would do it with objects:


$customerID = 5;
$newName = 'Frank Thomas';
// Fetch the customer's info.
$Customer = Customer::fetch($db, $customerID);
// Change the name.
$Customer->name = $newName;
// Save the info.
$Customer->save();

A(Answer):

Excellant example by pbmods!

A few things to note when you compare that example’s procedural vs. OOP code: The OOP code makes things more organized, as things that "belong" to a customer are located as a variable or method within the customer class, and is referred to either directly with the classname::classmember syntax or by the $classobject->classmember syntax. In other words, you now know where to find things that belong to this particular object that is being modelled in your code.

But another aspect of OOP that is very valuable is the way that code can be made re-usable or flexible. Take this example: Let us say we have two things that are very different, let us say an object "dbdata" that needs to be stored in a database, and another object "filedata" that needs to be stored in a file on the hardisk. So if you imagine that you write a class for each object, and for each object you write a member function that does the appropriate save and then call it with a common name, for example "saveData()".


function handleData($dataitem) {
// do some things here to the data.
// now you need to save the data.
$dataitem->saveData();
// do other stuff maybe
}
$myfiledata = new filedata();
$mydbdata = new dbdata();
// do stuff here
// handle the data for each object
handleData($myfiledata);
handleData($mydbdata);

The point here is that each class knows how to save its data because of its own class method. Each class has its own set of methods to do whatever tasks are needed, but in a manner that is appropriate for that class. But externally to the class, the code can look the same. You then begin to be able to code much cleaner, and more concise.

If you were to do this procedurally, you could do some tricks (you can have specific save functions for each object and send the name of the save function to call as an argument to the above "handleData" function, for example) or you would need to add arguments to a common save function to tell the function how to save the data depending on which object it is called for. But this is sloppy and can easilly lead to very confusing code.

A(Answer):

Wow, suddenly it all makes sense, that was an awesome example. It shows me that what i thought was oop was simply not right! Thank you so much.

LEAVE A COMMENT