PHP interval timing - php

I have a problem, I'm running a script and the PHP line duplicates to whatever number $num_newlines equals. This is what I am currently using:
for ($i=1; $i<=($num_newlines - 1); $i++) {
$tweetcpitems->post('statuses/update', array('status' => wordFilter("The item $array[$i] has been released on Club Penguin.")));
}
What I want to do is have 90 second intervals between however many duplicates are made. So I'm not tweeting like 50 times within 10 seconds. What I want to do is add a 90 second interval between each tweet, please help!

Use the sleep() function:
for ($i = 1; $i <= $num_newlines - 1; $i ++) {
$tweetcpitems->post('statuses/update', array('status' => wordFilter('The item ' . $array[$i] . ' has been released on Club Penguin.')));
sleep(90);
}
This snippet sleeps after every tweet, also after the last one. To prevent sleeping unnecessary after the last tweet, use this:
for ($i = 1; $i <= $num_newlines - 1; $i ++) {
$tweetcpitems->post('statuses/update', array('status' => wordFilter('The item ' . $array[$i] . ' has been released on Club Penguin.')));
if ($i <= $num_newlines - 1) {
sleep(90);
}
}

Two options:
If you can set up CRON jobs - create a queue of messages to post (in a database or file) and let a script run every 90 seconds that takes and removes one message from the queue and sends it.
Use sleep function inbetween sending messages. Note that you may need to increase the time limit (from the comments: under Linux, sleeping time is ignored, but under Windows, it counts as execution time).

Related

Limiting a for loop

So I'm having a small problem with a piece of my code, I have a system that is adding checkpoints to a program and I want it to add a checkpoint every 14 mins, but I also want to limit it to only add x amount of checkpoints based on how many hours a course as. So for an example, the first course has 12 hours so I only want 12 checkpoints created, but it's creating 16 based on the $time_in_secs, so that variable will always be different as its check the time between the start and end date of the program. For the second program, it has 24 hours but its creating 33 checkpoints and so on and so forth. $checkpoint_limit is what I want to limit the for loop by, but I still need it add the 840 as that is the time in seconds and I need a checkpoint created every 14 mins
I have done a few different things but none of them seemed to work. Tried setting a min() also tried doing an if but also does not seem to work.
$checkpoint_limit = (abs($numHours) * 3);
//840 = 14 minute interval * 60
for ($i = 840; $i < $time_in_secs; $i += 840) {
//Code here that adds the checkpoints
}
In for loop check for no of checkpoints created and if they exceed $checkpoint_limit then break the loop.
Try:
$checkpoint_limit = (abs($numHours) * 3);
$no_of_checkpoints = 0;
//840 = 14 minute interval * 60
for ($i = 840; $i < $time_in_secs; $i += 840) {
//Code here that adds the checkpoints
$no_of_checkpoints++;
if($no_of_checkpoints > $checkpoint_limit){
break;
}
}
Use a second condition inside for loop with && operator.For example;
$j=0
for($i=840;$i<$timeInSecs && $j<12;$i +=840)
{
//example code here
$j++
}
I am sorry for the low quality answer i am using SO mobile and could not manage to post the code.So j variable is like a checkpoint time.You have added 14 minute checkpoint and what i get is u want it to loop for a specific count you can do it with that way.And you should increase $j in the end of the for loop.

run php script exactly every 2 second

i have one php file that i want to run every 2 second for a 1 minute. because in my server i can set min cron for 1 minute only. so i made this script.
<?php
$start = microtime(true);
set_time_limit(60);
for ($i = 0; $i < 59; ++$i) {
shell_exec('/usr/local/bin/php /usr/local/www/my_file.php');
time_sleep_until($start + $i + 2);
}
?>
and second option is.
<?php
for ($i = 0; $i <= 59; $i+=2) {
shell_exec('/usr/local/bin/php /usr/local/www/my_file.php');
sleep(2);
}
?>
but both of them are not working because my script execution time is 50 to 60 second. so, its not running every 2 second but every 50 to 60 second. so, is there any solution for that to start new script execution every 2 second? i don't have any idea please help me.
You can write a bash script which executes your php script every 2 seconds for defined amount. And this bash script can be executed via cronjob.
Example:
#!/bin/bash
count=10
for i in `seq 1 $count`; do
/bin/php /path/to/scrip.php &
sleep 2
done

Why php threads are sequential not parallel on my localhost?

I want to use pthread in php to do some tasks in parallel. I have installed pthread on xampp on win10 and I just copied some examples from websites but the result of all of them is sequential instead of parallel!
One example from http://www.smddzcy.com/2016/01/tutorial-multi-threading-in-php7-pthreads/:
<?php
class SomeThreadedClass extends Thread
{
private $tID;
public $data;
public function __construct(int $tID)
{
$this->tID = $tID;
$this->data = $tID . ":" . date('H:i:s');
}
public function run()
{
echo $this->tID . " started.\n";
sleep($this->tID);
echo $this->tID . " ended. " . date('H:i:s') . "\n";
}
}
$threads = [];
for ($i = 1; $i < 5; $i++) {
$threads[$i] = new SomeThreadedClass($i);
$threads[$i]->start(); // start the job on the background
}
for ($i = 1; $i < 5; $i++) {
$threads[$i]->join(); // wait until job is finished,
echo $threads[$i]->data . "\n"; // then we can access the data
}
The result on the website is:
1 started.
2 started.
3 started.
4 started.
1 ended. 18:18:52
1:18:18:51
2 ended. 18:18:53
2:18:18:51
3 ended. 18:18:54
3:18:18:51
4 ended. 18:18:55
4:18:18:51
When I run the code on my localhost, I get this result:
1 started.
1 ended. 13:11:24
2 started.
2 ended. 13:11:25
3 started. 3 ended. 13:11:26
4 started. 4 ended. 13:11:27
1:15:41:23
2:15:41:23
3:15:41:23
4:15:41:23
Why threads are sequential not parallel on my localhost?
The threads are executing in parallel. You can tell that by looking at the times being output. All threads start at the same time, and they each finish just 1 second between each joined thread. Given that the sleep time is being incremented on each new thread being spawned, the time gap between each thread finishing would incrementally increase if they executed sequentially.
For example, changing the thread spawning and joining part of your script to the following (to force sequential execution):
for ($i = 1; $i < 5; $i++) {
$threads[$i] = new SomeThreadedClass($i);
$threads[$i]->start(); // start the job on the background
$threads[$i]->join(); // wait until job is finished,
echo $threads[$i]->data . "\n"; // then we can access the data
}
Would output something similar to:
1 started.
1 ended. 15:14:06
1:15:14:05
2 started.
2 ended. 15:14:08
2:15:14:06
3 started.
3 ended. 15:14:11
3:15:14:08
4 started.
4 ended. 15:14:15
4:15:14:11
Notice the different start times and the incremental gaps between the finish times.
As for why you are receiving the output in that sequence, it is simply how the output buffer is handling the output from multiple threads. My output is different, but then I'm using OS X.

No output from the loop

I'm iterating over a huge array and it involves querying multiple APIs so to avoid data loss and timeout, I'm doing this:
for ($i = 0; $i < $count; $i++) {
if ($i % 100 == 0) {
echo 'processed: '.$i."\n";
// save to file
}
}
... it works if the loop is a few hundred iterations during test and outputs processed ..., but nothing at all in prod environment during the script is running, it echos everything only after its done. I just want to avoid any timeouts incase it takes (and usually does) long.
PHP output is buffered; see here. If you flush the buffer (or turn buffering off), you'll see it happen in real-time.
As "belt and braces", if you really care about the output, I'd echo the $count before you even enter the loop.
what is the aim of this code block?
well, until $i reaches 100, it is waste of resource anyway..
you can try:
if( $count > 100 ) {
ini_set('max_execution_time', 0); // no time limit
// $count contains at least $i times 100
for($i = 1; $i <= $count / 100; $i++) {
echo $i * 100;
}
}

Project Euler || Question 10

I'm attempting to solve Project Euler in PHP and running into a problem with my for loop conditions inside the while loop. Could someone point me towards the right direction? Am I on the right track here?
The problem, btw, is to find the sums of all prime numbers below 2,000,000
Other note: The problem I'm encountering is that it seems to be a memory hog and besides implementing the sieve, I'm not sure how else to approach this. So, I'm wondering if I did something wrong in the implementation.
<?php
// The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
// Additional information:
// Sum below 100: 1060
// 1000: 76127
// (for testing)
// Find the sum of all the primes below 2,000,000.
// First, let's set n = 2 mill or the number we wish to find
// the primes under.
$n = 2000000;
// Then, let's set p = 2, the first prime number.
$p = 2;
// Now, let's create a list of all numbers from p to n.
$list = range($p, $n);
// Now the loop for Sieve of Eratosthenes.
// Also, let $i = 0 for a counter.
$i = 0;
while($p*$p < $n)
{
// Strike off all multiples of p less than or equal to n
for($k=0; $k < $n; $k++)
{
if($list[$k] % $p == 0)
{
unset($list[$k]);
}
}
// Re-initialize array
sort ($list);
// Find first number on list after p. Let that equal p.
$i = $i + 1;
$p = $list[$i];
}
echo array_sum($list);
?>
You can make a major optimization to your middle loop.
for($k=0; $k < $n; $k++)
{
if($list[$k] % $p == 0)
{
unset($list[$k]);
}
}
By beginning with 2*p and incrementing by $p instead of by 1. This eliminates the need for divisibility check as well as reducing the total iterations.
for($k=2*$p; $k < $n; $k += $p)
{
if (isset($list[k])) unset($list[$k]); //thanks matchu!
}
The suggestion above to check only odds to begin with (other than 2) is a good idea as well, although since the inner loop never gets off the ground for those cases I don't think its that critical. I also can't help but thinking the unsets are inefficient, tho I'm not 100% sure about that.
Here's my solution, using a 'boolean' array for the primes rather than actually removing the elements. I like using map,filters,reduce and stuff, but i figured id stick close to what you've done and this might be more efficient (although longer) anyway.
$top = 20000000;
$plist = array_fill(2,$top,1);
for ($a = 2 ; $a <= sqrt($top)+1; $a++)
{
if ($plist[$a] == 1)
for ($b = ($a+$a) ; $b <= $top; $b+=$a)
{
$plist[$b] = 0;
}
}
$sum = 0;
foreach ($plist as $k=>$v)
{
$sum += $k*$v;
}
echo $sum;
When I did this for project euler i used python, as I did for most. but someone who used PHP along the same lines as the one I did claimed it ran it 7 seconds (page 2's SekaiAi, for those who can look). I don't really care for his form (putting the body of a for loop into its increment clause!), or the use of globals and the function he has, but the main points are all there. My convenient means of testing PHP runs thru a server on a VMWareFusion local machine so its well slower, can't really comment from experience.
I've got the code to the point where it runs, and passes on small examples (17, for instance). However, it's been 8 or so minutes, and it's still running on my machine. I suspect that this algorithm, though simple, may not be the most effective, since it has to run through a lot of numbers a lot of times. (2 million tests on your first run, 1 million on your next, and they start removing less and less at a time as you go.) It also uses a lot of memory since you're, ya know, storing a list of millions of integers.
Regardless, here's my final copy of your code, with a list of the changes I made and why. I'm not sure that it works for 2,000,000 yet, but we'll see.
EDIT: It hit the right answer! Yay!
Set memory_limit to -1 to allow PHP to take as much memory as it wants for this very special case (very, very bad idea in production scripts!)
In PHP, use % instead of mod
The inner and outer loops can't use the same variable; PHP considers them to have the same scope. Use, maybe, $j for the inner loop.
To avoid having the prime strike itself off in the inner loop, start $j at $i + 1
On the unset, you used $arr instead of $list ;)
You missed a $ on the unset, so PHP interprets $list[j] as $list['j']. Just a typo.
I think that's all I did. I ran it with some progress output, and the highest prime it's reached by now is 599, so I'll let you know how it goes :)
My strategy in Ruby on this problem was just to check if every number under n was prime, looping through 2 and floor(sqrt(n)). It's also probably not an optimal solution, and takes a while to execute, but only about a minute or two. That could be the algorithm, or that could just be Ruby being better at this sort of job than PHP :/
Final code:
<?php
ini_set('memory_limit', -1);
// The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
// Additional information:
// Sum below 100: 1060
// 1000: 76127
// (for testing)
// Find the sum of all the primes below 2,000,000.
// First, let's set n = 2 mill or the number we wish to find
// the primes under.
$n = 2000000;
// Then, let's set p = 2, the first prime number.
$p = 2;
// Now, let's create a list of all numbers from p to n.
$list = range($p, $n);
// Now the loop for Sieve of Eratosthenes.
// Also, let $i = 0 for a counter.
$i = 0;
while($p*$p < $n)
{
// Strike off all multiples of p less than or equal to n
for($j=$i+1; $j < $n; $j++)
{
if($list[$j] % $p == 0)
{
unset($list[$j]);
}
}
// Re-initialize array
sort ($list);
// Find first number on list after p. Let that equal p.
$i = $i + 1;
$p = $list[$i];
echo "$i: $p\n";
}
echo array_sum($list);
?>

Categories