Don't allow people to break your code

I posted these thoughts on the forum of a well known open source cms, but nobody has come with a real answer. Maybe the developers are quite busy, or maybe they are not reading that subforum.

Anyway, what I suggested was a different approach when coding php. We all know that php can be used in a very dirty manner, mixing php with html and so on, but what I want to suggest does not go in that direction.

What I propose is to do meaningful and robust code. To anticipate to the possible errors which can appear when more people participates in an open source program and do not take care of being as careful as you. This usually leads to problems when classes are redefined, variables are overwritten and code gots broken because nobody knows what do the include files have inside.

So, main points I would recommend:

  • Use the include_once and require_once with the real purpose they were used.If a file needs to be included just once, why do you use a simple include? Use include_once. And if a file is a MUST for executing more code, why do you put an include? Put require. Obviously if a file must be included once, use require_once.

    I have seen several pieces of lazy written code which break easily when you mix them with code which includes the same files. Why? Because they just put include. This does not mean you can't use include, but use it where it can't harm. That is, do not use it for including functions or classes, but instead, pieces of text that change rather rarely, etc (although for this case I would recommend using templates, for example smarty).

  • Never, ever, unless you really know why you are doing it, use $GLOBALS. Function parameters were created for some reason.
  • In the same line, never, ever work with register globals =on. This is insecure, obsolete, dirty, leads to errors and definitely is ugly.
  • Prepend your own prefix to the classes you create and release to the public.For example, each time I do something for xplsv, I prepend those objects with xplsv_. This way is more complicated to have name collisions when mixing source codes from different projects. And it's specially useful for typical classes names as Utils, Text, Common, etc. All of us have created that kind of classes and do not want them to got broken because somebody else had the same idea, don't you?
  • Use classes and objects. Using classes you don't dirty the namespace so much as if you use functions. You can simply add more functionality to a project using a class which encapsulates all of those functionalities, and does not include lots of functions which you will have to rename if you decide to change your mind.It's easier to explain with an example: Imagine I want to have some functions which are useful for manipulating texts. So I have these functions: text_tolowercase(), text_removeampersands(), etc... Then you think that text is too generic, and you have to replace it for textutils.

    There you go: text_tolowercase() becomes textutils_tolowercase(), and text_removeampersands() becomes textutils_removeampersands(). Of course, you have realized that after creating a big project with those functions, so you have to replace it on every single line of code which uses those functions. And test it. Stupid waste of time, yes.

    After that, here comes Pepe Perez. He's a brilliant coder and has made more functions like yours, but unfortunately some of them collide with your functions. He put the same names, so if you want to use his code, you'll have to decide between your code or his code, or work on integrating both, or... you know.

    If you had put everything inside a class... Let's say we call it xplsv_textutils... you wouldn't have had to rename each function and fix each line of code where the functions were used, as you would have been doing something like this:

    require_once('xplsv_textutils.class.php');
    XplsvTextUtils::tolowercase($blah);
    

    And if Pepe Perez used classes, adding his class PepePerez_textutils would have been superquick.

  • Finally, if you do not trust the other coders in your project (i would suggest never trust even yourself), be careful when including files which should define a class. This would be something similar to the C++ style of including files.In the whatever.h (the header file for a class), you do something like:

    #ifndef _WHATEVER_
    #define _WHATEVER_
    (here you define whatever)
    #endif
    

    So each time a file includes whatever.h, a check is made to verify that whatever has not been defined before. This could be somehow imitated in php by checking if a class exists before including its definition:

    if(!class_exists("whatever_class" )) {
    require_once("whatever.class.php" ) ;
    }