What will happen if same static method is called by two parallel threads?
Will it make one thread waiting or can two parallel instances of a static method exists?
Assume function don't use member variables and only use local variables.
Example:
<?php
public class ClassName{
public static function doStuff(){
// Function code goes here
}
}
?>
Assume this function is called by GET request to the server. Then if two users send a call to the URL exactly at same time, then what will happen?
See Confirmation that PHP static variables do not persist across requests for the information you need.
Standard PHP does not do any locking or waiting. It will just run the method and the 2 seperate request do not known of each other and they can't access each others memory(In the given case).
This is a race condition. It depends which request gets processed first. A http request is handled by a webserver and the webserver spawns a php process to process the php script.
Related
Hi i have a strange problem with a WordPress plugin that i am writing, but this isnt about WordPress per se and more to do with PHP so please read on so I can explain. The WordPress plugin is hooked up so that the init() function gets called... this works i can confirm it gets called once.
class MyClass
{
static $i=0;
public static function init()
{
self::$i++;
}
public static function dosomething()
{
echo 'i is = ' . self::$i;
}
}
When callinf dosomething() for the first time from within Wordpress it is ok. I then have another ajax-response.php file which includes the above class and again calls dosomething, which prints the i value = 1.
The problem is the i value when calling via the ajax-response.php script is back to 0?
Its as if it is executing in a totally different memory space and creating a new program, such that static member variables are only shared between same process as opposed to multiple web threads.
Any ideas?
Thanks in advance,
Chris
Its as if it is executing in a totally different memory space and creating a new program, such that static member variables are only shared between same process as opposed to multiple web threads.`
Exactly! :) That's 100% how this works. Each PHP request is a new one, with its own memory. The static keyword is not designed to work around that.
If you want to persist stuff across multiple processes / requests in a web application, you need to use sessions.
Ajax request is another request. That's why there are new variables
You may use session to store values between requests
You might need sessions on this one. Variables are stored in the current instance only, so if you call another script and create an instance of the MyClass class all of its properties will be set to default.
That's correct, you're variables won't stay active between different processes. Each process has it's own copy of the variable. You have many choices here.
You could use store the variable in a session if you want it to be short term storage. If you want to store it indefinitely you should store it in a database or a file.
I got a class constructor which kicks off a curl_multi and goes about downloading certain number of files and takes a few seconds to complete. Will the object instance be created only after the constructor is done with the downloads?
class Downloader {
public function __construct($download_links_array,...) {
$handle = new curl_multi_init();
...
}
}
$downloader = new Downloader( array($download_links) );
$downloader->get_item(10); // Will this be too early to call?
So the question is will the instance get created before invoking get_item() or it will the control only be returned after the instance (ie, all the downloads are completed) is created?
Thanks!
It depends. How do you download your files? synchronously or not? If you do it synchronously, then your call of the function which executes the download will not return until the files are downloaded. Otherwise, the function will return immediately and your files will be downloaded in the background (usually you need to supply a callback function that handles the event of finishing the downloads while working asynchronously).
Moreover, an object is not considered ready as long as the constructor has not finished its work. That means, that the new call won't return until the object is ready, i.e. the constructor is finished.
Combining the two sections above teaches us that if the downloading is done synchronously, the object will be ready only after downloads are finished, thus the call of get_item will be executed only after all of the downloads are finished. However, if you download your files asynchronously, then the object will be ready regardless of when your downloads are finished, and the call for get_item may be executed even before your downloads are finished.
You can read this answer which might bring you better understanding on the difference between the two (as they discuss a very simple example of executing a query which might take a long time instead of downloading files).
Note: Constructors really do not need to perform such tasks.
I have my own library class which is designed for gathering data from external web sites (uses curl). This class has constructor which receives parameters (e.g. URL, xpaths) and method updateDatabase. How to pass parameters to constructor and call method updadeDatabase in app internally? This method should be fired e.g. two times per day without user request (using the cron) So I don't want insert this code in controller and create appropriate route. How to do this?
class Source
{
public function __construct(Http $http, array $params)
{
...
}
public function updateDatabase()
{
...
}
}
Your best bet is probably to create an artisan command. This gives you access to to run your code within the Laravel framework from the command line (or cron job).
All the information you need for creating an artisan command can be found here.
Basically, inside the command's fire() method you would do something like:
public function fire() {
$source = App::make('Source'); // or however you instantiate your class
$source->updateDatabase();
// output a message to the command line
$this->info('All done.');
}
Your command can also take arguments and options from the command line, if you need to pass those in.
The documentation linked above will tell you all you need to know.
I'm currently working with an existing application that defines a couple constants on the login of a user. For example, if Alice logs in SOME_CONSTANT is defined as 1, while if Bob logs in SOME_CONSTANT is defined as 2. Now I'm trying to write a script that will do a couple of things as if it were Alice and a couple things as if it were Bob. By "as if it were" I mean that SOME_CONSTANT is defined one way for one iteration and another way for the next iteration. Unfortunately, constants are not the best at switching values and refactoring the application to change these from being constants is not an option at this time.
One method I had considered was to use pcntl_fork(). I would fork before the time the constants were defined and run a separate process for each constant. However, I would like this script to be able to run on Windows as well as Linux. At the moment the pcntl extension is not directly supported for Windows. And I'm going to try to avoid getting everything working through Cygwin if I can help it.
Another method I had considered was having the script call children scripts using exec("php childscript.php constant_value"). Will this method allow one child script to define a constant one way and another child script define it another way? I think it should, but I haven't tested it yet. Also, is there any other major problems anyone can see with this method?
Is there another method I haven't considered that would be a better choice? Thank you for your time.
As you've already noticed, using a const variable is not a viable method to handle your task. Additionally, even if you didn't need to write a script to do something with multiple users, a single instance of this wouldn't work - you would need to "set the constant" when the user logs in, which you can't do.
If you're looking for a pseudo-readonly implementation, and you are using OOP-style, you can add a private variable and override the __get magic-method. So, whenenver the outside requests SOME_CONSTANT, your class will return the value of _someFakeConstant. Then, in your login() or switchUser() method inside the class you can safely change the value.
Example:
class User {
private $_someFakeConstant = -1;
public function __get($name) {
if ($name == 'SOME_CONSTANT') {
return $this->_someFakeConstant;
}
// handle undefined variables; trigger_error() will work (see example on php.net)
}
public function login() {
// logic to "identify" the user
$this->_someFakeConstant = 1;
}
}
$user = new User();
$user->login();
echo $user->SOME_CONSTANT;
The method of using exec() to call the PHP child script appears to work fine.
Ok this seems like a stupid question that I should certainly know the answer to, but I've got some weird behavior where the constructor of one of my classes checks to see if a table exists, if not it creates it.
The strange thing is when the table doesn't exist, if the constructor is called multiple times then it doesn't see the table that should have been created on the first constructor call.
Are all function calls synchronous in PHP?
For example:
f1();
f2();
Does the interpreter wait for f1() to return before calling f2()?
Does the interpreter wait for f1() to return before calling f2()?
Yes, even if f1() kicks off other asynchronous tasks.