• PHP Help
  • I can not figure out why I have a Endless loop

I know eval is dangerous and evil but I need to use this for this situation. Basically I have two different databases that has the same table structure but with different data so I used a for each

loop to access both databases and a while loop to show all the databases results and I used eval so I can make the variables unique from each other. Everything seems to work well,

till I load the page and there are no errors but the page goes into a endless loop and it just keeps generating the first rows value which never progress showing the next rows value so how can I structure this better so I won't end up in a endless loop?

This is my code

<?php

$search_user_input='a';

$array_of_user_xs_database_name = array('agency_clients','agency_models');
$array_of_user_xs = array('client','model');

$iterator = new MultipleIterator();
$iterator->attachIterator(new ArrayIterator($array_of_user_xs_database_name));
$iterator->attachIterator(new ArrayIterator($array_of_user_xs));

foreach($iterator as $index => $value){

$user_xs_database_name= $value[0];
$user_x= $value[1];
$User_x= ucfirst($user_x);

eval('
$db_servername_getSearched'.$User_x.'="localhost";
$db_username_getSearched'.$User_x.'="jd";
$db_password_getSearched'.$User_x.'="1234";
$db_name_getSearched'.$User_x.'= $user_xs_database_name;

$db_connect_getSearched'.$User_x.'= new mysqli ($db_servername_getSearched'.$User_x.',$db_username_getSearched'.$User_x.',$db_password_getSearched'.$User_x.',
$db_name_getSearched'.$User_x.');

$db_query_getSearched'.$User_x.'= "SELECT uid, photo, CONCAT(first_name, \' \', last_name) AS name, signature_name, phone_number, email
FROM '.$user_x.'s WHERE CONCAT_WS(\' \','.$user_x.'s.first_name,'.$user_x.'s.last_name) LIKE \'%".$search_user_input."%\'
OR signature_name LIKE \'%".$search_user_input."%\' OR phone_number LIKE \'%".$search_user_input."%\' OR email LIKE \'%".$search_user_input."%\'";

$db_result_getSearched'.$User_x.'= $db_connect_getSearched'.$User_x.'->query($db_query_getSearched'.$User_x.');
');

$mysqli_result= eval('return $db_result_getSearched'.$User_x.';');

if($mysqli_result-> num_rows >= 1){

$mysqli_row= eval('return $db_row_getSearched'.$User_x.'= $db_result_getSearched'.$User_x.'->fetch_assoc();');

while($mysqli_row){

?>

<h1>
<?php

$photos= eval('return $db_row_getSearched'.$User_x.'["photo"];');
echo $photos;
?>

</h1>

<?php
}
}
}

?>

    The reason for the forever loop is because you are only fetching the 1st row of data before the start of the loop, then looping while that value is true, which is forever, or until the maximum run-time is exceeded.

    None of this eval() code is necessary. If you think it is, you need to revisit what variables are for. Variables are designed to hold changing data values. Variables are named for their purpose, not for the value in them. You don't create newly named variables just because you have assigned a different value to a variable. The only things that change for each iteration of the foreach() loop are the database name and the table name.

    The following is equivalent to what you came up with and should (untested) work -

    <?php
    
    $search_user_input='a';
    
    $array_of_user_xs_database_name = array('agency_clients','agency_models');
    $array_of_user_xs = array('client','model');
    
    $iterator = new MultipleIterator();
    $iterator->attachIterator(new ArrayIterator($array_of_user_xs_database_name));
    $iterator->attachIterator(new ArrayIterator($array_of_user_xs));
    
    $db_servername ="localhost";
    $db_username ="jd";
    $db_password ="1234";
    
    foreach($iterator as $index => $value)
    {
    	// db name
    	$database_name = $value[0];
    	// table root name (code adds an s to it)
    	$table_name = $value[1] . 's';
    
    $mysqli = new mysqli ($db_servername, $db_username, $db_password, $database_name);
    
    $sql = "SELECT uid, photo, CONCAT(first_name, ' ', last_name) AS name, signature_name, phone_number, email 
    FROM $table_name 
    WHERE CONCAT_WS(' ',first_name,last_name) LIKE '%$search_user_input%' OR signature_name LIKE '%$search_user_input%'
    	OR phone_number LIKE '%$search_user_input%' OR email LIKE '%$search_user_input%'";
    
    $result = $mysqli->query($sql);
    
    while($row = $result->fetch_assoc())
    {
    ?>
    	<h1>
    	<?php
    	echo $row["photo"];
    	?>
    	</h1>
    <?php
    }
    }
    

    pbismad Thanks for your reply. Yes I know you can do this like this but the reason why I used eval() so I can have unique variables so I can later use for example one of the unique variables $db_servername_getSearchedClient later on down the page for something else that's why I used eval for this script.

    o8codex

    You still don't need eval for that. If you have to have a distinct identifier, then variable variables are sufficient, but more useful would be an associative array (e.g. $db_servername_getSearched[$User_x]['photo']) because, for example, all your "db_servername_getSearched" items can be handled as a single group.

    E,g. something like

    <?php
    
    $search_user_input='a';
    
    $array_of_user_xs_database_name = array('agency_clients','agency_models');
    $array_of_user_xs = array('client','model');
    
    $iterator = new MultipleIterator();
    $iterator->attachIterator(new ArrayIterator($array_of_user_xs_database_name));
    $iterator->attachIterator(new ArrayIterator($array_of_user_xs));
    
    foreach($iterator as $index => $value){
    
    $user_xs_database_name= $value[0];
    $user_x= $value[1];
    $User_x= ucfirst($user_x);
    
    $db_servername_getSearched[$User_x]="localhost";
    $db_username_getSearched[$User_x]="jd";
    $db_password_getSearched[$User_x]="1234";
    $db_name_getSearched[$User_x]= $user_xs_database_name;
    
    $db_connect_getSearched[$User_x]= new mysqli ($db_servername_getSearched[$User_x],$db_username_getSearched[$User_x],$db_password_getSearched[$User_x],
    $db_name_getSearched[$User_x]);
    
    $db_query_getSearched[$User_x]= "SELECT uid, photo, CONCAT(first_name, \' \', last_name) AS name, signature_name, phone_number, email
    FROM '.$user_x.'s WHERE CONCAT_WS(\' \','.$user_x.'s.first_name,'.$user_x.'s.last_name) LIKE \'%".$search_user_input."%\'
    OR signature_name LIKE \'%".$search_user_input."%\' OR phone_number LIKE \'%".$search_user_input."%\' OR email LIKE \'%".$search_user_input."%\'";
    
    $db_result_getSearched[$User_x]= $db_connect_getSearched[$User_x]->query($db_query_getSearched[$User_x]);
    
    
    $mysqli_result= eval('return $db_result_getSearched'.$User_x.';');
    
    if($mysqli_result-> num_rows >= 1){
    
    $mysqli_row= $db_row_getSearched[$User_x]= $db_result_getSearched[$User_x]->fetch_assoc();
    
    while($mysqli_row){
    
    ?>
    
    <h1>
    <?php
    
    $photos= $db_row_getSearched[$User_x]["photo"];
    echo $photos;
    ?>
    
    </h1>
    
    <?php
    }
    }
    }
    
    ?>
    

    Though I don't know what "getSearched" contributes to the name, and I'd probably group servername/username/password/name by $User_x instead of the other way around as you have it.

    Weedpacket Thanks for your response and yeah I want unique variables because later down the road i'm going to want to call a certain group of variable for example this $db_row_getSearched'.$User_x.' really means this $db_row_getSearchedClient or this $db_row_getSearchedModel because what if later down the road I want to call $db_row_getSearchedClient['Name']; and I try your code it gave me errors the browser seems to not like any of these kind of variables $db_row_getSearched[$User_x].

    o8codex pbismad Thanks for your reply. Yes I know you can do this like this but the reason why I used eval() so I can have unique variables so I can later use for example one of the unique variables $db_servername_getSearchedClient later on down the page for something else that's why I used eval for this script.

    Then you would use an array to hold the values, as Weedpacket has shown (less the remaining eval() code and the wrong fetch logic), with the main array index being the 'Client' or 'Model' values. You should actually fetch all the rows from a result set into a variable for use in the rest of the code, so that you don't have database specific code throughout your presentation code.

    o8codex Weedpacket Thanks for your response and yeah I want unique variables because later down the road i'm going to want to call a certain group of variable for example this $db_row_getSearched'.$User_x.' really means this $db_row_getSearchedClient or this $db_row_getSearchedModel because what if later down the road I want to call $db_row_getSearchedClient['Name']; and I try your code it gave me errors the browser seems to not like any of these kind of variables $db_row_getSearched[$User_x].

    Array elements are unique variables. To dynamically reference, for example the 'Name' value, using a variable for the main array index, you would use - $db_row_getSearched[$User_x]['Name']. To statically reference it, you would use - $db_row_getSearched['Client']['Name']. All ignoring that $db_row_getSearched[...] is only the first row from either result set due to the wrong fetch logic.

    Next, you have an sql injection problem, by putting what's likely external data directly into the sql query statement and you don't have any error handling for the connection or query statements. You need to use a prepared query when supplying external/unknown values to an sql query statement and use exceptions to handle all database statement errors.

    Lastly, I once did a benchmark of variable variables v.s. arrays and variable variables are three times slower than using an array. In every case where you may want to produce a series of named variables, you should just use an array.

      laserlight Thanks for responding I change the code a tiny bit so you can know what I mean but it gives me the same result

      <?php

      $search_user_input='a';

      $array_of_user_xs_database_name = array('agency_clients','agency_models');
      $array_of_user_xs = array('client','model');

      $iterator = new MultipleIterator();
      $iterator->attachIterator(new ArrayIterator($array_of_user_xs_database_name));
      $iterator->attachIterator(new ArrayIterator($array_of_user_xs));

      foreach($iterator as $index => $value){

      $user_xs_database_name= $value[0];
      $user_x= $value[1];
      $User_x= ucfirst($user_x);

      $db_servername_getSearched[$User_x]="localhost";
      $db_username_getSearched[$User_x]="jd";
      $db_password_getSearched[$User_x]="1234";
      $db_name_getSearched[$User_x]= $user_xs_database_name;

      $db_connect_getSearched[$User_x]= new mysqli ($db_servername_getSearched[$User_x],$db_username_getSearched[$User_x],$db_password_getSearched[$User_x],
      $db_name_getSearched[$User_x]);

      $db_query_getSearched[$User_x]= "SELECT uid, photo, CONCAT(first_name, ' ', last_name) AS name, signature_name, phone_number, email
      FROM '.$user_x.'s WHERE CONCAT_WS(' ','.$user_x.'s.first_name,'.$user_x.'s.last_name) LIKE '%".$search_user_input."%'
      OR signature_name LIKE '%".$search_user_input."%' OR phone_number LIKE '%".$search_user_input."%' OR email LIKE '%".$search_user_input."%'";

      $db_result_getSearched[$User_x]= $db_connect_getSearched[$User_x]->query($db_query_getSearched[$User_x]);

      if($db_result_getSearched[$User_x]-> num_rows >= 1){

      while($db_row_getSearched[$User_x]= $db_result_getSearched[$User_x]->fetch_assoc()){

      ?>

      <h1>
      <?php

      echo $db_row_getSearchedModel["photo"];

      ?>

      </h1>

      <?php
      }
      }
      }

      ?>

      And now i'm getting these errors

      Notice: Trying to get property 'num_rows' of non-object in C:\example path\test.php on line 33

      Notice: Trying to get property 'num_rows' of non-object in C:\example path\test.php on line 33

      If this method does work I know I will get this section to repeat twice echo $db_row_getSearchedModel["photo"]; but for simplicity I just wanted you guys to know what I mean by calling a unique variable.

      So if you have a user named "wilbur" you have an entire table named "wilburs" just to contain wilbur's name and number and so on? I think there is a major design problem right there.

      Also

      while($db_row_getSearched[$User_x]= $db_result_getSearched[$User_x]->fetch_assoc()){
      

      You're replacing your entire result set with its first row—no surprise that it no longer works like a result set afterwards.

      o8codex I just wanted you guys to know what I mean by calling a unique variable.

      Not at all clear, still, sorry.

      P.S. When posting code, put it between [code=php]...[/code] tags for readability.

        Write a Reply...