3

I need to include an external php file, then execute some code and finally include the final file But since the first file has the beginning of the foreach and the second file has the end of the foreach, it's not working:

master script:

if ($conditionMet) include('begin.php');

echo 'blablabla';
... do more stuff

if ($conditionMet) include('end.php');

begin.php:

foreach (array(1,2,3,4) as $id):

end.php:

endforeach;

Of course it doesn't work. I thought maybe because php would not know where to start looping at the foreach again after begin.php was included but it's not that because it works if I do this:

if ($conditionMet) eval('foreach (array(1,2,3,4) as $id):');
echo 'blablabla';
if ($conditionMet) eval('endforeach;');

Can't write the code like this with eval, I don't like using eval, plus I have more code to put in begin.php and end.php

UPDATE:

It seems there is confusion as to why I want to do this and the purpose of the code. I thought it would be better to simplify the code to get a straight solution but it looks like I only made it worse, so I'll explain more:

If you forget about the two if the master script, the line echo 'bablabla; is in fact a lot of code with a foreach loop in it as well that passes through an associative array and outputs correct html. The array would for instance be like that:

array(
    array('product'=>'carrot', 'price'=>5),
    array('product'=>'onion', 'price'=>4),
    array('product'=>'apple', 'price'=>2)
);

Now on certain occasions, the array would be slightly different like such:

array(
    array('product'=>'carrot', 'price'=>5, 'category'=>'vegetable'),
    array('product'=>'onion', 'price'=>4, 'category'=>'vegetable'),
    array('product'=>'apple', 'price'=>2, 'category'=>fruit')
);

This is when $conditionMet is true, so in "begin.php", it rebuilds the array like such:

foreach ( regorganizeArray($productsArray) as $productsArray)

to become

array(
    array(
        array('product'=>'carrot', 'price'=>5, 'category'=>'vegetable'),
        array('product'=>'onion', 'price'=>4, 'category'=>'vegetable'),
    ),
        array('product'=>'apple', 'price'=>2, 'category'=>fruit')
    )
);

then will display extra stuff for instance

<h4>vegetables</h4>

then it the rest of the master script is executed seamlessly with the master script just displaying the content of the array without even knowing there's a difference.

Finally, "end.php" ends the foreach.

Now you're probably all thinking that I should put the code of the master script in a function but there are several versions of it (themes) and they never do the exact thing. The ONLY thing that all the different versions of the master script have in common is that the input array is the same.

There you go, sorry for all the confusion, I would not be a really good teacher as I'm bad at explaining, but I hope this made things clearer.

7
  • That's not even valid PHP code... Commented May 13, 2014 at 7:58
  • I wrote a simplified example and did not even notice the errors. anyway, fixed it now. Doesn't change that fact that it's not working.. Commented May 13, 2014 at 8:16
  • Control structures can be only nested Commented May 13, 2014 at 8:21
  • Why would you have an if statement to close the loop? This needs to always occur Commented May 13, 2014 at 8:26
  • 1
    It's not working for multiple reasons, but even if you put the includes side-by-side and not within conditional blocks, it would not work because the unclosed loop in the first included script would fail to parse. PHP runs the included code as a standalone script, it doesn't just stream in the code and trust that it will be valid eventually. (I actually only learned this because of your question, or I might have stumbled into this problem myself someday.) Commented May 13, 2014 at 8:56

3 Answers 3

1

Each php file must be syntactically valid before the preprocessing is done, so since you have a syntax error in begin.php the request will be dead and you'll have a syntax error.

Sign up to request clarification or add additional context in comments.

4 Comments

Excellent point. I was working on an answer that would avoid the entangled control blocks and just have include($start); include($end); side by side, but even doing that part "right" won't work per your point. It throws a parse error on the first include because the loop isn't closed. So the OPs approach is fundamentally flawed since there is no right way to split the loop across multiple scripts.
That's what I thought as well, but then why is it working with eval()?
@NaturalBornCamper - I think you are mistaken. Try running the eval example in a standalone script without the condition check, like : eval('foreach (array(1,2,3,4) as $id):'); echo 'blablabla'; eval('endforeach;'); When I run this, I get back a parse error for each eval and a blablabla in between. I think your underlying assumption is based on an imperfect test. I tested with PHP 5.3 and 5.4
Damn, you're right, I tested a different scenario and it's not working. The result falsely made me think it was working. Well, eval my my plan B, no idea what to do now
1

Why not simply do something like:

$productsArray = array(...) ; // This is what you have at the beginning
if ($conditionMet) {
    $productsArray = regorganizeArray($productsArray) ;
}
else {
    $productsArray = array($productsArray, ) ;
}
foreach ($productsArray as $productsArr) {
    // Do whatever you want
}

If you have this array:

$productsArray = array(
    array('product'=>'carrot', 'price'=>5),
    array('product'=>'onion', 'price'=>4),
    array('product'=>'apple', 'price'=>2)
); 

And the conditions is not met, you will create something like:

$productsArray = array(
    array(
        array('product'=>'carrot', 'price'=>5),
        array('product'=>'onion', 'price'=>4),
        array('product'=>'apple', 'price'=>2)
    )
); 

So the foreach statement will loop one time, and the only time it loops the $productsArr will contains the first array.

If the conditions is not met you get (after reorganization) this array:

array(
    array(
        array('product'=>'carrot', 'price'=>5, 'category'=>'vegetable'),
        array('product'=>'onion', 'price'=>4, 'category'=>'vegetable'),
    ),
    array(
        array('product'=>'apple', 'price'=>2, 'category'=>'fruit')
    )
);

And you will loop 2 times, first you'll get the vegetable array and second time the fruit array.

7 Comments

I added more clarifications! sorry about that!
@NaturalBornCamper I updated my code. The idea is to always have a loop but to only loop one time when the condition is not met. Don't know if it matches what you want.
Thanks Holt! Unfortunately the code inside the foreach would crash because if it was reorganized, it is not an array of products anymore, but an (array of (array of products))
@NaturalBornCamper Yes, it is why I added the else block, so if you do not reorganize the code, you always have an array of array of products and in each loop you have an array of products. It works, except if you have conditionnal statement inside the foreach loop that check conditionMet.
@NaturalBornCamper I added explanation on my answer.
|
0

That approach won't work as it is not valid PHP. Not exactly sure why you'd need a separate php file to perform the loop but if you need to, you can use functions and callbacks like so:

In Master script:

if ($conditionMet) {
   include('loopscript.php')
   performTheLoop('doMyStuff')
} else {
   doMyStuff();
}

function doMyStuff() {
  echo 'blablabla';
}

In loopscript.php:

function performTheLoop($callback) {
  foreach (array(1,2,3,4) as $id) {
    call_user_func($callback); 
  }
}

1 Comment

I want to avoid code repetition, this is why I don't want to do and if +else statement. the "echo 'blablabla'" code is actually much bigger. I added somevclarifications so you can see my point better, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.