Getting data from forked children - php

I am playing with pcntl_fork() in PHP.
I took the class that is written in the second comment, and tried to send data to it - which seems to work fine.
Now I did some processing on that data, and would like to receive some results in my parent process.
Does anyone know how this can be done ? The only way I can think of doing this is to store the information in the database and/or other storage.

Having worked with pcntl fork in a number of projects i do not believe there is any way to send data back to the parent process directly. You would be able to do this via the database as you have already mentioned however you may be better off using PHP's shared memory components (http://php.net/manual/en/book.shmop.php) or memcache for this purpose.
Can you elaborate on what you are doing, it may be that you can avoid this requirement.

Related

PHP multithreaded cURL alternative proposed, but is it good?

Because PHP doesn't have multithreading capabilities I am trying to find a workaround to speed up a simple process.
The process is I am posting data to a webpage with various permutations in the post-data on each request. In a foreach loop I am checking each request response to see if a string exists using strspos. When it is found, it breaks and returns the page. There are around 1000 requests, and it takes bout 1 minute to complete or longer.
As I don't want to use additional libraries, my idea was to exec standalone scripts passing each permutation of post data (say 1000 processes). Each process will only write to a file if the string is found. And on the main script I will run a loop checking if file exists, when it does find that the file exists, can read the file for the post data that was correct.
It seems sound in theory, but I wanted to check if this is a ridiculous solution for a problem that has much simpler solutions!
Thanks.
One solution is using process control library
http://php.net/manual/en/book.pcntl.php
I don't know if you have support for them installed

Is there a way in PHP to use persistent data as in Java EE? (sharing objects between PHP threads) without session nor cache/DB

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.

PHP Request Lifecycle

Okay, so I'm relatively naive in my knowledge of the PHP VM and I've been wondering about something lately. In particular, what the request lifecycle looks like in PHP for a web application. I found an article here that gives a good explanation, but I feel that there has to be more to the story.
From what the article explains, the script is parsed and executed each time a request is made to the server! This just seems crazy to me!
I'm trying to learn PHP by writing a little micro-framework that takes advantage of many PHP 5.3/5.4 features. As such, I got to thinking about what static means and how long a static class-variable actually lives. I was hoping that my application could have a setup phase which was able to cache its results into a class with static properties. However, if the entire script is parsed and executed on each request, I fail to see how I can avoid running the application initialization steps for every request servered!
I just really hope that I am missing something important here... Any insight is greatly apreciated!
From what the article explains, the script is parsed and executed each time a request is made to the server! This just seems crazy to me!
No, that article is accurate. There are various ways of caching the results of the parsing/compilation, but the script is executed in its entirety each time. No instances of classes or static variables are retained across requests. In essence, each request gets a fresh, never-before execute copy of your application.
I fail to see how I can avoid running the application initialization steps for every request servered!
You can't, nor should you. You need to initialize your app to some blank state for each and every request. You could serialize a bunch of data into $_SESSION which is persisted across requests, but you shouldn't, until you find there is an actual need to do so.
I just really hope that I am missing something important here...
You seem to be worried over nothing. Every PHP site in the world works this way by default, and the vast, vast majority never need to worry about performance problems.
No, you are not missing anything. If you need to keep some application state, you must do it using DB, files, Memcache etc.
As this can sound crazy if you're not used to it, it's sometimes good for scaling and other things - you keep your state in some other services, so you can easily run few instances of PHP server.
A static variable, like any other PHP variable only persists for the life of the script execution and as such does not 'live' anywhere. Persistence between script executions is handled via session handlers.

Caching JSON data

I've never really cached data before, but I feel as though it will greatly improve my site.
Basically, I pull JSON data from an external API that helps the basic functionality of my website. This info doesn't really change that often yet my users pull the info from the API thousands of times a day. If it updated once a day, that would be fine. I want to run a cron job daily that will pull the info and update the cache.
I already tried a few different things, both pulled using PHP:
1) Store data in an SQL table
I had it working, but there's no reason why I should ping the database each time when I can just store it in basic HTML/JSON.
2) .JSON file (using fwrite)
I had it stored, but the only way this worked is if the .getJSON() callback function is prepended to the JSON data and then the data is surrounded by parentheses (making it jsonp, I believe).
Does anyone have any advice or any directions to lead me in? As I said, I've never really done anything like this so I don't even know if I'm remotely headed in the right direction.
Edit:
Okay so I talked to my hosting and since I'm on a shared hosting (dreamhost) I can't install memcached, which sucks. The only info they could give me was that if it is on http://pecl.php.net/ then I can most likely use it. They said APC is available. I'm not sure if this fits my problem. I'd like to be able to access the cache directly in jQuery. Thanks
You can use memcached. Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering. Very easy to implement and has a low system footprint.
Since you can't use memcached, go back to your database option and store it in a table using the MEMORY engine.
try memcached. You can easily generate a string key and store whatever blob of json you want with it. works like a dictionary, except persists in memory.
There's an option to give it an expiration time (otherwise it just stays cached forever). So when the user requests the data, just check if it's stored in memcached. If it is, great, return it. If it's not, do whatever you do to build it, then put it in memcached with a 24 hour expiration.
If your data varies per user:
I've done this by storing an object in the $_SESSION array.
I attach a quick bit of logic that determines if the data expiry period is up. If so, it draws new data, serves and caches. If not, it draws from $_SESSION and serves it up.
Try Redis.
And to store data easily without unexpected errors on set/get - encode it using base64.
this to store:
file_put_contents($path, $json_text);
and this to restore:
$json_text = file_get_contents($path);
echo $json_text;
echo can be used to pass the json exactly as it comes from the http request. if you need to parse it into a variable (in javascript) you can use array = JSON.parse('<?php echo $json_text; ?>');. if you need to parse in php, use $array = json_decode($json_text);.

What happens to a class in PHP once its been instantiated?

I'm just playing around with some PHP and was wondering what happens when an object from a class is created within another PHP script?
I assume once its created and been processed their is no way of then going back and 'playing' around with it from another script?
The idea is i'm trying to create a kind of deck of cards using a card class, each card has specific data that is added to each individual object to make it unique, suit, value etc. Once its created i need to be able to go back to specific cards to use them. In java i'd have an arraylist of card objects, i'm not sure how to approach the same area in PHP.
Thanks.
There is no problem passing objects around inside a php script, your problem is that php is that the webserver calling the script is essentially "stateless". i.e. every time someone posts the url from a browser a complete fresh copy of the php program is fired up.
To save data between times there are several options:-
One is to use $_SESSION variables which are associated with a user session but $_SESSION itself is an array so it gets really clumsy holding complex structures here, also , it sounds like you want to share the deck between users.
You could serialise your object and store it in a file -- which is OK as long as its not updated very often -- but if its updated by every user they will start overwriting each others changes.
Much better is to store the deck in a database (SQLITE is usually built into php) so that several users can share and update in a controlled manner.
Another good option would be to use one of the popular data caches such as "memcached" which will cache the data between calls to the script.
To reuse an object between page calls seems to be your issue. Maybe you can serialize the object and store it in database and pick it up back?? Check php.net/serialize Let know how it goes.
What you could do to keep the objects available to you is to serialize the objects and store them in a database table. If you link a game ID or something similar to the cards then you can retrieve them later using this game ID.
I don't know if the cardgame you are writing is realtime, using a database might be too much overhead. Another possibility is to use an existing caching solution, like for example Memcache.
So you want to create a serverside coded cardsgame? Good luck!
It is possible to do this, tho I think a script like a javascript you are talking about is much more suitable.
You could make a function that initialises a deck of cards and work with indexes etc. Save your things in cookies / sessions and work with postbacks. It's gonna be a hell of a job tho in my opinion compared to jscript.
Tho when you think about it, you could use ajax to make this game feel better for the user :).
Php scripts are not like Java server apps.
Where your Java server will run for a long time, your php script will just be a one time thing.
Instead of this kind of process : user make a request to Java-run server, server receive the request in one of it's infinite loops, server process it, server send the response, server wait for new request; you have this kind of thing : a webserver (Apache, Nginx, whatever other webserver) receive the user's request, understand it needs to be interpreted by php, starts a php child, this child do what's in the script, send its answer, dies, the server wait for new requests.
So, when a php script ends, nothing (in good case) is left from it.
But, a php script can use persistent storage on the server so another request can read from it. That's why you have files, databases and even shared memories functions.
If the games state is for one user only, you can use sessions (usually files) to store your deck object. If it's meant to be used by multiple players, you should store it after serialization in a database.

Categories