I have a website that has about 150 require_once calls in a "catalog" page. Each page calls require_once on this catalog to make sure all necessary files are loaded. Calling require_once on this catalog takes somewhere between 5 and 15 seconds, and I have no easy way to reduce the number of classes each page needs.
So: is there any way to speed up this process? I assume it will need to be done once, but I also assumed it would be cached for the session, which doesn't seem to be the case since this 5-15 second overhead is the same on every single page load.
Hopefully this makes sense.
Thanks!
The idea behind require_once is to make sure:
You don't have the file more than once.
Make load times faster so that the file isn't included again.
PHP stores in memory what files have already been loaded. If you call require_once on a file and then call it again, PHP won't even look for the file, it'll see that it's already been loaded and won't bother to read the file.
This makes me think that require_once isn't the culprit of your page load issues.
However, I may be misunderstanding the question. If you mean that each require_once is different, then that's another story. IF they are used to load classes, check out the PHP autoload function. PHP: Autoloading Classes. This will only load the classes that are called upon.
My first guess would be that you have some logic defined in one of your required scripts. If they were all just class definition files, there's no reason requiring them would take 5-15 seconds.
Is there some reason you're including every class on every page? You should look into autoloading classes instead, if possible.
Related
I'm testing some database related functions in interactive mode.
The first thing I did is to include the testing file, let's say database.php
Then I can make change to the database by a function call.
The question is, when I make any changes to database.php, I have exit PHP interactive mode, re-enter, include the testing file again.
I'm seeking a way to reload the include file during the interactive mode.
There is no simple method of doing this cause PHP is not built for this job, but there are some things you can take a look at as it might do the job for you. However this all depends on what is in your database.php.
Create a simple function like reset and use PHP's runkit functions to update your include.
If your database.php contains functions, you need to remove the functions before including it again. If your file has a class defined in it you could try the import function and just call the function that does all this for you but in the end this is all manual labor and it might be simpler to look at other alternatives.
I for one use a auto refresh timer in my browser to refresh the page every # seconds. However I have two screens which makes using this method much easier.
That is something you should never do. It will create double functions, which will create confusion in the PhP interpreter.
You should require files out of your scope, so they are globally available, That way you can reduce the server overhead (memory usage) and reuse the included class directly without requiring it again.
Or you could create an autoloader, which imports the file when needed. If it is already there, it will return the needed instance without the extra overhead. An autoloader keeps track of the already included or required files.
That said, with include or required, you could load files. Instead of required_once or include_once, they keep including files.
I have several classes in PHP. All separated in files. (class1.php, class2.php)
On my site, I have included them all together, so I can use all of them.
Now, when I use jQuery Ajax to get data from the database I have to call another file (like getData.php)
But on this file, I have to include all of the classes (or at least some) again. So every time I want to receive data from the database, it loads all classes again(I think). The problem is, that they're not that small and they are still growing. That's bad, I think.
Is there a way to avoid this? So that I include the classes only once.
step one: only include the files you need. How? using an autoloader (and a system that can easily determine what file contains which class, like Classname.class.php or something) will help: If you call new yourClass() the autoloader will load the file, but only that file.
Now you have a minimal set of files loaded. This set will not get smaller, as you are actually using the files. What you can do is speed stuff up by
using APC. Your PHP files get 'cached' and they don't need to be re-parsed again and again.
use other forms of cache, like memcached: save certain data in memory so you don't need anything other then your memcache-class loaded (heck, you won't even hit your database anymore for these requests :) )
require and include have the variations require_once and include_once. They prevent the script from loading a file multiple times.
I think I can safely assume, because the functions exist, that there would be cases where you would need the require/include function instead of the require_once/include_once one. But I cannot imagine a case like that. What would that be?
Probably the best example would be when giving output. If, say, you had a snippet of HTML that might appear more than once on various pages, you could put it into a separate file and include it as many times as you wanted.
Moreover, it's often unnecessary to use require_once or include_once. If the file will only be called once (e.g. in __autoload) then the simple functions have less overhead, because PHP doesn't need to keep track of whether the file has been included before.
One may want to use require_once instead of require if you want to have a variable or constant defined only once. This is helpful for making reusable classes in a very large code base that manages dependencies rapidly. Lets say I have a file A that needs a file B but I already include file C that included file B. Since file B was already included, the program does not have to evaluate that code again to properly evaluate file A. This is a case where you may want to include the file only once.
It helps with managing your dependencies
In my project structure I have the usual class per file separation and auto-loading is easy, but now I would like to group some small classes in a a single file, probably a file with the name of the current folder.
now:
|/module
|-Smallclass1.php
|-Smallclass2.php
|-Smallclass3.php
|-Normalclass.php
after:
|/module
|-module.php <-- smallclasses go here
|-Normalclass.php
Now comes the debate.
To autoload one 'SmallclassX' I was thinking to check if SmallclassX.php file exists if not check if module.php exists and if so, check if the class exists inside the file and include it. Including the whole module.php file when I need a single class seems an overhead specially if the file contains many classes. Here they suggest using tokens the check if the class exists, but I'm not sure about it's efficiency, after that I'll need a method to include only the class I need.
Do you think if I get to load only the class I need like I mentioned, will it be also an overhead because of reading the file more that once and looking inside to include the piece of code I want?
You can stack autoloaders using spl_autoload_register, allowing you to first attempt to load the class from a dedicated file, then falling back to including the module file afterwards (and if no autoloader can solve the dependency, error out normally). This will allow you to avoid all hacks by parsing tokens and other items, which will require a lot more than just require-ing the file and seeing what the result is afterwards.
I would however advice you to benchmark this solution. Whether it's more effective will depend on the delay for accessing the files (APC) and the cost of parsing and including each class seperately.
I'll also agree with the other comments, it might be confusing that you have two separate schemes for including classes, and APC will remove most of the cost of having separate files anyway.
I've discovered the __autoload function today and after reading the official manual page of this function there's a point I don't get at all.
What's clearly the difference between using __autoload() and let's say require_once?
because it looks autoload is the new fashion way of doing the required includes but to me it's far better to use require_once instead. Hence, __autoload has to be defined into all the php files which means writing its code down there, if I put ALL my includes/require_once/...etc into one file let's call it main_header.php then all I'll need to do in my web app files is write one line of code:
<?php require_once('main_header.php'); ?>
Am I wrong somewhere?
I can see two things going for autoloading (not necessarily __autoload; prefer the more modern spl_autoload_register instead):
You don't need to explicitly include the classes. Of course, you could make a main_header.php as in your example, but then the next item comes into effect.
You don't have to load 100 classes if you are only going to use 10 of them.
It's also worth to point out that autoloading is also triggered when unserializing an object of a class that has not been yet defined, which makes things infinitely more practical. Of course there is another hook in unserialize for this (the configuration setting unserialize_callback_func), so autoloading is not technically necessary. It's definitely nicer though.
First: Use spl_autoload_register() instead of __autoload().
The autoloader is called, when you try to access a class, that doesn't exists. With include() you just include a class. The main difference is, that using an autoloader the class is only included, if its really required/used.
Usually you define an autoloader in one file and include this one on every request. If you use bootstrapping (meaning: a single file, that catches every request and redirects it to the appropriate target) its only required to define the autoloader there. So its its not required to define it in every file.
Autoloader is used for lazy initialization. It's the most effective with MVC architecture, not with websites that include a file here and there and define db connection string in every file (which is terrible).
Using autoload with MVC framework saves resources and brings a lot to modularity. Since you don't have to include files with classes, you just instantiate a class you require in the controller you're currently at.
Basically, it's an OOP thing. You shouldn't worry about it if you're not using object approach to structuring your website and include/require is what will work for you.
I think it comes down to personal preference. For me, autoload is a typical php kind of thing - a dirty "magic-quotes"-alike hack, that only exists because they don't bother to sit down and code a clean solution to the problem - in this case, an adequate packaging system + a catchable ClassNotFound exception. Until we've got this fixed, I'll stick to include.
Choose the right tool for the job. Autoloading is for loading the source-code of yet undefined Classes prior use. So you can instantiate classes you have not required the files for so far.
This makes sense if you work with classes and you want to require files at a central place, a single point instead all over in different files.
But if you're using includes and requires to let's say build a website with menu and footer, this does not make sense. Autoload does not work for this:
<html>
<head><title>Reciepes collection - My Homepage</title></head>
<body>
<?php include('header.html'); ?>
<h1>My Reciepes collection</h1>
<p>Cooking is one of my favorite hobbies .... (</p>....)
<?php include('footer.html'); ?>
</body>
</html>
If you're making use of requires to load functions, you can not use autoload either.
So only because autoload looks somewhat fancied by others to you, it does not mean that it fits your needs.
I personally use it in projects where I do not want to take care of the requires for classes and where I want to be able to dynamically load classes from within a modular directory and library structure.
I only make use of spl_autoload_register() to register one or more autoload implementations. It's the recommended method to register an autoload function in PHP as it allows to have multiple autoloaders.
All the answers are more than correct and adequate. I just thought I should add my two cents.
First, *_once functions are slow. Do not use them.
Secondly, in an app I am developing, I have lots of classes which I rely on each other and I do not always know which classes are needed in a page.
Instead of creating a main.php page and including all the classes which are a lot; obviously wasting resources and time (Include and require are expensive), I use autoload to include those files as and when they are needed by the page.
All I do therefore is code and the classes are added automatically.
This also improves your code and directory structure since you follow a system in naming your classes and files.
Just an addition. In terms of resource usage and speed(decreasing order of requirements and increasing order of speed):
Require_once() ; include_once() ; require() ; include()
Making include the best and fastest.
Autoload and the include family functions both have their place.
Autoload is intended for lazy loading of modules in an OO based script (namely classes and interfaces) and is invoked when you use new or statically call a method of a class that hasn't yet been loaded. This triggers autoload to run a function that attempts to load (typically via include) the class or interface in question. The advantage of this approach is that classes are only loaded as and when they are needed. Any class that doesn't get used doesn't get loaded.
Autoload cannot be used for loading program fragments that aren't a class or an interface, for those items you still need the include family.
As for having to add an autoload function to every script that needs to autoload? In this case you put the autoload function in its own file and include it in the scripts that need to autoload. :)
Another note: include and require may become a big pain while unit testing.
I don't know how should I prevent requiring / including anything. There is test helpers, that can do some useful things, such as preventing exiting or dieing, but they still cannot mock include or require.
Mockery library recommends using autoloading to be able to mock public static methods.