davidmyers Posted July 16, 2010 Share Posted July 16, 2010 I'm in the process of building a modular PHP app/framework/backend to be used for websites that I create. I'm more used to writing in C++ and Java when I do OO things so I'm running into issues with PHP that I'm not used to. I have a source file for each class and my webpage (ie index.php) has an autoload function declared at the beginning to take care of including any necessary source files. Some of my source files have other classes as includes so that they can work together. For instance, Class1 includes Class2 and Class 3 also includes Class2. If index.php calls both Class1 and Class3, it gives me an error that Class2 has been redeclared. I have tried shuffling around the includes trying to see if I could get things to work, but no cigar. Obviously I am approaching this incorrectly, but this is how I'm used to handling includes and class dependencies. There must be some way that you're supposed to handle this, or maybe you're expected to keep all classes independent. Whatever the case I'm sure that someone else has run in to this problem before. Quote Link to comment Share on other sites More sharing options...
kenrbnsn Posted July 16, 2010 Share Posted July 16, 2010 Look at include_once Ken Quote Link to comment Share on other sites More sharing options...
davidmyers Posted July 16, 2010 Author Share Posted July 16, 2010 That was exactly what I needed. I used that to replace all of my standard includes in my classes and kept the autoload function in the index.php page and everything is working perfectly. Thanks for the help. Quote Link to comment Share on other sites More sharing options...
Mchl Posted July 16, 2010 Share Posted July 16, 2010 When using autoload function you shouldn't need any additional includes in class files. Quote Link to comment Share on other sites More sharing options...
davidmyers Posted July 16, 2010 Author Share Posted July 16, 2010 @Mchl I tried removing the includes from the classes and leaving the autoload function in the index.php page, but I would get an error that Class2 could not be found in Class1.php. The autoload function would load a source file, but it would only load files that are explicitly called in the index.php page where the autoload function was defined. At least that was my experience. I originally tried having the autoload function in each class and then again in the index.php page, but it gave me the error that the function was redeclared. I think I know what you mean though. The autoload function is basically an include and when you include a file, it is essentially copied and pasted into the file that includes it. Therefore the Class1.php would become part of the index.php file which has the autoload function. So the Class1 code would just utilize the autoload function. Unfortunately, something about the way PHP handles includes prevents this from being the case, at least in my experience. Perhaps, PHP evaluates the code in the included files before it evaluates the file that actually calls the include function. In that case, the Class1 code would be evaluated before it was inserted into index.php and it would not be able to utilize the autoload function. I think this is the case, but then again I've just started working with the OO aspects of PHP so I'm no expert on it. Quote Link to comment Share on other sites More sharing options...
Mchl Posted July 16, 2010 Share Posted July 16, 2010 I'm using class autolaoding at this very moment and can assure it works fine Want an example? Quote Link to comment Share on other sites More sharing options...
davidmyers Posted July 16, 2010 Author Share Posted July 16, 2010 Sure, I'd love it. Maybe I wasn't utilizing it correctly. As I said, I'm new to the OO part of PHP and I'm not very sure about PHP's behavior with many of these things. Hopefully you can show me how to only use the autoload function across all of my files. Quote Link to comment Share on other sites More sharing options...
Mchl Posted July 16, 2010 Share Posted July 16, 2010 <?php define('CLASSES_PATH', 'classes/'); //we put all our classes in this directory - a bit ugly, but for sake of example it's fine set_include_path(CLASSES_PATH.PATH_SEPARATOR.get_include_path()); spl_autoload_extensions(".php"); // only look for classes in *.php files spl_autoload_register(); //register default autoload function $ob1 = new Class1(); $ob1->useClass2(); <?php class Class1 { public function useClass2() { $obj = new Class2(); } } <?php class Class2 { public function __construct() { echo 'Hello from Class2!'; } } Quote Link to comment Share on other sites More sharing options...
davidmyers Posted July 16, 2010 Author Share Posted July 16, 2010 Ok, I'll have to give that a try. That's very different than what I was talking about though, in terms of an autoload function. The code that I have been using for autoloading is this: function __autoload($class_name) { require_once $class_name . '.php'; } The code I've been using searches for the use of any classes that the file does not have a definition for and then includes that file. Your code looks like it includes every source file that is contained within a specific location. Assuming that your code works correctly and seemingly has the end result of what I was initially trying to achieve, what are the pros and cons of each? I'm sure there are situations where one version is better than the other or reasons why both exist. What I'd like to know is which is a better or more correct way to handle includes. Can anyone give a detailed/practical comparison of the two methods? Quote Link to comment Share on other sites More sharing options...
Mchl Posted July 17, 2010 Share Posted July 17, 2010 My code uses spl_autoload as __autoload() implementation. It's just an implementation of autoloading function that comes with PHP, so that you don't have to write your own. You could change index.php to use your function instead like this: <?php define('CLASSES_PATH', 'classes/'); //we put all our classes in this directory - a bit ugly, but for sake of example it's fine set_include_path(CLASSES_PATH.PATH_SEPARATOR.get_include_path()); function __autoload($class_name) { require_once $class_name . '.php'; } $ob1 = new Class1(); $ob1->useClass2(); Your code looks like it includes every source file that is contained within a specific location. It doesn't. It includes class file if and only if there's a code instantiating a new object of given class and this class was not declared. Quote Link to comment Share on other sites More sharing options...
davidmyers Posted July 17, 2010 Author Share Posted July 17, 2010 I tried the code that you gave me and it works great. It has given me exactly what I was looking for in the first place. Thanks so much for the help. Quote Link to comment Share on other sites More sharing options...
Mchl Posted July 17, 2010 Share Posted July 17, 2010 To clarify my code a bit further, this line: spl_autoload_register(); //register default autoload function is almost doing the same as function __autoload($className) { spl_autoload($className); } Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.