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 :) )
Related
I'm building a website for a client, and he wishes to have a calculator for clients to calculate their monthly premium when they want to lease a car. This calculator appears in three different places in the website, so I decided to build it once, then include() the file into the main file. For instance:
case 'calculator':
case 'bereken-leasebedrag':
include('calculator.php');
break;
However, I have several classes defined in the main file:
use site\database\Vote;
use site\database\Vehicle;
use site\database\VehicleType;
use site\utils\ApiConnect;
use site\utils\Calculator;
And some more.
Some of these classes are used by the calculator file, such as Calculator and Vehicle and a few others. These classes are defined in the main file, but are not transferred to the calculator file, whereas variables like $_SESSION, $_POST and even my own defined variables like $car and $calc are available in the included file.
If I don't re-declare my classes at the beginning of calculator.php, it throws a fatal error in the page, saying it can't find, for instance, the class ApiConnect.
Am I doing something wrong here? Logically speaking, included files should inherit pretty much everything, and it seems counter-productive to have to specify every class needed for the included files.
I'm terrible at explaining things, so if I need to elaborate on something, I'd be more than happy to.
Thanks to deceze, I learned that use is used for aliasing, something I didn't derive from my Google searches.
Apparently the autoloader automatically includes all the classes we have, we just manually apply aliasing for every class. Which is kind of weird, but there you go.
Long story short, I had to either apply aliasing in the included file so that I could just say new Calculator(), or remove the aliasing and change every new {CLASS}() to new \{PATH}\{TO}\{CLASS}. I personally went with the first option, but if you have an autoloader and are running into thesame problem, at least you have a choice.
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.
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 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.
I am working on code re-factoring of configuration file loading part in PHP. Earlier I was using multiple 'ini' files but now I plan to go for single XML file which will be containing all configuration details of the project. Problem is, if somebody wants configuration file in ini or DB or anything else and not the default one (in this case XML), my code should handle that part.
If somebody wants to go for other configuration option like ini, he will have to create ini file similar to my XML configuration file and my configuration manager should take care everything like parsing, storing in cache. For that I need a mechanism lets say proper interface for my configuration data where the underlying data store can be anything( XML, DB, ini etc) also I don't want it to be dependent on these underlying store and anytime in future this should be extensible to other file formats.
Assuming you're wanting to use a class to handle all this, you have 3 options:
Have a base class called something like, ReadConfigurationBase then 3 implementation classes, ReadConfigurationXML, ReadConfigurationINI, and ReadConfigurationDatabase and you'd have to choose the right one
Same as above, but using a factory to choose, based off of something passed in. Like if you pass config.xml it would know to return ReadConfigurationBase implemented using ReadConfigurationXML
Have a class called ReadConfiguration and it acts as step 2, but creates, contains, and owns, the 3 other classes.
The 3 non-base classes would simply know how to read that type of configuration file, and pass the information back in a generic manner. think along the lines of an interface: You know you can get the data, but you don't care how.
I'd suggest option 3, since it would make life easiest. You would have to do a little bit of modification every time you want to add a storage method, but that would just be adding a little bit into the ReadConfiguration class.
There is a way you could make it 100% dynamic, but that would complicate matters, and I don't think you really need it for this.
Have a look at Zend_Config. It provides adapters for Arrays, Xml and Inis. Like all components in Zend Framework, it can be used isolated from the remaining Framework. Even if you don't want to use it, it's well designed and you might get a few ideas for your own config manager from it.