I am tweaking a zen-cart website to be more cpu efficient. After profiling it, I see that the getimagesize function is accounting for nearly 50% of page load time. The images are locally stored. One option is to go through zen-cart's source code and replace this function with something custom to reference a cached value since images are rarely ever changed. However, since php is open source, perhaps another option is available: Is there any way to modify this function to make it just read a value from a cache which I can set whenever I upload an image to the server? Maybe by adding an optional parameter to the function that makes it read from cache.
Interesting idea, but this would require recompiling PHP. While not impossible, it's probably not a good idea from a maintenance point of view: You would have to re-integrate your patch on every PHP update.
However, you might be able to override getimagesize(): There seem to be PHP modules and libraries that can add this capability to PHP.
I have no experience with any of them, but here are some suggestions on how to do it:
PHP - override existing function
Override default php function (the namespaces idea is clever, but probably won't work in your case)
Related
Im working on a website that shows products.
The site is written in PHP.
to make it easier to maintain, I created a php code for the "product" item with thumbnail, price, etc.
I would like to know if it is hard on Disk IO to put an include file inside a foreach. Let say the array counts about 200 items.
foreach($wines AS $wine):
require 'components/wine.php';
endforeach;
Are we still ok or there will have some hosting issue?
Thanks!
Answer
Regarding your question though, its probably Ok with the disk. Files imported using require() are also cached in precompiled bytecode the same way as the main file (if you have OPCache or any cache system enabled), so PHP wont read it from disk every time you include it.
Recomendation
I would not recommend that approach at all. I think a more recomendable approach would be to define a function that returns or displays whatever you want to show, then require the file once and call the function between the loop.
I see many downsides in your approach, like:
Its a bad practice, it couples your code because now this file can only be included in this file. It becomes required that the contents of the file are aware of the file that its including it, making it harder to maintain and more prone to errors in the future.
It can arise problems in the future, eg. if someone declares a function inside the file, it would cause a crash as requiring the file twice would redeclare the function leading to an error
It will cause some overhead in the execution, as PHP perform some validations and operations when a file is included
If you want more information about require or OPCache I link documentation below
https://www.php.net/manual/en/function.include.php
https://www.php.net/manual/en/intro.opcache.php
Assume I have a system in PHP that involves class discovery.
The result of the class discovery is cached for performance.
Now I had the idea to attempt to clear or invalidate the cache, if the code changes. Either because a developer did something, or because a new version of a 3rd party library was downloaded.
One idea would be to compare file hashes for the class file. But doing this with e.g. md5(file_get_contents($file)) seems rather costly, and not something we want to do in every request / process.
Is there another, faster way to get hash for a PHP class, that produces a different result if the code changes?
I imagine that the answer is no, but one can always ask and hope.
I think you can use filemtime function to get the last modified of the file instead of checking the content of the file.
Sorry if it's not what you want to.
Is there a way in PHP to use "out of session" variables, which would not be loaded/unloaded at every connexion, like in a Java server ?
Please excuse me for the lack of accuracy, I don't figure out how to write it in a proper way.
The main idea would be to have something like this :
<?php
...
// $variablesAlreadyLoaded is kind of "static" and shared between all PHP threads
// No need to initialize/load/instantiate it.
$myVar = $variablesAlreadyLoaded['aConstantValueForEveryone'];
...
?>
I already did things like this using shmop and other weird things, but if there is a "clean" way to do this in "pure PHP" without using caching systems (I think about APC, Redis...), nor database.
EDIT 1 :
Since people (thanks to them having spent time for me) are answering me the same way with sessions, I add a constraint I missed to write : no sessions please.
EDIT 2 :
It seems the only PHP native methods to do such a thing are shared memory (shmop) and named pipes. I would use a managed manner to access shared objects, with no mind of memory management (shared memory block size) nor system problems (pipes).
Then, I browsed the net for a PHP module/library which provides functions/methods to do that : I found nothing.
EDIT 3 :
After a few researches on the way pointed out by #KFO, it appears that the putenv / setenv are not made to deal with objects (and I would avoid serialization). Thus, it resolves the problem for short "things" such as strings or numbers but not for more large/comples objects.
Using the "env way" AND another method to deal with bigger objects would be uncoherent and add complexity to the code and maintenability.
EDIT 4 :
Found this : DBus (GREE Lab DBus), but I'm not having tools to test it at work. Has somebody tested it yet ?
I'm open to every suggestion.
Thanks
EDIT 5 ("ANSWER"):
Since DBus is not exactly what I'm looking for (needs to install a third-party module, with no "serious" application evidence), I'm now using Memcache which has already proven its reliability (following #PeterM comment, see below).
// First page
session_id('same_session_id_for_all');
session_start();
$_SESSION['aConstantValueForEveryone'] = 'My Content';
// Second page
session_id('same_session_id_for_all');
session_start();
echo $_SESSION['aConstantValueForEveryone'];
This works out of the box in PHP. Using the same session id (instead of an random user-uniqe string) to initialize the session for all visitors leads to a session which is the same for all users.
Is it really necessary to use session to achieve the goal or wouldn't it better to use constants?
There is no pure PHP way of sharing information across different
threads in PHP! Except for an "external"
file/database/servervariable/sessionfile solution.
Since some commentators pointed out, that there is serialize/unserialize functionality for Session data which might break data on the transport, there is a solution: In PHP the serialize and unserialize functionality serialize_handler can be configured as needed. See https://www.php.net/manual/session.configuration.php#ini.session.serialize-handler It might be also interesting to have a look at the magic class methods __sleep() and __wakeup() they define how a object behaves on a serialize or unserialize request. https://www.php.net/manual/language.oop5.magic.php#object.sleep ... Since PHP 5.1 there is also a predefined Serializable interface available: https://www.php.net/manual/class.serializable.php
You can declare a Variable in your .htaccess. For Example SetEnv APPLICATION_ENVIRONMENT production and access it in your application with the function getenv('APPLICATION_ENVIRONMENT')
Another solution is to wrap your variable in a "persistent data" class that will automatically restore its data content every time the php script is run.
Your class needs to to the following:
store content of variable into file in __destructor
load content of variable from file in __constructor
I prefer storing the file in JSON format so the content can be easily examined for debugging, but that is optional.
Be aware that some webservers will change the current working directory in the destructor, so you need to work with an absolute path.
I think you can use $_SESSION['aConstantValueForEveryone'] that you can read it on every page on same domain.
Consider to refer to it's manual.
I'm a little confused here.
I know that for every PHP request, the entire application is bootstrapped all over again.
Given this, how can a cache be effective, if all of the globals are reloaded for each and every request?
For example:
User calls URI/user/view/123. User 123 is loaded from a database and stored in $user.
Why would you cache the contents of $user - when you merely need to refer to the variable in order to get the contents?
Am I missing the point?
Thank you,
Its more like caching images, common database querys
For instance say your site has a lot of articles and each article has categories. And say you dont change categories very often, then using a cached result of a query of the categories table is preferable then doing the query. this is a simplified example.
Another example is with images, if your site needs like thumbnailed version of user photos that they have uploaded instead of having php use the GD library to rescale the image and etc just save a version of that thumbnail version and use it instead of running through the GD code again.
As always, an image is worth a thousand words, here it is :)
(source)
As you can see, you reload some PHP librairies (like the basic environment (Globals, Requests, Cookies, etc), but not everything (in this case, Security, Application, various libraries, Views).
You skip what can be cached ;)
I've worked on a CMS which would use Smarty to build the content pages as PHP files, then save them to disc so all subsequent views of the same page could bypass the generation phase, keeping DB load and page loading times down. These pages would be completely standalone and not have to run in the context of another script.
The problem was the instance where a user first visited a page that wasn't cached, they'd still have to be displayed the generated content. I was hoping I could save my generated file, then include() it, but filesystem latency meant that this wasn't an option.
The only solution I could find was using eval() to run the generated string after it was generated and saved to disc. While this works, it's not nice to have to debug in, so I'd be very interested in finding an alternative.
Is there some method I could use other than eval in the above case?
Given your scenario, I do not think there is an alternative.
As for the debugging part, you could always write it to disc and include it for the development to test / fix it up that way and then when you have the bugs worked out, switch it over to eval.
Not knowing your system, I will not second guess that you know it better than I do, but it seems like a lot of effort, especially since that the above scenario will only happen once per page...ever. I would just say is it really worth it for that one instance to display the initial page through eval and why could you not be the initial user to generate the pages?