In PHP, as in other languages, there are several types of loops that differ in syntax and usage.

Cycles are divided according to what type of operation we want to perform over the elements:

**for** : A general cycle where we know the number of repetitions in advance, or we can calculate it.

**while**, **do-while**: A general cycle where we do not know the number of repetitions in advance.

**foreach**: Browsing arrays and objects.

**recursion**: Breaking down a complex problem into a set of smaller ones.

**For** is suitable for cases where we know the number of repetitions beforehand. Perfect for linear traversing intervals.

Generally it is recorded:

```
for (initialize; expression; increment) {
// cycle body
}
```

**Initialization**: Definition of the initial state of the cycle (what variables we need),

**Expression**: Condition. As long as the cycle is valid,

**Increment**: Change the cycle state compared to the previous pass (**increment** - increment by one).

For example, a series of numbers from **0 **to **10** can be written:

```
for ($i = 0; $i <= 10; $i++) {
echo $i . '<br>';
}
```

Or multiples of two from **2 **to **100**:

```
for ($i = 2; $i <= 100; $i += 2) {
echo $i . '<br>';
}
```

While the cycle runs until the condition is true. The difference between ** while ** and **do-while** is when the condition will be evaluated.

```
while (expression) {
// cycle body
}
```

Alternatively:

```
do {
// cycle body
} while(expression);
```

**While** first evaluates the condition and then runs inside the cycle,

**Do-while** first processes the inside of the cycle before evaluating the condition.

The advantage is especially when we cannot know in advance if the cycle ever goes and we want to guarantee that it always runs at least once (then we use **do-while**).

Example:

We have a number stored in **$ x = 2**. To **$ y** We also want to generate a number in the interval **<0; 10>** to be different than it is in variable **$ x**. Simply put: Generate a random number between **0** and **10**, which is not **2**.

In this case, use a **do-while** cycle. We do not know in advance how many times the cycle will have to run (we may be unlucky and we will still hit the same number, in which case the cycle will run long) and at the same time we want to guarantee that it will run at least once.

```
$x = 2;
$y = $x;
do {
$y = rand(0, 10);
} while($x == $y);
echo 'X : ' . $x . '<br>';
echo 'Y: ' . $y;
```

**Foreach** is perfect for scrolling through fields and objects. We can get only specific values, but also keys.

If we only want to get specific values:

```
foreach ($data as $value) {
// data processing
}
```

Alternatively we can get the keys:

```
foreach ($data as $key => $value) {
// data processing
}
```

**Foreach** is perfect for browsing real data - like database results or key fields:

```
$countries = [
'gb' => 'Great Britan',
'us' => 'United States',
];
foreach ($countries as $shortcut => $name) {
echo $shortcut . ': ' . $name . '<br>';
}
```

Recursion occurs when a function or method calls itself. Used to break down a complex problem into a group of smaller ones.

Understanding recursion can be challenging for beginners because it is based on the idea of transferring responsibility. The function actually says something with the meaning: "I can't solve this problem, but I know someone who does ..." so he calls it, he calls someone again ... when the final member is called to cut the problem.

It is worth noting that any recursive algorithm can be rewritten to use cycles where recursion is not needed (the reverse is also true). Recursion is a good servant, but a bad master. It helps to solve some types of problems in a simple and very effective way;

In general, recursion is highly memory intensive because it creates new instances and contexts of functions and methods. For example, for browsing through tree structures, this is the only sensible way to solve the problem.

Example:

We need to calculate the factorial of number **5**, this is done in mathematics as follows:

`5! = 5 * 4 * 3 * 2 * 1`

Thus, there is a gradual multiplication of a series of numbers from **1** to the number for which we are interested factorial.

Recursively it can be solved very elegantly:

```
function factorial(int $n)
{
if ($n === 0) {
return 1;
}
return $n * factorial($n - 1);
}
```

Or even shorter implementation using ternary operator:

```
function factorial(int $n)
{
return $n === 0 ? 1 : $n * factorial($n - 1);
}
```

The same can be rewritten to use cycles:

```
function factorial(int $n)
{
$result = 1;
for ($i = $n; $i > 0; $i--) {
$result *= $i;
}
return $result;
}
```

Writing with a cycle is a bit longer, but it has a significantly lower memory consumption. For calculation we use only one variable **$ result**, where we continuously change the value and we do not have to create new instances of the **factorial ()** function.

It can very easily happen that the cycle is endless (this is achieved by never ending the condition). We should take this into account and stop the cycle yourself with **break ;**.

For example, we roll the dice until the number **6** falls. The implementation tempts to use the **while** loop:

```
while (true) {
$value = rand(1, 6);
if ($value === 6) {
echo 'Value given ' . $value;
break;
}
}
```

By writing **while (true)** we have ensured an infinite number of repetitions, because true will always be **true**. So we have to stop the cycle by constructing **break**; but what if the value of 6 never fails and we never stop?

Personally, I always count the number of repetitions and if it exceeds a critical limit, I will forcibly end the cycle. For example, if we exceed **1000** attempts. In this case, it is preferable to use **for** instead of **while** while calculating the number of waveforms.

If we exceed the number of waveforms, it is polite to inform the developer by throwing an exception.

```
for ($i = 0; $i <= 1000; $i++) {
$value = rand(1, 6);
if ($value === 6) {
echo 'Value given' . $value;
break;
}
}
if ($i === 1000) {
throw new \Exception('Maximum number of throws exceeded.');
}
```