Procedural vs Object Oriented PHP Programming

In a case when a client needs code only for particular project. What would be better for him? I am not talking what would be better for me as developer to reuse code in other projects, but only from the client side. Is in this case procedural code really so bad?

Please write together with your comment how many years of experiences you have in both procedural and OOP.

I just read post from somebody from 10+ years of PHP experiences. He wrote:

As a PHP programmer since PHP3, I have ten years’ commercial experience with the language, as well as fluent perl and good exposure to four or five other languages. Back in PHP3, there was no OO, and so that’s what I started with.

Having since had experience with both models, plus both models in perl, and modern OO languages such as Ruby, I believe I am reasonably informed.

I believe that it is often said that OO code is somehow more ‘structured’ or ‘re-usable’ than procedural code, and that this is simply incorrect.

Good PHP procedural code is just as powerful as OO code.

It is very easy for OO programmers to pretend they are producing quality code, whereas in fact they are programming an infectious monster that does not offer any or many opportunities for elegant re-use outside of the initial problem domain. This is the case a large percentage of the time with most OO PHP programmers.

For this reason I always emphasise the use of procedural code for overall logic. Object oriented approaches are only used on specific problem domains that are both well defined and well suited to the OO model.

If you work on a project, you probably use data structures. Data structures in PHP are classes. Many times, when I write a big program I find myself writing the same code for different classes. When you find yourself doing it, it’s time to switch to a more object-oriented style.
I have a little experience in PHP, and 3-4 years in object oriented PHP5.

Procedural code is only really useful for small projects. Once you go over a couple of hundred lines of code it makes more sense to use an OO approach as that will generally keep the code at any level of abstraction to a small enough piece of code to actually be able to follow properly.

I would like to see those claims backed up with something. Nothing he said was more than a baseless assertion.

With procedural you basically end up choosing between:

-Reliance on global variables making for very difficult to test code

OR

-Functions which take many, many arguments.

Both along with a mess of difficult to find functions.

Of course OOP doesn’t solve either of these immediately but it gives you more power to do so, offering:

-More levels of scope
-Polymorphism
-Inheritance
-A better model of real world problems

As for

As a PHP programmer since PHP3, I have ten years’ commercial experience with the language, as well as fluent perl and good exposure to four or five other languages. Back in PHP3, there was no OO, and so that’s what I started with.

This is known as an appeal to authority fallacy. Keep in mind also that after 10 years working in a language you get used to doing things in a certain way. Don’t take ‘experience’ as an argument on its own.

bazinga!

That quote is fun – why fun? it makes a lot of statements, but it doesn’t explain the reasoning behind them. I’m hoping that’s an incomplete quote – but given the propensity for “me too” posting on forums and the illiterate whiny “TLDR”/ “AAAH, WALL OF TEXT” that probably is the entire thing. It makes claims, but doesn’t back them up with any examples, similes or other devices to support it. In marketing circles that’s called “authoritative text”.

So let’s actually DISCUSS the topic!

The problem as I see it is too often many programmers seem to want it to be a vs… a question of one or the other instead of the rational choice of AND. Objects AND procedural. You see this in how they write code; you have the die-hards and nubes who refuse to ever touch objects as they’re “too complex” and the zealot-like recently converted who start wrapping EVERYTHING in objects whether it’s warranted or not.

Some tasks are inefficient/wasteful as objects. Objects by their very nature bring large memory overheads, often increasing the number of function calls… this is made worse when the simplest of things are wrapped in functions for no reason as methods. A declared object keeps all it’s variables in memory once they are initialized and/or declared until you release the object or manually release them with unset – this can lead to a very large memory footprint.

On the other hand, objects are like Vegas. What goes on in Object stays in Object. The reduction in the use of global namespace is very attractive, the ability to have public and private values is also very attractive… but more important than all that:

Objects are polymorphic – you can declare them once and have all values the same across ten variables of the same thing automatically; and they expandable, you can add new properties via inheritance.

Procedures on the other hand pass values on the stack and release values when they end – meaning you generally have better garbage collection sticking to them so long as you don’t go nuts using ‘globals for no reason’. Well written procedures passing values by reference and returning the result can be faster, less code,

BUT they lack inheritance – and in PHP they aren’t overloadable (very few languages allow for overloading). Once you make a procedure you cannot ‘enhance it’ without writing a whole new procedure with a whole new name; meaning you have to backtrack to every time it’s called just to change it if desired.

The choice for me comes down to something I read in either a smalltalk or modula book quite a long time ago… a series of short questions to ask yourself:

Is the data being handled “object-like” – as in when you first reference it ALL it’s values are being initialized for use.

Are you going to run more than one instance of the data/handler code simultaneously?

Will one or more classes be inheriting from this object in the future or might the user want to expand it thus?

It shouldn’t be a question of JUST one or JUST the other – they’re just tools in your toolbox and as always, just use the right tool for the right job. Some examples:

PDO – database connections are IDEAL for objects… you can make the initial connection a local object to prevent code appendages from EVER having access, you can pass the object by reference without any of the security information contained within becoming global. You can choose to easily expand the PDO object with new methods and variables and modify the constructor to set up anything you want. Perfect candidate to be an object and vastly superior to the various mysql_ functions.

For example, extending PDO.


class dbPDO extends PDO {
	public $tablePrefix;

	public function __construct($dbType,$dbName,$server,$port,$username,$password,$tablePrefix) {
		$dsn=$dbType.':dbname='.$dbName.';host='.$server.(
			empty($port) ? '' : ';port='.$port
		);
		parent::__construct($dsn,$username,$password);

		$this->tablePrefix=$tablePrefix;

	}

	function tableExists($tableName) {
		try {
			$qHandle=$this->query(
				"SHOW TABLES LIKE '".$this->tablePrefix.$tableName."'"
			);
			/* damned shame we can't trust rowCount */
			$result=$qHandle->fetchAll();
			return (count($result)>0);
		} catch (PDOException $e) {
			echo 'Error - ',$e->getMessage(),'<br />';
			return false;
		}
	}

	function countRows($tableName) {
		$result=$this->query(
			'SELECT COUNT(*) AS COUNT FROM '.$this->tablePrefix.$tableName
		);
		return $result->fetchColumn();
	}
}

But let’s just look at a simple common function… like say we wanted to take any text and turn it into camelbacks:


function camelBack($inString) {
	return lcfirst(str_replace(
		array(
			' ',"\
","\	","\\r",'&nbsp;'
		),'',ucwords($inString)
	));
}

Simple short common function – not a candidate for heavy modifications… why would this standalone function EVER need to be an object… or why would you put it into one? It’s USEFUL being global in scope and doesn’t need any extra overhead.

Or this function:


function isValidEmail($address) {
	if (filter_var($address,FILTER_VALIDATE_EMAIL)==FALSE) {
		return false;
	}
	/* explode out local and domain */
	list($local,$domain)=explode('@',$address);
	
	$localLength=strlen($local);
	$domainLength=strlen($domain);
	
	return (
		/* check for proper lengths */
		($localLength>0 && $localLength<65) &&
		($domainLength>3 && $domainLength<256) &&
		(
			checkdnsrr($domain,'MX') ||
			checkdnsrr($domain,'A')
		)
	);
}

Another example of there being NO reason to put it into an object or make it part of an object. You might want to call it at any point in your code for any variable, so global scope function for the win.

Again, right tool for the right job. Too often I’m seeing people wrapping the simplest of things in objects for no good reason – at the same time I see people being gun-shy of them quite often for tasks they do well…

One thing I’m going to mention is the ancestor of objects, the RECORD – which in pascal is called a record (funny that) and in C is declared as a STRUCT; PHP has similar functionality in it’s “string indexed” arrays which allow any array element to be any data type. (Am I praising something with loose/nonexistant typecasting? I guess I am.) You’ll often hear the claim that procedural involves “passing too many variables” – this claim is typically a bunch of nonsense if you wrap up those variables into complex nested arrays… To that you’ll hear the claim that “it takes too much memory as every variable passed is copied” – true enough, unless you pass that nice big array by REFERENCE. Passing by reference just makes a pointer to the original copy instead of a copy – consuming very little memory and letting in many cases procedural code have all the versatility of objects… since the data is stored in the array, and you can just pass a different array to each function.

I believe it’s important to understand all three approaches and use whichever one seems like the least code and least complex code to do the job. If it feels like you’re code is getting needlessly complex, it probably is.

As the old saying goes, the less code you use the less there is to break.