lfernando Posted August 16, 2010 Share Posted August 16, 2010 Hi everyone!! I just started learning PHP two weeks ago and I hope someone can help me!! I need to do a find and replace on a string, and each replace needs to have an unique id, and if that unique id exists in a table then return the value on the table. Make sense? So like "find all the Xs in the string, replace with "X1, X2, X3...", then if "X3' exists on TableB, return value "X3 is on the table and has a value of Y3". I actually got this to work already but it takes a long time to do it so I'm hoping someone could give me some advice on how to make it more EFFICIENT: // PART ONE, find all "X" and replace with unique_id for ($count = 1; $count <= strlen($string); $count++) // do this loop as many times as there are characters in $string { $unique_id = "replacement_" . $count; // give each replacement an unique id (replacement_1, replacement_2, replacement_3, etc..) $string = preg_replace("X", $unique_id, $string , 1); // find X and replace it with the $unique_id in $string, and only do this ONCE } $count_replacements = substr_count($string,"replacement_"); // count how many replacements occured in total // PART TWO, find all unique_ids in tableB and echo the unique_id_value for ($count = 1; $count <= $count_replacements; $count++) // do this loop as many times as there were replacements { $unique_id = "replacement_" . $count; // set the unique_id of each replacement $show_tableB = mysqli_query($link, 'SELECT * FROM tableB'); // select the unique_ids and the unique_id_values in TableB while ($row = mysqli_fetch_array($show_tableB)) { $tableBs[] = array('unique_id' => $row['unique_id'], 'unique_id_value' => $row['unique_id_value']); } foreach($tableBs as $tableB): // for each entry in TableB, if the unique_id in TableB matches the unique_id of the replacement, return the unique_id_value if ($tableB['unique_id'] == $unique_id) { echo $unique_id . " is on TableB and it has a value of ". $tableB['unique_id_value'] } endforeach; } The problem with this is: its not very efficient. If $string has 500 charachters, it does the "PART ONE" 500 times. Then, say it found 300 Xs, it does "PART TWO" 300 more times. And every time it does "PART TWO", it checks all entries in TableB (which could be 200 or more). So, that's it. Anyone has a better idea of how to do this?? Thanks!!!! Quote Link to comment Share on other sites More sharing options...
Ninjakreborn Posted August 16, 2010 Share Posted August 16, 2010 Get the ID # in a variable. Get the value in another variable (via the database) and then run an str_replace on the string. It's the fastest method for simple find/replace logic. So basically take the ID and hit the database to get the value. Have the id as $find_id $replace_value (holding the DB value you wanted to replace the ID with). Then run an str_replace. Only use regex if you have an advanced pattern you have to match with. Quote Link to comment Share on other sites More sharing options...
Psycho Posted August 16, 2010 Share Posted August 16, 2010 Well you have a significant flaw in the logic. You have a loop that runs for each character in the string. Then inside the loop you use preg_replace(). There is absolutely no correlation between the loop and preg_replace(). On the first iteration of the loop preg_replace() will replace the first instance of the search string - regardless if it is at the first character position or not. So, if you have a 200 character string with 5 "x" characters, all the replacements are done after the 5th iteration of the loop - but the code will run the loop 195 more times! Secondly - and more importantly - you are running queries in a loop. This is a HUGE waste of resources. Never, ever run queries in a loop. Query the data you need and process the records in PHP. Besides that loop has no purpose since you are running the same query every time without any where clause. This could be made much more efficient if you separated the string and the ID in the database. But, this shoudl work for what you have //Define search and replacement strings $searchStr = "X" $replaceStr = "replacement_": //Query all possible replacements in table and put into array $query = "SELECT `unique_id`, `unique_id_value` FROM `tableB` WHERE `unique_id` LIKE '{$replaceStr}%'"; $result = mysqli_query($link, $query); $replaceAry = array(); while ($row = mysqli_fetch_array($result)) { $replaceAry[$row['unique_id']] = $row['unique_id_value']; } //Create loop to replace each search string ONLY WHILE the search string exists $idCount = 0; while(strpos($string, $searchStr)!==false) { $idCount++; //Increment the ID $idStr = $replaceStr.$idCount; //If $idStr exists in the replaceAry echo comment to that effect if (isset($replaceAry[$idStr])) { echo "{$idStr} is on TableB and it has a value of {$idStr}<br />\n"; } //Replace the search string with replacement and unique ID $string = preg_replace($searchStr, $idStr, $string, 1); } Quote Link to comment Share on other sites More sharing options...
lfernando Posted August 16, 2010 Author Share Posted August 16, 2010 Hi MJ, First of all, thank you so much for your quick reply!! In my real code, I wasnt actually running the query inside the loop, but it was still taking a long time. This is how your code worked for me: $searchStr = "X"; $replaceStr = "replacement_"; $result = mysqli_query($link, 'SELECT * FROM tableB WHERE `unique_id` LIKE "{$replaceStr}%"'); //Query all possible replacements in table and put into array while ($row = mysqli_fetch_array($result)) { $tableBs[] = array('unique_id' => $row['unique_id'], 'unique_id_value' => $row['unique_id_value']); } $idCount = 0; //Create loop to replace each search string ONLY WHILE the search string exists while(strpos($replaced, $searchStr)!==false) { $idCount++; //Increment the ID $unique_id = $replaceStr.$idCount; foreach($tableBs as $tableB): //If $unique_id exists in the table, echo the right value if ($tableB['unique_id'] == $unique_id) { $unique_id = "The ID " . $unique_id . "was found and it has the value of". $tableB['unique_id_value']; } endforeach; //Replace the search string with replacement and unique ID $string = preg_replace($searchStr, $idStr, $string, 1); } (with a few changes...) and it taks less than a split second!! Thank you so much!! Now, any idea how I make it work for both X and x? (ignore case?). Quote Link to comment Share on other sites More sharing options...
lfernando Posted August 16, 2010 Author Share Posted August 16, 2010 Ahh, I managed to figure it out myself. probably not the best way, but it works: just used two variables: $searchStrUpperCase = "X"; $seachStrLowerCase = "x"; then added OR to the while loop while(strpos($replaced, $searchStrUpperCase)!==false OR strpos($replaced, $searchStrLowerCase)!==false) Thanks again for your help! Quote Link to comment Share on other sites More sharing options...
Psycho Posted August 16, 2010 Share Posted August 16, 2010 Doesn't anyone read the freak'n manual?! No need to create two search strings. Just use stripos() to "Find position of first occurrence of a case-insensitive string" http://us.php.net/manual/en/function.stripos.php Quote Link to comment Share on other sites More sharing options...
lfernando Posted August 16, 2010 Author Share Posted August 16, 2010 emm..geez...like i said, i just started less than two weeks ago, i do use the manual alot but as i'm new sometimes i'm a bit overwhelmed by it. sorry if i ofended you :/ Quote Link to comment Share on other sites More sharing options...
Psycho Posted August 16, 2010 Share Posted August 16, 2010 No offense taken. It's jsut that PHP has one of the best online manuals in my opinion and it seems people do not take advantage of it. When using a new function you should always read the manual for that function to understnad the imput parameters and the possiblel output. Additionally, right after the examples for a function is a list of related functions. I can't tell you how many times I was reviewing a function that "kind of" did what I wanted but not exactly and then found exactly what I needed in the related functions section. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.