Fatal Error Cannot Redeclare Function II

In the previous article, we saw how to prevent an error like this one by wrapping the function in an if (! function_exists() statement.MODX logo

[code language=”html”]
Fatal error: Cannot redeclare functionname() (previously declared in
path/somefile.php:49) in path/somefile.php on line 55
[/code]

In this article, we’ll look at a better method: putting the function inside a class.

MODX logo

 

The Problem

When you put a function like the one below in your PHP code, you are ‘declaring’ it. Essentially, you are telling PHP to hang on to the function in case someone calls it. The code of the function is not executed, but rather saved for later use. If the function is never called, its code is never executed. We’ve changed the name of the function here from add() to addIntegers(). This is a good coding practice, not only because it helps prevent collisions with other functions named add(), but also because the name of the function better describes what the function actually does. This will come in handy when you’re looking at your code down the road and see that function called.

[code language=”php”]
function addIntegers ($a, $b) {
return $a + $b;
}
[/code]

 

As we saw in the previous article, PHP won’t let you declare the function more than once. If the code is used more than once on a page, PHP will throw a fatal error. In that article, we saw a quick solution that looked like this:

[code language=”php”]
if (! function_exists(‘addIntegers’)) {
function add ($a, $b) {
return $a + $b;
}
}
[/code]

 

A Better Method

Suppose someone else’s code on the same page also has a function called addIntegers. If the other developer has not wrapped the function as we did, PHP will still throw a fatal error if our code is called first. If our code is called second, or if the other developer has also wrapped the function, things are even worse. Our code might end up using the other developer’s function instead of our own, or vice versa.

If the two functions are different, this could be disastrous. Suppose the two functions add records to different parts of the database. In the worst case scenario, they would both work, but add the data to the wrong table. It might go unnoticed for a while and would be a nightmare to correct.

A much more robust, and infinitely safer, solution would be to put the function inside a class. This is not a quick solution for cases where a developer has forgotten to wrap a function. It’s a suggestion for developers who want their code to play nice with the code of others.

 

Classes

A class in PHP is an object that “encapsulates” functions and variables. Functions inside classes are usually referred to as “methods” to distinguish them from standalone functions and we’ll use that term from here on. They’re still functions, but they can only be called via the class they are declared in.

This is all much simpler than it sounds.

 

Putting our Function in a Class

In this example, we’ll add a subtractIntegers() method so you can see a class with multiple methods. To put our method inside a class, all we need to do is this:

[code language=”php”]
class MyMathFunctions {
public function addIntegers($a, $b) {
return $a + $b;
}

public function subtractIntegers($a, $b) {
return $a – $b;
}
}
[/code]

 

Now, our addIntegers() function is a method of the MyMathFunctions Class. When we want to use it, we need to create an object of the class (the technical term is “instantiate”), and call our method. That looks like this:

[code language=”php”]
$math = new MyMathFunctions();
echo $math->addIntegers(2,3);
/* Displays 5 */
[/code]

 

Our subtractIntegers() method would be called the same way. Once you’ve instantiated the MyMathFunctions object, any of its methods can be called in the same way.

The variable, $math is arbitrary, you could use any variable name here. It’s technically described as an “instance” of the MyMathFunctions object. Since it has the addIntegers() method, we can call that method as many times as we like. More important, the method can *only* be called through the class object, using the -> operator. No one can call our method without first intentionally instantiating the MyMathFunctions object, so collisions are extremely unlikely, no matter what the method (function) is called. If someone else has an addIntegers() method. They can call it with no chance of our method being called and no potential for the PHP fatal error.

Another advantage of using classes is that the class code, like that of our MyMathFunctions class, is usually put in another PHP file, separate from any code that calls its methods. If someone manages to access the class file, it will execute, but it won’t actually *do* anything. Typically, our the code in the example just above would look like this:

[code language=”php”]
include ‘mymathfunctions.class.php’;

$math = new MyMathFunctions();
echo $math->addIntegers(2,3);
/* Displays 5 */
[/code]

 

Our MyMathFunctions class code would be in the mymathfunctions.class.php file. Because MODX executes code via the index.php file, you need to include a full path to any included files, so the code above would more likely look like this:

[code language=”php”]
include MODX_CORE_PATH . ‘components/mycomponentname/model/mymathfunctions.class.php’;

$math = new MyMathFunctions();
echo $math->addIntegers(2,3);
/* Displays 5 */
[/code]

 

We’ve declared our addIntegers() method as public. That means the method can be called from outside the class as in the example above. Methods can also be declared as private or protected. Private methods can only be called from within the class itself (in other words, only by other methods in the class). Protected methods can only be called from within the class or from within descendants of the class. Our method needs to be public because we need to call it from outside the class.

In the MODX core, most methods are declared as public, even if they’re only intended to be called from within a class. This is done because it makes the classes easier to test with PHP unit tests. It’s not universal, but most methods in MODX that are intended to be called only from within the class are prefixed with an underscore like this: _methodName(). They are declared as public, but it’s generally a bad practice to call those methods in your own code.

 

Coming Up

By putting our methods inside a class, we’ve prevented the fatal error about redeclaring a function that occurs when the code is used more than once on a page. We’ve also pretty much eliminated the issue of other code containing functions with the same name. We have a new problem, however. Like functions, classes also can’t be redeclared in PHP. If our class code is ‘included’ more than once, will produce another fatal error. We’ll look at solutions for preventing that in the next article.

 


For more information on how to use MODX to create a web site, see my web site Bob’s Guides, or
better yet, buy my book: MODX: The Official Guide.

Looking for quality MODX Web Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , | Posted under MODX, MODX | RSS 2.0

Author Spotlight

Bob Ray

Bob Ray is the author of MODX: The Official Guide and over 30 MODX add-on components. He hosts Bob's Guides, a source of valuable information for MODX users, and has been very active in the MODX Forums with over 19,000 posts.

Leave a Reply

Your email address will not be published. Required fields are marked *