Reputation: 53
I have a VERY labor intensive PHP script, which does several api calls to a server elsewhere. I need to run this script to keep certain data on my server, synchronized with data on the remote server.
I want this script to start every time a specific type of user visits a specific page.
My problem is however, if a user that is qualified goes to this page, page load-time is REDONCULOUS, even though the data the script processes, doesn't effect the page itself in any way.
So, what i was wondering is, how can i run this script using the same conditions, but run it only on my server?
In other words, how can i run this script and stop the browser from waiting for its output?
EDIT: useful information: Using XAMPP for Windows, PHP 5.5, Apache 2.4.
EDIT 2: Using curl seems to be the best option, but it doesn't want to actually run my script.
Here's the call:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://localhost/tool/follow/PriceTableUpdate.php');
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);
curl_exec($ch);
And here is the actual PriceTableUpdate.php:
<?php
ini_set('max_execution_time', 3600);
$marketData=simplexml_load_file("http://www.eve-markets.net/api/xml?listid=20158key=JKgLjgYvlY6nP");
foreach ($marketData->marketList->type as $type) {
$ItemID = (int)$type['id'];
$ItemBuy = $type->buy->price;
$ItemSell = $type->sell->price;
$ItemMedian = $type->median->price;
mysqli_query($con,"UPDATE piprices SET `ItemBuyPrice` = $ItemBuy, `ItemSellPrice` = $ItemSell, `ItemMedianPrice` =$ItemMedian WHERE `piprices`.`ItemID` = $ItemID");
}
?>
EDIT 3: Using the above DOES work, in case anyone ever wants to ask this question again. You have to remember though, that since you are using curl, the php file no longer uses variables you've set before, so you will need to define your database connection in the php file again.
Upvotes: 4
Views: 6712
Reputation: 53
Using the curl function display in the OP, i got it to work. I forgot to add mysql connection details, which i didn't need before ( when using include ).
Upvotes: 0
Reputation: 46365
You can probably make a separate call to your php script with the onLoad
event - that is, you wait until the page is loaded, then call this other script "in the background". The latter can be done with the following lines of code (I found this by following a link http://www.paul-norman.co.uk/2009/06/asynchronous-curl-requests/ posted by @Gavriel in a comment to one of the other answers):
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.yoursite.com/background-script.php');
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);
curl_exec($ch);
curl_close($ch);
?>
Adding this code anywhere in your page should cause the script to be executed without delay for the page load - you won't even need to use a onLoad
event in that case.
Upvotes: 2
Reputation: 3572
There are a couple ways. One, you can fork the execution:
<?php
# only works if pcntl_fork is installed on POSIX system
# will NOT work on windows
# returns new child id
$pid = pcntl_fork();
if ($pid == -1) {
die("could not fork\n");
} else if ($pid) {
$my_pid = getmypid();
print " I am the parent. pid = $my_pid \n";
pcntl_wait($status); //Protect against Zombie children
} else { # child pid is 0 in child
$my_pid = getmypid();
print " I am the child. pid = $my_pid \n";
}
# example output
# I am the parent. pid = 23412
# I am the child. pid = 23414
Or, fork the process at the OS system level (with command &
, assuming you are running PHP on linux/unix). So, PHP may be used to execute a shell script.
Also, some people have suggested Ajax, though you need to be careful to consider the case where multiple scripts can be fired off at the same time. What will this do to load on the server, and resource locking? There probably also needs to be some locking logic to ensure only one script is executing at a time, along with a 'heartbeat' that lets you know if the process is alive or dead.
Upvotes: 0
Reputation: 4357
You should separate the browser-request from the background-data-request.
When the user does the access, then create an item in a message-queue server. put required data within that message. let the queue executed from the same/different machine.
if you are not split the request, you webserver worker process stays alive until php has full executed you script. the also say, blocking the browser. you can "flush" the current output, but server still wait until php is ready to close the browser connection.
Upvotes: 1
Reputation: 2441
Have a long running, background, process that processes jobs from a queue; something similar to beanstalkd.
When this process comes across a job named, for example, 'sync.schizz' it will start your sync . Now you just need to pop a job into the queue when your special visitor swings by - which will be lightning fast.
Upvotes: 0
Reputation: 19237
If I understand what you want to do, then one possible solution is to run the other php in another thread. In php you can do this by calling it via curl: http://php.net/curl
Upvotes: 2
Reputation: 22698
Why not using AJAX in this? When the page loads and meets your specific conditions, make an AJAX request to the server and start the script without waiting for a response back to the browser.
Upvotes: 4
Reputation: 1494
Try to use exec() function
If your server is a unix-like os, terminating your command with & will launch the command and won't wait the end of it exec('./mylongcommand &');
Never tried this, but it should work...
Upvotes: 0