PHP objects that stay in memory - php

I recall reading on php.net (although unfortunately can't seem to find the page) that the PHP interpreter can run in different ways - most commonly, every time a page is requested, an instance of the PHP interpreter is created, runs its course, and then is destroyed, along with all the memory associated with that particular page call. Apparently, it is also possible to allow all the memory to linger, so that it can be used again in future page calls; as I understood it, essentially allowing multiple different PHP scripts to access and modify the same objects, without losing them after the script is complete.
Or at least, so I remember. Is there any truth to this? If so, how would I set it up?

php doesn't work that way. its about run and forget.
you can save data between requests using userland shared memory extensions, for example: apc, xcache, memcached, etc.
or by using the session data array after calling session_start
$_SESSION
don't think of php scripts like a java application in e.g. tomcat. standard php was not designed for that use case. php compiler works on-the-fly.

You can use shared memory for some of what you want, but Redis/Memcache are probably better bets.

Let the server stay between requests, so will objects do:
appserver-in-php - Generic HTTP applications approach for PHP5.3+ (inspired by Rack and WSGI)
With well written applications that gives you more speed than APC, however it doesn't scale between users if you need to put on mutliple boxes (you still can use sticky sessions).

Related

Does PHP's SyncMutex class named mutexes work across different processes on the same server?

BACKGROUND
I am using Apache and PHP to build a web application and I need to synchronize access to a region of shared memory. Since different instances of PHP have different process ID's, I am wondering if PHP's SyncMutex class with named mutexes can be used for this. Doing a Google search, I see quite a bit of information about using files as mutexes, but not much for the SyncMutex class. Not even the manual has much more information beyond the definition of the class and a few examples on how to use it.
QUESTION
Will a SyncMutex class named mutex in one process be visible in a different process?
RESEARCH
https://helperbyte.com/questions/470561/how-to-prevent-simultaneous-running-of-a-php-script
PHP mutual exclusion (mutex)
PHP rewrite an included file - is this a valid script?
Most reliable & safe method of preventing race conditions in PHP
FINALLY
The data involved is VERY transient and can change on a moment's notice (think volatile keyword in C). The data becomes useless after 30 seconds or so, and is purged periodically. For performance reasons, I'm storing it in the server's shared memory where the access is much faster than writing to a file or a database. Is this a valid use case or am I barking up the wrong tree? Should I use something else? Like a semaphore?
ADDITIONAL INFORMATION (EDIT 8/25/2021)
Upon further research, I have discovered that the pthreads module for PHP has been depreciated by the module owner several months ago and is no longer maintained. PHP is now using something called parallel to facilitate multithreading. Because of the design of the setup that I'm using, parallel is not compatible with what I am trying to do. So it looks like that I will have to use MySQL to handle this after all for right now.
My idea of using a memory server is still viable, but the server needs to be written in a language other than PHP due to the change in PHP's multithreading architecture. That will be done using C++, but not right now.
Thank you to everyone who responded.
According to the user supplied example below the documentation page for SyncMutex::unlock, SyncMutex lock created in one process is visible in another.
Additionally SyncSharedMemory class description says it explicitly:
Shared memory lets two separate processes communicate without the need
for complex pipes or sockets. [...] Synchronization objects (e.g. SyncMutex) are still required to protect most uses of shared memory.

Is there a way to define constants that persist in memory when PHP loads?

Is there a way to define constants that boot into memory when the PHP process starts on the server? If so, can it be done with arrays, classes, and functions as well?
Before people start listing the different ways of declaring things that will be available across pages and scopes: I'm not asking this from a coding convenience, but rather a performance perspective.
It seems like a waste to keep loading things that never change, from pages or databases etc, on every script execution. Being a server-side process, I would think PHP has some way to read things into memory once and have them always available.
What you are looking for is an opcode cache. Opcode caches work by storing the compiled contents of PHP files in shared memory, then using that data to short-circuit the standard code parsing process when the file is included/required in the future.
The canonical opcode cache at this point is the PHP opcache extension, but a number of other opcode caches exist, including APC and XCache.
Opcode caches do not cache data from databases. There are other extensions which you can use to assist in this process, though, such as APCu which stores them in shared memory, or memcached which stores them in an external process. None of this is automatic, though, as caching data from a database requires some application knowledge to know what is useful to cache, and to handle cache invalidation when you update the database.
In general php is a single treaded environment and it does not actually run constantly (unlike java). Php starts working only when receives a command to do so. Then it parses the code into opcode and eventually executes it. And that technically happens on every request (or CLI command).
However, there are several ways how you can cache the opcode with not much efforts with APC: http://www.php.net/manual/en/book.apc.php

Is it possible not to load the bootstrapping mechanism at every call?

This is not a PHP question, but my expertise is with PHP frameworks.
A lot of frameworks have a bootstrapping (loading of classes and files) mechanism. (Drupal, Zend Framework to name a few)
Everytime that you make a request, the complete bootloading process needs to be repeated. And it can be optimized using APC by automatically caching some intermediate code
The general question is:
For any language, is there any way to not load the complete bootstrapping process? Is there any way of "caching" the state (or starting at) at the end of the bootstraping process to not load everything again? (maybe the answer is in some other language/framework/pattern)
It looks to me as extremely inefficient.
In general, it's quite possible to perform bootstrap / init code once per process, instead of having to reload it for every request. In your specific case, I don't think this is possible with PHP (but my knowledge of PHP is limited). I know I have seen this as a frequently criticism of PHP's architecture... but to be fair to PHP, it's not the only language or framework that does things this way. To go into some detail...
The style of "run everything for every request" came about with "CGI" scripts (c.f. Common Gateway Interface), which were essentially just programs that got executed as a separate process by the webserver whenever a request came in matching the file, and predefined environmental variables would be set providing meta information. The file could be basically any executable, written in any language. Since this was basically the first way anyone came up with of doing server-side scripting, a number of the first languages to integrate into a webserver used the cgi interface, Perl and PHP among them.
To eliminate the inefficiency you identified, the a second method was devised, which used plugins into the webserver itself... for Apache, this includes mod_perl for Perl, and mod_python for Python (the latter now replaced by mod_wsgi for Python). Using these plugins, you could configure the server to identify a program to load once per process, which then does the requisite initialization, loads it's persistent state into memory, and offers up a single function for the server to call whenever there is a request. This can lead to some extremely fast frameworks, as well as things such as easy database connection pooling.
The other solution that was devised was to write a web server (usually stripped down) in the language required, and then use the real webserver to act as a proxy for the complicated requests, while still serving static files directly. This route is also used frequently by Python (quite often via the server provided by the 'Paste' project). It's also used by Java, through the Tomcat webserver. These servers, in turn, offer approximately the same interface as I mentioned in the last paragraph.
The short answer is: in PHP there's no good way to skip the bootstrapping. (Technically you could run a PHP service 24/7 that ran forked children to handle requests, but that's not going to make your life any better.)
A good framework shouldn't do much in bootstrapping. In my personal one that I use, it simply registers an autoload function for classes, loads the config settings from MemCache, and connects to a database.
At that point, it parses the request and sends it to the proper controller / action. While creating the new router object every time is a "waste," the actual process of handling the request needs to be done regardless if the bootstrapping process is magically "cached" between requests.
So I would measure the time it takes between starting the page and getting to the action method to see if it's even a problem. If the framework is doing expensive things related to configuration and class loading, you should be able to minimize that via storing the end results in memcache.
Note that you should always be using an opcode cache (e.g. APC) and a persistent SAPI (e.g., php-fpm) in production. Otherwise, there is a lot of overhead with starting up and shutting down.
I would suggest you to look into FastCGI and C/C++ interface if you want to handle multiple requests. Usually it brings many problems (such as data caching / flushing, memory leaks etc), but can raise performance 10-100 times.
PHP is more suitable for web interface, and if you need fast-processing then you can write a persistent handler.
Also take a look at Java / Tomcat, Python and mod_perl. Some people have also suggested xcache.
For the PHP frameworks they do need to support a multi-request structure in the core, and I'm not aware of any framework doing that.
However said that, I'd love to have a project which would let PHP script to respond to multiple requests inside a loop. Not simultaneously, but bypassing the initialization.
Also you can take a look at https://github.com/kvz/system_daemon, and http://gearman.org/.

cache methods in php?

what are the available cache methods i could use in php ?
Cache HTML output
Cache some variables
it would be great to implement more than one caching method , so i need them all , all the available out there (i do caching currently with files , any other ideas ?)
Most PHP build don't have a caching mechanism built in. There are extensions though that can take care of caching for you.
Have a look at APC or MemCache
If you are using a framework, then most come with some form of caching mechanism that you can use e.g. Zend Framework's Zend_Cache.
If you are not using a framework then the APC or Memcache as Pelle ten Cate mentioned can be used. The correct approach to use does depend in your situation though, do you have your website or application running on more than server and does the information in the cache need to be shared between those servers? (if yes then something like memcache is your answer, or maybe a database or distributed NoSQL solution if you are feeling brave).
If you code is only running on the one server you could try something simple like serializing your variables, and writing them to disk, then on every request afterwards, see if the files exists, if it does, open it and unserialize the string into the variable you need.
This though is only worth it if it would take a long time to generate the varaible normally,
(e.g longer than it would to open,read,unserialize the file on disk)
For HTML caching you are generally going to get the most mileage from using a proxy like Varnish or Squid to do it for you but i realise that this may not be an option for you.
If its not then you could the write to disk approach i mentioned above, and save chunks of HTML to files. look in the PHP manual for ob_start and its friends.
Since every PHP run starts from scratch on page request, there is nothing that would persist between calls, making cacheing moot.
Well, that's the basic view. Of course there are ways to implement a caching, sort of - and a few packages and extensions do so (like Zend Extensions and APC). However, you should have a very close look whether it actually improves performance. Other methods like memcache (for DB results), or switching from PHP to e.g. Java will often yield better results.
You can store variables in the $_SESSION, but you shouldn't keep larger HTML there.
Please check what you are actually trying to do. "Bytecode cacheing" (that is, saving PHP parsing time) needs to be done by the PHP runtime executable. For cacheing Database (SQL) request/reply-pairs, there is memcache. Cacheing HTML output can be done, but is often not a good idea.
See also an earlier answer on a similar question.

How to persist objects between requests in PHP

I've been using rails, merb, django and asp.net mvc applications in the past. What they have common (that is relevant to the question) is that they have code that sets up the framework. This usually means creating objects and state that is persisted until the web server is recycled (like setting up routing, or checking which controllers are available, etc).
As far as I know PHP is more like a CGI script that gets compiled to some bytecode each time it's run, and after the request it's discarded. Of course you can have sessions, to persist data between requests from the same user, and as I see there are extensions like APC, with which you can persist objects between requests at the server level.
My question is: how can one create a PHP application that works like rails and such? I mean an application that on the first requests sets up the framework, then on the 2nd and later requests use the objects that are already set up. Is there some built in caching facility in mod_php? (for example that stores the compiled bytecode of the executed php applications) Or is using APC or some similar extensions the only way to solve this problem? How would you do it?
Thanks.
EDIT: Alternative question: if I create a large PHP application that has a very large set up time, but minor running time (like in the frameworks mentioned above) then how should I "cache" the things that are already set up (this might mean a lot of things, except for maybe the database connections, because for that you have persistent connections in PHP already).
To justify large set up time: what if I'm using PHP reflection to check what objects are available and set the runtime according to that. Doing a lot of reflection is usually slow, but one has to do it only once (and re-evaluate only if the source code is modified).
EDIT2: It seems it's APC then. The fact that it caches bytecode automatically is good to know.
Not sure if APC is the only solution but APC does take care of all your issues.
First, your script will be compiled once with APC and the bytecode is stored in memory.
If you have something taking long time to setup, you can also cache it in APC as user data. For example, I do this all the time,
$table = #apc_fetch(TABLE_KEY);
if (!$table) {
$table = new Table(); // Take long time
apc_store(TABLE_KEY, $table);
}
With APC, the task of creating table is only performed once per server instance.
PHP (and ruby for that matter) are interpretive languages. That is they parse the files each time they are requested and I suppose you could say are converted to a pseudo byte code. It is more 'apparent' one could say that PHP is more like this than say RoR but they both behave the same way.
The feature of persisting data between requests is a feature of the server not of the language itself. For example, the RoR routing you speak of is in fact cached but that's cached in the server's local memory. It isn't compiled and stored for faster readins. The server (and by server I mean both the box & the web service instances) restarts this information is gone. The 'setting up the framework' you speak of still involves parsing EACH file involved in the framework. Rails parses each file during the request again and again, the production level features may in fact cache this data in memory but certainly in development it does not. The only reason I mention that is because it illustrates that it's a feature of the server not the language.
To achieve the same thing in PHP you could use Zend Server. As far as I know this is the only PHP interpreter that will 'compile' and use byte code when told to. Otherwise you'll need to find a way to store the data you want to persist over requests. APC as you mentioned is a very powerful feature, a more distributed one is Memcached and then of course there's more persistent forms like disc & sql.
I am interested in knowing why you'd like this particular feature. Are you noticing performance issues that would be 'solved' by doing this?
I think you're making some incorrect generalizations. All of those frameworks (ex: Rails) can be run with different configurations. Under some, a process is created for every request. This obviously hurts performance, but it shows that these frameworks don't rely on a long-running process. They can set things up (reparse config files, create objects, etc.) every request if needed.
Of course, mod_php (the way PHP is usually used) runs inside the web server process, unlike CGI. So I don't see anything fundamentally different between CakePHP (for example) and Rails.
I think perhaps you are looking for something like Python's WSGI or Ruby's Rack, but for PHP. This specifies an interface (independent of how the language is run) for an application. For a new request, a new instance of an application object is created. As far as I know, this does not exist for PHP.

Categories