PHP foreach select range to show

Hello,

I have this:

foreach ($customers as $customer){

and I only need the 500th - 1000th records in that array, how do I only foreach those?

Thanks
LVL 1
movieprodwAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Marco GasiFreelancerCommented:
Maybe something like this:
$i =0;
foreach ($customers as $customer){
if($i >= 500 && $i <= 1000) {
//stuff here
}
}

Open in new window

movieprodwAuthor Commented:
Would I need to say $i++ somewhere?

I am trying a similar way but the issue is that calling to load each '$customer' is very slow, so I have 20k results and it has to load the first 500 each time I do that. It would be great if I could just start at 500
movieprodwAuthor Commented:
Maybe there is a way to delete the first 500 out of the $customers array? then I could just tell it to stop when $i = 1000

Is that possible?
Build an E-Commerce Site with Angular 5

Learn how to build an E-Commerce site with Angular 5, a JavaScript framework used by developers to build web, desktop, and mobile applications.

Ray PaseurCommented:
Yes, array_slice() can remove parts of an array.
movieprodwAuthor Commented:
Thanks Ray... did that at apparently it is an object, can you do the same with an object?

$customers = array_slice($customers, 0, 5);
Ray PaseurCommented:
You might also consider a for() statement.
http://php.net/manual/en/control-structures.for.php

Something like this:
for($i = 500; $i <= 1000; $i++) {
    /* Do Stuff */
}

Open in new window

Ray PaseurCommented:
No, you cannot use PHP array functions on objects directly, but you can often cast objects as arrays and then use array functions.  You can find the data types with var_dump()
movieprodwAuthor Commented:
Okay, trying to work with Magentos objects to update 20k passwords but it keeps timing out, it is super slow.

I figured if I could do 500 at a time it would be great, but it had to load the first 500 to get to the second 500, takes forever.

I was hoping that I could just start at the 500th and run to the 1000th, then 1000th to 1500th
Marco GasiFreelancerCommented:
Forgive me yes you had to put $i++
Ray PaseurCommented:
You can increase the PHP time limit.  Try putting set_time_limit(2) inside the loop.  But I'm concerned that 20K of anything should not be too slow -- 20K is not a big number in computer science.  Are there any things that slow this process down unnecessarily?
movieprodwAuthor Commented:
I agree, 20k should be lightening.

Do you see any red flags in my code below? I was just running 50 for the test, it seems to take about 30 seconds for 50.

// LOAD CUSTOMER COLLECTION
$customers = Mage::getModel('customer/customer')->getCollection();

// LOAD VARIABLES
$count = $_GET['count'];
$countplus = $count + 50;
$basenumber = '0';

// LOAD FILE
$file = 'account_passwords.csv';
$current = file_get_contents($file);

// LOAD CUSTOMER INFO
foreach ($customers as $customer){
	
	if($basenumber > $count) {
		if($basenumber > $countplus) {
			file_put_contents($file, $current);
			echo '<script type="text/javascript">
				window.location = "/resetallpasswords.php?count='.$countplus.'"
				</script>';
				echo 'orange';
				exit();
		} else {
			$password = strtoupper(substr( $customer->getEmail(), 0, 3)).rand(111,999);
			$customer->setPassword($password)->save();
			$current .= $customer->getGroupId(). ",". $customer->getEmail(). ",". $customer->getPassword()."\n";
		}
	}
	
	$basenumber++;	
} 

Open in new window

Ray PaseurCommented:
No giant red flags, but maybe the methods called on $customer are hitting the database (active record design)?  It would take hands-on study to isolate the cause for delay.

You can time parts of the script with something like this class.  Maybe something will leap out once you've seen the timings.
<?php // demo/class_Stopwatch.php
error_reporting(E_ALL);

// START THE TIMER
$t = new StopWatch;
$t->start();

// DO SOME ACTIVITY THAT YOU WANT TO TIME
$x = file_get_contents('https://google.com/');

// GET A READOUT FROM THE TIMER
echo $t->readout();

// RESET THE TIMER
$t->reset();


// A SCRIPT TIMER FOR ALL OR PART OF A SCRIPT PHP 5+
// MAN PAGE http://php.net/manual/en/function.microtime.php
class StopWatch
{
    protected $a; // START TIME
    protected $s; // STATUS - IF RUNNING
    protected $z; // STOP TIME

    public function __construct()
    {
        $this->a = array();
        $this->s = array();
        $this->z = array();
    }

    // A METHOD TO PROVIDE A FINAL READOUT, IF NEEDED
    public function __destruct()
    {
        $ret = $this->readout();
        if (!$ret) return FALSE;
        echo
          __CLASS__
        . '::'
        . __FUNCTION__
        . '() '
        ;
        echo "<b>$ret</b>";
        echo PHP_EOL;
    }

    // A METHOD TO REMOVE A TIMER
    public function reset($name='TIMER')
    {
        // RESET ALL TIMERS
        if ($name == 'TIMER')
        {
            $this->__construct();
        }
        else
        {
            unset($this->a[$name]);
            unset($this->s[$name]);
            unset($this->z[$name]);
        }
    }

    // A METHOD TO CAPTURE THE START TIME
    public function start($name='TIMER')
    {
        $this->a[$name] = microtime(TRUE);
        $this->z[$name] = $this->a[$name];
        $this->s[$name] = 'RUNNING';
    }

    // A METHOD TO CAPTURE THE END TIME
    public function stop($name='TIMER')
    {
        $ret = NULL;

        // STOP ALL THE TIMERS
        if ($name == 'TIMER')
        {
            foreach ($this->a as $name => $start_time)
            {
                // IF THIS TIMER IS STILL RUNNING, STOP IT
                if ($this->s[$name])
                {
                    $this->s[$name] = FALSE;
                    $this->z[$name] = microtime(TRUE);
                }
            }
        }

        // STOP ONLY ONE OF THE TIMERS
        else
        {
            if ($this->s[$name])
            {
                $this->s[$name] = FALSE;
                $this->z[$name] = microtime(TRUE);
            }
            else
            {
                $ret .= "ERROR: CALL TO STOP() METHOD: '$name' IS NOT RUNNING";
            }
        }

        // RETURN AN ERROR MESSAGE, IF ANY
        return $ret;
    }

    // A METHOD TO READ OUT THE TIMER(S)
    public function readout($name='TIMER', $dec=3, $m=1000, $t = 'ms', $eol=PHP_EOL)
    {
        $str = NULL;

        // GET READOUTS FOR ALL THE TIMERS
        if ($name == 'TIMER')
        {
            foreach ($this->a as $name => $start_time)
            {
                $str .= $name;

                // IF THIS TIMER IS STILL RUNNING UPDATE THE END TIME
                if ($this->s[$name])
                {
                    $this->z[$name] = microtime(TRUE);
                    $str .= " RUNNING ";
                }
                else
                {
                    $str .= " STOPPED ";
                }

                // RETURN A DISPLAY STRING
                $lapse_time = $this->z[$name] - $start_time;
                $lapse_msec = $lapse_time * $m;
                $lapse_echo = number_format($lapse_msec, $dec);
                $str .= " $lapse_echo $t";
                $str .= $eol;
            }
            return $str;
        }

        // GET A READOUT FOR ONLY ONE TIMER
        else
        {
            $str .= $name;

            // IF THIS TIME IS STILL RUNNING, UPDATE THE END TIME
            if ($this->s[$name])
            {
                $this->z[$name] = microtime(TRUE);
                $str .= " RUNNING ";
            }
            else
            {
                $str .= " STOPPED ";
            }

            // RETURN A DISPLAY STRING
            $lapse_time = $this->z[$name] - $this->a[$name];
            $lapse_msec = $lapse_time * $m;
            $lapse_echo = number_format($lapse_msec, $dec);
            $str .= " $lapse_echo $t";
            $str .= $eol;
            return $str;
        }
    }
}

Open in new window

Bernard S.CTOCommented:
Some random thoughts in brain storming mode:
- account_passwords.csv and $contents: you are using some repeating payload here by reading the content once, updating in memory all the content once per loop, then rewriting all the content to the file.
I would consider using for the final write not a rewrite but an append
$current = '';
// LOAD CUSTOMER INFO
foreach ($customers as $customer){
	if($basenumber > $count) {
		if($basenumber > $countplus) {
			file_put_contents($file, $current,FILE_APPEND);
			echo '<script type="text/javascript">
...

Open in new window

- not sure to understand everything but it seems you are restarting from 0 each time (which would justify a rewrite instead of an append).
Since your program seems to somehow assume that collection() always returns data in the same sort order, I would probably try some jumping over the already travelled path, something like
//CUSTOMER COLLECTION
$customers = Mage::getModel('customer/customer')->getCollection();

// LOAD VARIABLES
$count = $_GET['count'];
$countplus = $count + 50;


// LOAD FILE
$file = 'account_passwords.csv';
$current = '';

// LOAD CUSTOMER INFO
for ($basenumber = $count; $basenumber  < $countplus; $basenumber ++) {
	$customer= $customers[$basenumber ];
	
	$password = strtoupper(substr( $customer->getEmail(), 0, 3)).rand(111,999);
	$customer->setPassword($password)->save(); // not sure this really gives the expetd result!!
	$current .= $customer->getGroupId(). ",". $customer->getEmail(). ",". $customer->getPassword()."\n";
}
			file_put_contents($file, $current,FILE_APPEND);
			echo '<script type="text/javascript">
			window.location = "/resetallpasswords.php?count='.$countplus.'"
			</script>';
			echo 'orange';
			exit();

Open in new window

- please note that you need to test that $customer->setPassword($password)->save(); gives the intended result in "my" suggestion but also in your code

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
movieprodwAuthor Commented:
Thanks for the help guys, I could not get it to work, ended up just inserting it all into the system using 2 scripts, one to make the passwords then another to add them in the db.

Thank you for the help, I learned some stuff
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.