I'm writing an app in modular way, so I can possibly reuse some of the components. I've also written utility functions that are shared among different components. For example, if I have classes A (in A.php), B (in B.php), and C (in C.php), and a function f (in utils.php), and this function is used in both A, B, and C, how does one organize the code?
For testing purposes, I run A.php, B.php, and C.php separately, so I need to include utils.php in all of them. Is doing require_once 'utils.php' in all three files a good solution? I've heard there may be a minor performance issue with using require_once. Or should I maybe write a separate 'test.php', whre I would import all the files I need, and use that code for testing instead of writing tests in actual class files?
First of all, require_once is certainly not "too" slow for running your tests. Remember, premature optimization is the root of all evil. Yes, it has some overhead, but unless it causes errors or slows down your production environment, don't bother. Measure, measure measure.
A good strategy that i tend to use is similar to the one of Zend Framework.
My classnames are based on my directory structure. For example, a class named Http_Client_Curl would be lokated in the following directory:
Http/Client/Curl.php
With a structure like this, it's very easy and convenient to use auto loading. See spl_autoload_register. This means that you can let PHP automatically include all files and classes as you need them, based on a pretty straight forward convention.
If you are speaking in terms of PHP 5.3, I believe namespaces and auto-loading would fit right into your application fairly well. On the other hand, legacy code tends to be organized into "libraries" or "includes" with a core "includes.inc.php" that uses the factory method, or various other design pattern, to load the classes.
If you’re programming object oriented you’d also put the function f into a class; a utils class in your utils.php file.
require_once may have a minimal hit on performance as it will have to remember and check if a file has already been included, but it’s the best way to include files, to make sure you have the files you need. You can then include all the dependencies of that file/class.
Tests should of course not be in your class files. I don’t quite get if all your classes are for testing now or if you’re testing your classes …
Regarding require_once:
Yes, it has some performance issues. When you are sure you are including the file only once, don't put it, it's an unnecessary check.
Some advices:
Try to use absolute_path when calling require
The time difference between require_once() vs. require() is typically not that significant, with the exception of a very large application that has hundreds of require*() calls, which case it really is slow
Use an opcode cache, like APC!
Related
I am creating a PHP website and it contains several sections, I was wondering is it safe to keep all of my functions in 1 file and then include it in every other file?
It would certainly make things easier for me but do you think it's a good idea? In both security aspects and speed. Because if I keep all my functions in a single page it would definitely become quite big, and I wouldn't be needing a lot of them in a lot of pages, so, wouldn't it affect my script's speed?
And do you think it's wise to keep all of them together? Aren't I just making it easier for hackers to find the core of my script? What do you suggest I should do?
Big, long functions files were (and still are, to an extent) pretty common in PHP projects.
Security of all files should certainly be a consideration, but a single functions file is no different from any other, really. Best practice is to keep it outside of your web root so that if PHP fails (it happens), your file still won't be accessible. If the server gets hacked, the location and format of your files is unlikely to make any difference.
Modern frameworks typically include hundreds of different files on every page load. The extra time this takes is barely measurable and probably not worth thinking about.
For maintainability, it's rarely a good idea to have one massive file. You should look at separating these into utility classes and autoload them as needed.
Security-wise, it is safe as long as the file is kept under the right permissions.
It is not the best practice, and I guess you should take a look at php's autoload
Security has nothing to do with the size of file.
You just need to make it inaccessible (which you can do it by .htaccess) and hidden by public (keep it outside of the web root)
And, what about the speed ?
I think it's nicer to get the files organized as specific as possible.
If there are many of tiny functions, you can organized it by its shared characteristics (maybe string functions, array functions, etc)
The time overhead is very very small and can be negligible.
And, I think maintainability is much more important than that negligible performance difference.
I'm looking into methods of reducing maintenance downtime for a certain application.
One thing I could do, is make use of anonymous functions in a way that allows me to re-include a file with a new function definition during runtime. That way the application behaviour can be patched at runtime.
I'm wondering if there are any frameworks out there that would be helpful in implementing this behaviour on a large scale through out an application.
I'm thinking it could help with things like keeping track of which functions are loaded from which files, when/how often to reload them and similar tasks.
I'll leave this open for now, but since I can't find anything at this time, I've started my own project: PHP - Reloaded
I've read a lot of articles about ZF performance and still can't understand, if I've enabled byte-code caching (APC), does it make sense to use some other tricks? E.g. disabling autoload and using one big php-file with all necessary classes instead.
I was surprised to find that this is the only question on the site tagged performance, autoload, php. What a better place than this to dispel the #1 autoload myth:
Modern, well-designed autoloaders won't break APC (or PHP 5.5's OPcache), and are not any worse for performance than require_once (except for the function call overhead, of course).
Why? Well, now we have spl_autoload_register, which lets you add multiple autoload handlers. This allows each third party library to ship it's own autoloader that knows how to load that library's files, and skip the rest.
For example, Zend Framework 1's Zend_Loader_Autoloader restricts itself to trying to load classes that start with a specific pseudo-namespace -- Zend_ (and anything else the user asks it to load). If it doesn't start with the desired pseudo-namespace, it simply returns and lets the next loader on the stack run. It also knows that it can find Zend_Foo_Bar_Baz in Zend/Foo/Bar/Baz.php, so it doesn't need to search the include path by hand. Like other modern framework autoloaders, it follows the the PSR-0 autoloading standard.
Any dependencies installed via composer also get automatically built namespaced autoloaders in the same way.
It's that include path scouring that makes poorly-designed autoloaders suck. You generally don't see these in modern PHP code. The intense filesystem stat calls that result from trying to find files are a frequent performance drag. Check out this presentation by PHP creator Rasmus Lerdorf, in which he increases the performance of Wordpress through benchmarking, profiling, and careful removal of slow operations like stat calls.
The require_once-everything-up-front from the olden days is is unnecessary when you're using modern libraries and don't have a sucky autoloader. It's only a major win when you disable apc.stat if you're using APC, or fiddling with OPcache's validate_, revalidate_, and enable_file_override INI options if you're using OPcache.
tl;dr: Unless you know that statting include files is your largest bottleneck, the Zend autoloader is just fine, and you don't need to resort to a require_once fest.
I can imagine that in larger projects some things tend to get redundant in most PHP scripts. From the top of my head: Including classes, authentication, including a configuration file, setting include path etc.
As far as my imagination has run, this should be done in absolutely every PHP script in the project. This would then be simplified by adding a "core" PHP script that handles all this.
However, from this very site, I can quote
"I am planning on creating a PHP file "core.php" that will be included at the top of EVERY SINGLE PHP file in the project. This file will handle authentication and include base functions. Thoughts?"
I cannot stress enough 'do not do this'. There is a rule among experienced PHP developers that any project with a large core.php file that it's a warning sign of bad development and should be best avoided.
Source
Which leaves me at a loss. Is it better to redundantly write the same 20-30 lines of code on top of every file than to embrace DRY coding?
Any clarification would be appreciated!
I'll quickly clarify here. The "Front Controller pattern" which I actually use when writing most websites and applications does not really fit the type of project I'm talking about. Well actually it does, and I already intend to use it, but my project also contains a lot of PHP scripts that should return content for Ajax requests. It is those PHP scripts that my question regards.
I recommend taking the same approach as Wordpress, the Front Controller pattern.
Basically it filters all incoming page requests through index.php. Open up .htaccess and you can see that it filters all requests through index.php unless the file or directory already exists. This allows you to parse the URL into sections in any syntax you would like. No need to make different files for different URLs. You can receive example.com/page/1 and map the section at the end to any page.
Kohana is a great library to attempt to understand and master this concept. It lets you extend classes and implements tons of PHP 5 features. As an added bonus Kohana is MVC (also HMVC) which is incredibly important for large sites.
I do not believe that answer was against DRY, even though it does not make it easy to see. The author did suggest using an established framework, which most certainly takes care of initialization and common application backend features in a centralized and modular manner.
Possibly the author meant "do not produce a homegrown big spaghetti ball of code"; this might be in practice an ill-conceived attempt to building a framework by bunching a boatload of core methods in a monolithic script.
If building (at least in a big part) to learn, I find nothing wrong with trying to centralize your core functions, organize them and start producing a fledgling framework in such a way. Doing this in a thoughtful manner will gain you invaluable practical experience and insight into how applications in general can be architected. Otherwise, I will side with the author of that answer: why have your application suffer from possibly wrong design decisions when there are many fantastic frameworks ready for use?
If you need to include 20-30 lines on top of every page, it sounds like it's time for a better architecture. Look into Dispatching/Routing for example. Every request is handled by a central .php file, the Dispatcher, which parses the request and decides which files need to be invoked and loaded.
This is implemented in most PHP frameworks. Play around with one to get a feeling for it.
Q1)
I'm designing a CMS (-who isn't!) but priority is being given to caching. Literally everything is cached. DB rows, DB id queries, Configuration data, processed data, compiled templates. Currently it has two layers of caching.
The first is a opcode cache or memory cache such as apc, eaccelerator, xcache or memcached. If an entry is not found in there it is then searched for in the secondary slow cache, ie php includes.
Are the opcode caches actually faster than doing a require_once to a php file with a var_export'd array of data in it? My tests are inconclusive as my development box (5.3 of XAMPP) keeps throwing errors installing any of the aforementioned programs.
Q2)
The CMS has numerous helper classes that are autoloaded on demand instead of loading all files. Mostly each has a require before it so no autoloading needs to take place, however this is not the question. Because a page script can have up to 50/60 helper files included I have a feeling that if the site was under pressure it would buckle because of all the i/o that this incurs. Ignore for the moment that there is output cache in place that would remove the need for what I am about to suggest, and also that opcode caches would render this moot. What I have tried to do is join all the helper files required for the scripts execution in one single file. This is achievable and works well, however it has a side effect of greatly increasing the memory usage dramatically even though technically the same code is being used.
What are your thoughts and opinions on this?
Using a compiler cache like APC should help out as it will take your helper files and cache them after they are converted to opcode. That will mean the files will not only be cached but already in opcode so they do not need to be parsed and compiled each time they are required.
Looks like you just have no idea what you want to cache (and why).
You just cannot compare "opcode cache" and "require_once". Opcode cache will cache required code as well as other code.
First, keep in mind that your operating system will cache files in memory if they are being accessed frequently enough.
Also, don't use require_once. It is significantly slower than require. If you aren't using an autoloader, you should be. There is no reason to be manually including files in a modern php application (very few exceptions).
50-60 helper files is crazy. Isn't there some way to combine these? Can't you put them all in a related helper class, like OutputHelper or CacheHelper? That way you only have to include the class, which, again, should be taken care of your autoloader. It sounds to me you're doing something like putting one function per file.
Opcode caching greatly reduces memory usage and execution speed, but I'm not sure what effect it has on require statements.
I agree with ryeguy. require_once is slower than require or include because it has to log every include and check against it. If your only doing one require/include (which you should be for classes) then you don't need require_once or include_once.
Autoloading is great for optimization. As you only will load in classes when needed. So if your app has 500 classes, but only needs 15 to run a certain page/script. Then only those 15 get loaded. Which is nice.
If you take a peak at any big framework. You will notice that they have migrated to using autoloaders. They use to use require_once at the last moment like this example from the Zend Framework Version 1.
require_once 'Zend/Db/Exception.php';
throw new Zend_Db_Exception('Adapter name must be specified in a string');
Zend Framework Version 2 is going to be using auto loaders instead. I believe this is the fastest and it's also the easiest to code for.