With file_get_contents in PHP, what happens if I use it on the same file twice?
Is it intelligent enough to only load the file once and simply refer to the result of the first call on subsequent calls; or do I need to implement something like that myself?
In the docs it has a line that says this, but I don't really understand what it means or whether it's related:
It will use memory mapping techniques if supported by your OS to enhance performance.
I'm not sure how to prepare a test case to work this out for myself, so any information around how I could do that would also be useful.
It'll read the file twice. If you want the same content twice, put it in a variable as a matter of good practice anyways.
Related
Most examples I've seen to update text based log files seem to suggest checking that the file exists, if so load it into a big string with file_get_contents(), add your new logs onto it, and then writing it back with file_put_contents().
I may be over-thinking this, but I think I see two problems there. First, if the log file gets big, isn't it somewhat wasteful of the the scripts available memory to stuff the huge file contents into a variable? Second, it seems that if you did any processing between the 'get' and 'put', you risk the possibility that multiple site visitors may update between the two calls, resulting in lost log info.
So for a script that is simply called (GET or POST) and exited after doing some work, wouldn't it be better to just build up your current (shorter) log string to be written, and at then just before exit(), just open in APPEND mode and WRITE?
It would seem that either approach could lead to losing data if there were no LOCK on the file between get and put. In the case of file_get/put_contents, I see that method does have a flag available called "LOCK_EX", which I assume attempts to prevent that occurrence. But then there is that issue of the time taken to move a large file into an array, and add to it before writing back. Wouldn't it be better to use fopen (append) with some kind of 'lock', between the fopen() and the fwrite()?
I apologise as I DO understand that "best way to do something" questions are not appreciated by the community. But surely the is a preferred way that addresses the concerns I'm raising?
Thanks for any help.
I want to require/include a content from database record, but require/include only accepts files. This thing is related to caching, so I dont want to write anything to file (collisions etc). How to dodge it?
Are you fetching PHP code from a database? If so, you're probably doing it wrong. Ideally you should only store data inside a database, not code.
If you're fetching a PHP structure from the database, consider using a serialize()'d version of it (or json_encode()'d).
Maybe I have missed the exact purpose of what you're trying to accomplish, do let me know if I'm on the wrong path with my answer.
Whatever you do, don't rely on eval unless you really really have to; and even then, don't :)
Since others have covered eval() and the fact that this is a bad idea, I will touch on the topic of writing this "content" to a file. Use tempnam. This will give you the name of a just-created unique filename with 0600 permissions. You can then open it, write your content, close, then require/include. See Example #1 on the tempnam man page.
Make sure to check that the return value of tempnam is not false; make sure to unlink the file after you are done.
If it is code, you need to use eval(), though there are many anti-patterns that involve eval()
The manual says:
Caution The eval() language construct is very dangerous because it
allows execution of arbitrary PHP code. Its use thus is discouraged.
If you have carefully verified that there is no other option than to
use this construct, pay special attention not to pass any user
provided data into it without properly validating it beforehand.
This is very dangerous, especially if the database content was contributed from a user, but anyway you could use this :
eval($your_database_content);
Manual
Think of PHP templating.
I was recently contemplating whether it makes sense to read a template file once, storing it in memory, and then parsing it (replace placeholders with values, e.g.) rather than require-ing that file as many times as you need it. A usage scenario would be a list with list items templated as separate files. The first thoughts I had were inclined towards the former solution, because I reckon replacing values would be an easier operation than requiring the file from the file system. Later, however, I realized that pretty much all hard disk drives (or other storage, for that matter) have their own caching, and requiring the same file over and over, will not result in it being re-read each time, but rather re-served from the cache.
Any thoughts are appreciated.
I assume by "disk cache" you're actually referring to the page cache? Wikipedia: Page Cache
If so I wouldn't really be inclined to trust something like this with the performance of my application. Don't forget the page cache only uses UNUSED memory and will happily spit it back out when needed.
I would be inclined to use something like APC as an object cache, this has the great side effect of not having to actually rewrite any of your code as it's all done behind the scenes. Another possibility would be to just assign your template to a variable and constantly reuse that. Or, if you wanted to you could even use Memcache, this kind of stuff is more useful for caching database returns though, or large datasets.
Sorry for the slightly incoherent ramblings...
I was recently contemplating
That's quite wrong of you.
Groundless contemplating out of nowhere seldom does any good but most likely will put you in a trouble. Just out of nowhere.
Instead of contemplating, one have to do profiling.
Of course no to measure any changes, like H Hatfeld said, but to determine, if they need any changes at all. Most of time it turns out that you were barking wrong tree.
Profiling is the right thing to make you bark the right one.
whether it makes sense to read a template file onc, estoring it in memory, and then parsing it
For the highload(or bloated) projects it makes.
So, PHP already have such a feature, called bytecode cache. There is a plenty of the thing on the market, at our company we are using eAccelerator.
But most of time default every-request parsing is enough.
You are absolutely right about filesystem cache and parsing being blazingly fast, much faster than usual application logic, which has to be optimized at the first place.
Every time you include a file, PHP has to parse it. This penalty can be offset using an opcode cache like APC. If your templates don't contain any PHP (which it sounds like they don't), I would recommend loading the template into memory once and then re-using it as needed.
Another thing to keep in mind when looking to optimize your code is make sure you can measure the change. Use something like Xdebug to profile your code and measure what effect your changes are having.
Edit
Since the files do currently contain PHP, take a look at this question/answer. I would recommend putting a function in the file so that it only needs to be loaded once, but can be called multiple times with different parameters.
I know of these two tricks for speeding page load time up some:
#ini_set('zlib.output_compression', 1);
which turns on compression
ob_implicit_flush(true);
which implicitly flushes the output buffer, meaning as soon as anything is output it is immediately sent to the user's browser. This one's a tad tricky, since it just creates the illusion that the page is loading quickly while in actuality it takes the same amount of time and the data is just being shown faster.
What other php tricks are there to make your pages load (or appear to load) faster?
It is always better to define a real bottleneck and then try to avoid it.
The way to follow any trick that is supposed to make something faster without understanding whether you have the problem or not - is always a wrong way.
The best way is to ensure that your script isn't creating/destroying unnecessary variables and make everything as efficient as possible. After that, you can look into a caching service so that the server does not have to reparse specific parts of a page.
If all that doesn't make it as fast as you need it to be, you can even "compile" the php code. Facebook does this to support faster load times. They created something called "HipHop for PHP" and you can read about it at: https://developers.facebook.com/blog/post/358/
There are other PHP compilers you can use to help.
If all this fails, then I suggest you either recode the website in a different language, or figure out why it is taking so long (more specifically, WHAT is causing it to take so long) and change that part of the website.
There are some that can speed your website(code custmoization)
1) If you’re looping through an array, for example, count() it beforehand, store the value in a variable, and use that for your test. This way, you avoid needlessly firing the test function with every loop iteration.
2) use build in function instead of custom function
3) put JavaScript function and files at bottom of file
4) use caching
Among the best tricks to speed up PHP page loads is to use as little PHP as possible, i.e. use a PHP cache/accelerator such as Zend or APC, or cache as much as you can yourself. PHP that does not need to be parsed again is faster, and PHP that does not run at all is still faster.
The same goes (maybe even more so) for database. Use as few queries as possible. If you can combine two queries into one, you save one round trip.
If I had PHP code in the database, could I "include" that somehow in PHP and execute it?
Well, sure I could write out a file with that content and just include that file, but maybe PHP has got something similar to eval() of JavaScript?
Yes, PHP has eval() too, but it is regarded very bad practice to use it.
This question discusses the major points well, without condemning it totally.
Most often, if eval() comes up, it is worth taking a hard look at the program you're building: There is probably a better way to do it. For example, if you want to fill data values into HTML code that is stored in a data base, a templating engine of some sort might be a better idea.
Note that not using eval() but writing out a file from the db and including that will have exactly the same security risk though...the point is not so much to eval() or not to eval() the problem is: what if someone hacks into your database, and has the ability to modify the PHP code? the'd be capable of having your server run their php script, and do what ever they like.
There is eval() for PHP. But please, never-ever use it! :D
Yes!
http://php.net/manual/en/function.eval.php
You can evaluate some code using the eval function -- but it's generally considered bad practice, and a bit dangerous, to use it.
(Well, actually, it's the same function name as in Javascript ;-) -- and it's bad practice in both languages -- what a coincidence ; or not)
Another solution that is sometimes used is to :
have your PHP code in a database
fetch it sometimes (not everytime) and store it to a file, used as a caching mecanism
include that file -- which will be executed
I've seen some pretty old CMS work this way, for instance... But note they where mostly using files as cache (To not make too many requests to the DB) -- even if it worked quite well.
What about using file cache? You can always store PHP code temporarly in file and include it. Simple logic with file generation, storing in cache, including correct file and refreshing old files (md5 checksum + file cache made timestamp + modification timestamp). Then just compare both timestamps to know if cache update is needed.