Funciones recursivas. Php

Esta es la primera entrada que hago en el blog, donde me gustaría que se centrara en la resolución de los problemas en programación de la vida real, problemas cotidianos a los cuales se enfrentan desarrolladores noveles con muy poca experiencia y a veces con no tan poca, intentando buscar, por ejemplo, solución a un problema de diseño de base de datos mediante programación y en este problema me voy a centrar hoy. En una entrada del foro de PHP de LWP (la web del programador) este problema se planteó.

Función recursiva: “Tengo una tabla id promotor, promovido se trata de una red de personas persona A promueve a B a su vez persona B promueve a C y así, sucesivamente. Quisiera una función que me sume cuantas personas tiene A en su red (es decir, B más los promovidos por B + C más los promovidos por C) es decir, el número de personas abajo de A”. Y esta fue la solución que le proporcioné:

<?php

function buscaPromovidos($promotor){

global $total;
 
$bd = new consulta_principal();//conexión a la base de datos
$tbl = 'promociones';//selecciono tabla
$where = "WHERE promotor = '$promotor'";
$clmns = '*';
$promotor = $bd->leer($tbl, $clmns, $where);//consulta SELECT FROM  {$where} "
$numero = count($promotor); 

    if($numero > 0) {    
      $total += $numero;
          
      for($i = 0; $i < $numero; $i++){

         buscaPromovidos($promotor[$i]['promovido']);
     
      }
    }

return $total;
     
}


?>

Como se ve, la función es recursiva y se llama así misma cada vez que encuentra una coincidencia y continúa buscando en la base de datos sin entrar en un bucle infinito. Ni que decir tiene que no hace falta tener que llegar a codificar bucles como este, imagina una base de datos con millones de registros, se haría eterno. Mejor hubiera sido crear una buena estructura relacional en la base de datos, desde el principio, para poder realizar búsquedas como esta sin sobrecargarla y hacer lento el script.

Después de un poco de análisis reprogramé la función para que no esté creando una nueva conexión a la base de datos a cada llamada a la función y pasarla por parámetro, al igual que no hacer global a la variable $total y pasársela a la función por referencia. Ahora la función es más rápida y óptima.

<?php

function searchPromoted($promoted, $db,  &$total){
      
    $table = 'promotions';
    $where = "WHERE promoted = '$promoted'";
    $columns = '*';
    $promoted = $db->read($table, $columns, $where);//aqui consulta del tipo SELECT {$clmns} FROM {$tbl} {$where} "
    $number = count($promoted);
        if($number > 0) {   
          
          $total += $number;      
             for($i = 0; $i< $number; $i++){
               searchPromoted($promoted[$i]['promoted'], $db, $total);
             }
        }
    
    return $total;
         
    }

//ejemplo de uso

  $bd = new conexion();//asi conecto con BBDD usa tu conexion
  $person = '42003';
  $total = 0;
  $number = searchPromoted($person, $bd, $total);

  if(isset($number)){
    echo "numero personas promovidas por $person es de: $number. ";
  }else{
    echo "numero personas promovidas por $person es de: 0. ";
  }

?>