tags:

views:

62

answers:

4

What I want to do is this:

When I write a class and the class instantiates another class, I want to import that class with an require_once. Just the way I do so in Objective-C. But instead of using plain require_once function and messing around with paths and string concatenation, I would prefer something like:

importClass('myclass');

but I'm afraid that it's impossible to write a function that will include code. If I would do that in the importClass() function, I would include the class code into the implementation block of the function, which of course is nonsense. So what options do I have here?

+5  A: 

The cleanest way to do what you want looks to be to use the Autoloader

Yacoby
Well, I can't use the Autoloader because I have lots of different directories where different kind of classes might be (i.e. system classes, userland classes). As far as I know, autoloader is configured to look in a specific directory. Sure one could make it search through several dirs, but that's not really what I want. Also, I don't like implicit class loading. I try to keep everything look as much as Objective-C as possible, so I don't get irritated next time I start doing Objective-C again (which I massively prefer over PHP, but that's off topic ;) )
openfrog
@openfrog you should not have a problem with class names when you are following the PEAR class name convention. See http://pear.phpmagazine.net/2006/10/advantages_of_using_the_pear_c.html
Gordon
+1  A: 

You can accomplish something similar using a class autoloader. I would also make sure that your include_path is set properly and that you are using a directory structure that makes sense for your classes - it's generally a good practice to NOT depend on class autoloaders, and instead include classes based on their relative path to your include_path.

I'd highly recommend browsing through Zend Framework, particularly Zend_Loader, for a good (if not over-architected) implementation. Also notice that Zend Framework will work without an autoloader in place - each file calls require_once on its direct dependencies, using their nice, organized directory structure.

pix0r
I'm not that sure about the part where you say that not using autoloading is a good practice : I'd rather say the opposite, actually ;; using an autoloader, you only load classes (and files) that are really necessary (better for performances) ;; it also forces you to structure your directories/files/classes well ;; and it also means you don't have to deal with include_once everywhere (and you never forget one include in one specific case)
Pascal MARTIN
That's the point of my idea, I don't want to think every time over and over again about paths.
openfrog
pix0r
Autoloader is bad style in my opinion. In languages like C or Objective-C, you include whatever you really need. Sure it can happen that you include something, use it, remove code and forget to remove the include. However if code is clean, well documented and maintained, this should not happen. PHP gives us many chances to code really dirty, and I try to circumvent this kind of stuff. If C or Objective-C doesn't have it, I don't want to use it, before I get used to it and start thinking C / Objective-C sucks.
openfrog
@Pascal I'm not sure about the performance of `require_once` vs autoload. I am fairly certain that writing code that doesn't depend on autoloading is more portable, however - thinking of a scenario in which you try to combine several pieces of software which each depend on their own autoloaders which may have different rules. I don't think that using `require_once` involves a big enough performance hit to justify your statement that using it is a bad practice.
pix0r
@openfrog : autoloading makes sure that only what you really need is actually loaded ;-) always. ;; if you are using language X, it might better to use every (useful / great) feature of language X, instead of limiting yourself to those of languages Y : else, why go through the troubles of learning a new language ?
Pascal MARTIN
@pixor : I didn't say using require_once was a bad pratice ;; I said not using autoloading might be seen as a bad practice ;-) ;; About the performance hit, I've never measured it myself, and I suppose it depends on how you are coding -- but the fact remains : autoloading allows you to load only what's really required. ;; about autoloading vs portability : well, for "external" libraries and the example your took, you may probably be true , unfortunatly -- for "internal" (i.e. provided with your application), not so sure.
Pascal MARTIN
@pixOr ZF2.0 will remove all require_once calls from the source and make autoloading obligatory. http://framework.zend.com/wiki/display/ZFDEV/Performance+-+Requiring+the+Autoloader - Doing so is already suggested in their performance guide as well.
Gordon
@Gordon thanks, I hadn't seen that. Guess that kills my argument :)
pix0r
@Pascal kinda right with that, but I only do PHP because I have no other choice. It's the only language that's really supported by hosters that are in my budget. On the other side, when I wrap my head too much around the "art of PHP", I loose my feeling for "the art of Objective-C". I earn my bread with Objective-C coding, not with PHP. So while I write a web framework for my website in PHP, I'm scared off to mess up my knowledge and intermix my hard-trained Objective-C brain-logic with PHP-style. I'll need a long break and 2 weeks of re-training therapy when I'm done with PHP ;) j/k PHP is ok
openfrog
@openfrog I go between PHP and Objective-C on a daily basis.. and while I understand your argument that there is some re-learning involved when going back and forth, I find myself bringing concepts from one language to the other more often than not. Don't be afraid to learn and use the constructs, paradigms and best practices in any language you're using! (Surprisingly, this can *even* apply to PHP) ;-)
pix0r
@openfrog You can get Ruby, Python and PHP on one host for around €3 nowadays. Why not install any readymade CMS for one of those languages and use that for your website?
Gordon
@Gordon Good point. I had developed a very special idea for a framework that isn't there yet, and I just want to make it real.
openfrog
+1  A: 

In my application I have a system base class which has a similar function. The import function takes a class name, looks in a couple of related directories and finds a matching name (I also did some stuff with extensions to libraries but you may not need that) and instantiates a class inside with the same name. Then it takes that new instance and sets it as an object in the system base class.

using autoload as other answers have suggested would probably work better in your situation but this is just another way to look at it.

Carson Myers
+1  A: 

It's not impossible at all. You can write this function:

function importClass($class) {
  require_once "$class.class.php";
}

The only caveat is that any global variables declared or used inside that file will now be local to importClass(). Class definitions however will be global.

I'm not sure what this really gives you however but you can certainly do it.

cletus
It gives me clean, logical code. Thanks man! Gonna try this.
openfrog