Run
Run

Reputation: 57176

PHP: improving the loop that uses foreach?

I use foreach to loop the array below and then making the order number to be store in the database,

$items_variable = array(
    'page_id',
    'page_content_1',
    'page_content_2',
    'page_content_3',
    'page_content_4',
    ...
);

The code only loop 4 items from the array above (but what if I have these page_content_# increased in the future?)

foreach( $items_variable as $item_variable )
{   
    if (in_array($item_variable, array(
        'page_content_1',
        'page_content_2',
        'page_content_3',
        'page_content_4'
    )))
    {
        if($item_variable == 'page_content_1') $order_in_page = 1;
        if($item_variable == 'page_content_2') $order_in_page = 2;
        if($item_variable == 'page_content_3') $order_in_page = 3;
        if($item_variable == 'page_content_4') $order_in_page = 4;
        ....
        }
}

The current method I have above doesn't look good to me especially when it comes to the line like this,

if($item_variable == 'page_content_1') $order_in_page = 1;

I will add more lines like this when I have page_content_# increased in the future and the script will look pretty ugly I suppose.

What if I have another type of data with order number (for instance - code_1, code_2, etc)? Then I have copy the code above and change the item name each time - this looks pretty gloomy isn't!

How can I make it better and dynamic?

Upvotes: 1

Views: 91

Answers (6)

Zar
Zar

Reputation: 6882

I'm not sure I understood your question, but you might want to store your data in a multidimensional array, like:

$items_variable = array(
    'page_id',
    'content' => array(
        //content
    )
);

Then you could just iterate through each content-array, such as:

foreach($items_variable['content'] as $content) {
    //do stuff with the content
}

No need for regex or other stuff.

Upvotes: 0

clime
clime

Reputation: 8885

foreach($items_variable as $item_variable) {   
    preg_match('/[0-9]*$/',$item_variable , $suffix);
    $suffix = $suffix[0];
    if ($suffix !== '') {
        # code 1
    } else {
        # code 2
    }
}

Upvotes: 1

Vyktor
Vyktor

Reputation: 20997

Associative array

You can do this:

$items_definitions = array(
    'page_content_1' => 1,
    'page_content_2' => 2,
    'page_content_3' => 3,
    'page_content_4' => 4,
    'page_content_5' => 5,
);

foreach( $items_variable as $item_variable ){ 
    if( isset( $items_definitions[ $item_variable])){
        $order_in_page = $items_definitions[ $item_variable];
    }
    ...
}

Dynamically extracting last part of string

Or do it completely dynamically assuming that it's always page_content_{$order_in_page}, either with regexp as hackartist suggested or use "oldschool method":

$prefix = 'page_content_';
foreach( $items_variable as $item_variable ){ 
    if( strncmp( $item_variable, $pregix, strlen( $prefix))){
        continue; // Assume that you don't want to do anything if it doesn't match
    }
    $page = intval( substr( $item_variable, strlen( $prefix)));
    if( !$page){
        continue;
    }
    $order_in_page = $page;
}

I recommend studying examples from intval() documentation :)

Switch statement

Php provides switch which allows you to handle many different cases with relatively small amount of code.

foreach( $items_variable as $item_variable ){
    switch( $item_variable){
        case 'page_content_1':
            $order_in_page = 1;
            break;
        case 'page_content_2':
            $order_in_page = 2;
            break;
        case 'page_content_3':
            $order_in_page = 3;
            break;
        ...
        default:
    }
}

I'd however do this only if first two options wouldn't work out for you (eg. you need to call different function for each case).

Upvotes: 3

Kevin Ji
Kevin Ji

Reputation: 10489

Your current array, if you write it out with the explicit keys, looks like the following:

$items_variable = array(
    0 => 'page_id',
    1 => 'page_content_1',
    2 => 'page_content_2',
    3 => 'page_content_3',
    4 => 'page_content_4',
    ...
);

Notice that the key number matches completely with the page content number. Thus, you could change the foreach loop to the following:

foreach( $items_variable as $order_in_page => $item_variable )

Now $order_in_page should be stored with the key number, which in your array correlates directly to the page content number. You may need to cast it into an int, although I am not sure of this fact:

$order_in_page = (int) $order_in_page;

If instead, your array looked like the following (without the 'page_id' element):

$items_variable = array(
    0 => 'page_content_1',
    1 => 'page_content_2',
    2 => 'page_content_3',
    3 => 'page_content_4',
    ...
);

Do the same thing as above, but add one to the result:

++$order_in_page;

If casting is needed, cast before the increment.

Upvotes: 1

bjelli
bjelli

Reputation: 10090

I'm not sure I understand your question, but maybe an associative array would be a solution for you. You can use it to match a string to a value:

$order_in_page = array(
    'page_content_1' => 1,
    'page_content_2' => 2,
    'page_content_3' => 3,
    'page_content_4' => 4,
    'someotherpage' => 5,
    'yet_another_page' => 6
);


$o = $order_in_page[$item_variable];

Stuff on the data structure http://en.wikipedia.org/wiki/Associative_array

PHP Documentation http://php.net/manual/de/language.types.array.php

Upvotes: 1

hackartist
hackartist

Reputation: 5264

not sure exactly what you want but try this instead of the if statement:

preg_match('/page_content_([0-9]+)/',$item_variable,$matches);
$order_in_page = $matches[1];

Upvotes: 2

Related Questions