PHP Alternative to using a query within a loop - php
I was told that it is a bad practice to use a query (select) within a loop because it slows down server performance.
I have an array such as
Array ( [1] => Los Angeles )
Array ( [2] =>New York)
Array ( [3] => Chicago )
These are just 3 indexes. The array I'm using does not have a constant size, so sometimes it can contain as many as 20 indexes.
Right now, what I'm doing is (this is not all of the code, but the basic idea)
For loop
query the server and select all people's names who live in "Los Angeles"
Print the names out
Output will look like this:
Los Angeles
Michael Stern
David Bloomer
William Rod
New York
Kary Mills
Chicago
Henry Davidson
Ellie Spears
I know that's a really inefficient method because it could be a lot of queries as the table gets larger later on.
So my question is, is there a better, more efficient way to SELECT information based on the stuff inside an array that can be whatever size?
Use an IN query, which will grab all of the results in a single query:
SELECT * FROM people WHERE town IN('LA', 'London', 'Paris')
To further add to MrCodes answer, if you start with an array:-
$Cities = array(1=>'Los Angeles', 2=>'New York', 3=>'Chicago');
$query = "SELECT town, personname FROM people WHERE town IN('".implode("','", $Cities)."') ORDER BY town";
if ($sql = $mysqliconnection->prepare($query))
{
$sql->execute();
$result = $sql->get_result();
$PrevCity = '';
while ($row = $result->fetch_assoc())
{
if ($row['town'] != $PrevCity)
{
echo $row['town']."<br />";
$PrevCity = $row['town'];
}
echo $row['personname']."<br />";
}
}
As a database design issue, you probably should have the town names in a separate table and the table for the person contains the id of the town rather than the actual town name (makes validation easier, faster and with the validation less likely to miss records because someone has mistyped their home town)
As #MrCode mentions, you can use MySQL's IN() operator to fetch records for all of the desired cities in one go, but if you then sort your results primarily by city you can loop over the resultset keeping track of the last city seen and outputting the new city when it is first encountered.
Using PDO, together with MySQL's FIELD() function to ensure that the resultset is in the same order as your original array (if you don't care about that, you could simply do ORDER BY city, which would be a lot more efficient, especially with a suitable index on the city column):
$arr = ['Los Angeles', 'New York', 'Chicago'];
$placeholders = rtrim(str_repeat('?, ', count($arr)), ', ');
$dbh = new PDO("mysql:dbname=$dbname", $username, $password);
$qry = $dbh->prepare("
SELECT city, name
FROM my_table
WHERE city IN ($placeholders)
ORDER BY FIELD(city, $placeholders)
");
if ($qry->execute(array_merge($arr, $arr))) {
// output headers
echo '<ul>';
$row = $qry->fetch();
while ($row) {
$current_city = $row['city'];
// output $current_city initialisation
echo '<li>'.htmlentities($current_city).'</li><ul>';
do {
// output name $row
echo '<li>'.htmlentities($row['name']).'</li>';
} while ($row = $qry->fetch() and $row['city'] == $current_city);
// output $current_city termination
echo '</ul>';
}
// output footers
echo '</ul>';
}
That's the purpose of prepared statements. You bind a placeholder to a value, and use it like a variable, with the same query. Since the query hasn't changed, you minimize the communication with the mysql server, resulting in an efficiency boost.
Example using PDO:
$cities = array(
"Los Angeles",
"New York",
"Chicago"
);
try {
//Change database parameters here (user, pass, database name)
$db = new PDO("mysql:host=localhost;dbname=users", "user", "pass");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $db->prepare("SELECT * FROM `users` WHERE `city` = :city");
foreach ($cities as $city) {
$stmt->bindValue(":city", $city);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
//Output data here. You can format it however you'd like
var_dump($city, $result);
}
}
catch (PDOException $e) {
//Error handling here
}
Related
How to insert data in table from RETS search query?
I am trying to insert data in a table. I am using a search query and then FetchRow in while condition to fetch the data in row and want to insert this row in a table directly. I have given the structure of table in this link. The code for insert values in table in while condition is here: require_once (ABSPATH . 'wp-admin/includes/upgrade.php'); $query = "(922=MIAMI), (131=2014-12-16+)"; $search = $rets->SearchQuery("Property", $class, $query, array("SystemName" => 1, 'Limit' => 1 )); if ($rets->NumRows($search) > 0) { $fields_order = $rets->SearchGetFields($search); $this_record = array(); while ($record = $rets->FetchRow($search)) { foreach ($fields_order as $fo) { echo $this_record[] = $record[$fo]; } $comma_fields_order = implode(",", $fields_order); $comma_record = implode(",", $this_record ); echo $dfsdf = "INSERT INTO rets_property_2 (".$comma_fields_order.") VALUES (" .$comma_record.")"; dbDelta($dfsdf); } } If I echo the insert query this is : INSERT INTO rets_property_2 (sysid,1,10,11,13,14,17,19,21,22,25,28,29,30,31,39,45,47,53,54,56,57,59,61,62,63,66,69,71,73,74,75,76,80,92,93,97,98,99,100,102,106,109,110,111,113,114,115,125,126,127,128,129,131,134,136,137,143,144,149,150,157,158,160,161,164,165,167,178,180,181,188,190,193,194,195,206,207,214,223,225,226,227,229,230,232,242,245,246,247,248,250,252,261,263,264,266,267,268,274,275,283,294,295,296,314,315,319,320,321,322,324,326,327,328,329,330,331,332,333,334,335,336,337,338,341,342,347,348,351,352,353,354,355,356,360,361,362,363,364,366,367,368,369,370,372,373,374,375,376,881,886,891,893,894,922,924,1088,1218,1223,1329,1333,1335,1337,1339,1358,1410,1462,1463,1464,1465,1473,1485,1486,1487,1488,1490) VALUES (305578689,Condo/Co-Op/Villa/Townhouse,33131,,,,3003,42,None,,4,,,,Entry Level,Miami Board of Realtors,0,,Cbs Construction,,,Electric Cooling,,Miami-Dade County,,,,ASIA CONDOMINIUM,,,,,,2008-06-12T14:19:47,5,2630,,,,,2,,1,Electric Heat,Condo,9,Yes,ASIA IS BRICKELL KEY ISLAND'S PREMIER LUXURY BLDG. W/ ONLY 123 UNITS, PRIVATE ELEVATORS, SPECTACULAR VIEWS AND MUCH MORE.,,,,,3813,2014-12-23T09:16:55,EWM 09,0648464,6000000,,Daysi Morey,,1,M1242705,,No,,Vacant,EWM Realty International,305-329-7600,,Maximum 20 Lbs,Yes,,0043,,Funding,Yes,5000000,T,EXOTIC LUXURY AND STRIKING DESIGN MAKES ASIA THE # 1 RESIDENCE FOR THE MOST DISCRIMINATING OWNER. SMART TECHNOLOGY, PRIVATE ELEVATORS, FLOOR TO CEILING WINDOWS, BREATHTAKING VIEWS OF BISCAYNE BAY, BAYSIDE, MIAMI RIVER AND MIAMI;S EXHUBERTANT SKYLINE. 12' CIELINGS,MARBLE BATHROOMS, GOURMET CHEF STYLE KITCHEN, LUXE BATH WITH FRENCH VANILLA IMPORTED MARBLE AND MUCH MORE MAKES THIS REMARKABLE RESIDENCE A SANCTUARY NESTLED IN BISCAYNE BAY. ALLOW 24 HOURS NOTICE FOR SHOWINGS.,,,6,6,,,0,,2014-01-24T10:02:22,Active-Available,BRICKELL KEY BLVD.,900,,,4663,Tax Reflects City & County Tax,New Construction,,,42,,0,2007,,None,Yes,Bay Front,2008,Under Construction,Bike/Jog Path,Elevator,0,No Approvals,,,ASIA CONDOMINIUM,,No,,,,Dishwasher,Dryer,Microwave,Electric Range,Refrigerator,Other Equipment/Appliances,Open Balcony,,30,Wood Floors,,Condominium,Elevator,Foyer Entry,Other Interior Features,0,All Amenities,Building Exterior,Cable Tv,1920,365,,,1,1 Assigned Space,2 Or More Spaces,,,0,Other Restrictions,,Elevator Secure,Garage Secured,Lobby Secured,,Condo 5+ Stories,34,Other,Condo,Corner Unit,High Rise,123,,Bay,,900 BRICKELL KEY BLVD. # 3003,,,,0,Miami,Florida,,,http://instatour.propertypanorama.com/instaview/mia/M1242705,2009-02-19T16:00:26,,,,ASIA CONDO UNIT 3003,1573.564,No HOPA,,,2389,No,No,No,No,900 BRICKELL KEY BLVD. 3003,Yes,) But nothing is being inserted in the table. Where I am wrong? Is there any other method to insert the whole row directly given by fetchrow into the table? Please show me right direction. I think the problem is with the data type, number and varchar. Then how can I format the insert query where data is coming from the array? I know my insert query is wrong. If I do try this INSERT INTO `rets_property_2` ( `sysid` , `1` ) VALUES ( 526252, 'dsfsdfsdf' ) this will work fine. But the question is How can I get the values from array if the value is string then 'somestringvalue' and if the value is integer then only integervalue and then wrapping them in a array?
$query = "(922=MIAMI), (131=2014-12-16+)"; $search = $rets->SearchQuery("Property", $class, $query, array("SystemName" => 1, 'Limit' => 5 )); if ($rets->NumRows($search) > 0) { $fields_order = $rets->SearchGetFields($search); while ($record = $rets->FetchRow($search)) { //var_dump($fields_order); foreach ($fields_order as $fo) { if( is_numeric($record[$fo])){ $valuesd[] = $record[$fo]; }else{ $onlyconsonants = str_replace("'", "", $record[$fo]); $valuesd[] = "'".$onlyconsonants."'"; } } $comma_fields_order = "`".implode("`,`", $fields_order)."`"; $valuestring = implode(",", $valuesd ); $wpdb->query("INSERT INTO rets_property_2 (".$comma_fields_order.") VALUES (".$valuestring.")"); unset($valuesd); $valuesd = array(); } /* end while */ } /* end if of number of row */
I would suggest using DBName column names instead of SystemName for your database table column names. I would also suggest using PDO to prepare/execute your statements. The below example should help you along: <?php $sysid = '1234' $property_1 = '1111 main' $stmt = $db->prepare("INSERT INTO table_name(`sysid`, `property_1`) VALUES( ?, ?)"); $stmt->execute(array($sysid, $property_1));
php foreach loop search mysql table with several words
I have a mysql table called foods with columns "id, name, addinfo, picname, mg1cup, mg100g". I have a form where the user can submit between 1-20 food names. The php file takes the submitted food names in an array called $terms[]. I need to search the sql table for all terms and return results for all columns for each of the terms. However, the results are only showing the first term submitted, repeated as many times as there are inputs (for example, if two words were inputted, the first term gets outputted in the results twice - instead of first word results, then second word results). I don't know what I'm doing wrong. Here's my code (I haven't added the function to sanitize the strings yet): <?php error_reporting(E_ALL); ini_set('display_errors', '1'); //connect to the wordpress (bluehost)DB require_once '../../../wp-config.php'; $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die('Could not connect to mysql'); $Db = mysql_select_db(DB_NAME, $link) or die('Could not select database.'); //check to see if the search term has a value, matches "name" column in DB, and if so, put it into an array called terms if (isset($_POST['terms'])) { $terms = ($_POST['terms']); if (count($terms) > 0 ) { $results=array(); foreach($terms as $term) { $sql = 'SELECT * from `wpqr_foods` WHERE `name` like "%'. $term .'%" ORDER BY name ASC'; $Q1 = mysql_query($sql); if(mysql_num_rows($Q1)) { while ($Res = mysql_fetch_assoc($Q1)) { $results[] = $Res; } } //$results = mysql_query($sql); $sql = 'SELECT * from wpqr_foods WHERE name LIKE "%'. $term .'%" ORDER BY name ASC'; $Q2 = mysql_query($sql); //get results if(mysql_num_rows($Q2)) { while ($Res = mysql_fetch_assoc($Q2)) { $results[] = $Res; } } } if (count($results) > 0 ) { foreach ($results as $CurRes ) { echo $CurRes['name']. "<br/>"; echo $CurRes['addinfo']. "<hr/>"; /* [id] => 5 [name] => Apples [value] => Yes [addinfo] => They can eat apples. They can also eat the skin of the apple and the leaves of the apple tree, but the tree leaves are high in calcium, so limit their intake. They can also chew on the apple tree branches. [picname] => apple [mgc1cup] => 5.8 [mgc100g] => 4.6 */ } } else { echo "(nothing entered)";//MEANS $TERM IS EMPTY } } else { echo "(nothing entered)";//means $_POST IS NOT SET (end of if(isset($_POST['term'])) { ) } } //function to sanitize array values from form function sanitizeString($var) { if (is_array($val)) { foreach ($val as $k => $v) { $val[$k] = htmlentities(strip_tags($v),ENT_QUOTES); } } else { $val = htmlentities(strip_tags($terms),ENT_QUOTES); } return $val; } ?> The HTML is <div class="my-form"> <form role="form" id="step1" method="post" action="/wp-content/themes/mia/vitcdata.php"> <p class="text-box"><label for="box1">Food <span class="box-number">1 </span></label><input type="text" name="terms[]" value="" placeholder="apples" id="box1" /> <a class="add-box" href="#">Add More</a></p> <p><input type="submit" value="Submit" /></p> </form> The form has dynamic form fields which users can add via javascript, and they can add up to 20 text inputs, in which all inputted terms get added to the $terms[] array. So, if I test it, use two fields, and input "apples" and "bananas", the results show all the data for "apples" repeated twice.
Check this, you can check a related question here: Using OR in LIKE Query in MySQL to compare multiple fields You might have to do something like this in your query. $sql = 'SELECT * from wpqr_foods WHERE name LIKE "%'. $term .'%" OR addinfo LIKE "%'. $term .'%" ORDER BY name ASC'; OR, $sql = 'SELECT * FROM `wpqr_foods` WHERE CONCAT(name, addinfo ) LIKE "%'. $term .'%" ORDER BY name ASC';
I would recommend the following two ways forward: It looks like the code block that queries the database and pushes results into $results is duplicated. You probably want to get rid of the duped block as that will create 2x results for each distinct term. I suspect what's actually getting passed to the server through the form is a string containing whitespace-separated (or commas, or whichever separator the user chose to enter) terms. Even though you've chosen to pass it (and receive it server-side) as an array, it is actually a string and you will have to explode it (or some other method) yourself into an array. To check if that's the case (and if you haven't do so already), somewhere inside the foreach ($terms as $term) loop you should inspect $term to see if it is what you expect it to be.
PDO Count & Loop Optimization
Information I am starting to notice a trend in my coding habits that I wonder if there is a better way to do it. Problem For the sake of an example, lets pretend I have a table that may have data in it, ideally I want to loop through the data if there is any, if not display an error message. Current Solution function countResults($type){ $STH = $this->database->prepare('SELECT COUNT(*) FROM table WHERE type = :type'); $STH->execute(array(':type' => $type)); return $STH->fetchColumn(); } if($class->countResults("1") != 0){ $STH = $this->database->prepare('SELECT * FROM table WHERE type = :type '); $STH->execute(array(':type' => $type)); while($row = $STH->fetch(PDO::FETCH_ASSOC)){ echo "Row Name:".$row['name']."<br />"; } } else { echo "None found"; } Attempts Made I have tried a solution of cutting this down by storing $STH->fetch(PDO::FETCH_ASSOC) into a variable then using if(!empty($var)){// loop code}; but it doesn't allow me to loop out the data correctly. Conclusion I understand this isn't a ground breaking bug that I am struggling to fix urgently, but I feel as if this is becoming a bad habit and there's a little nag in my mind that there is a smarter solution to this which I would love to learn before it turns into a habit! Feel free to ask questions if needed, Thank you.
Your approach is rather illogical than wrong. All you need is common sense. Imagine you're going to buy a six-pack. Are you getting cash from the pocket in two actions, or one? Are you really do like this: Reach into pocket, only to feel the money. There are some. Okay. Take the hand back and then reach again - for the money this time. Why not to reach just once, and buy your beer if you get enough, or say sorry if not? $STH = $this->database->prepare('SELECT * FROM table WHERE type = :type '); $STH->execute(array(':type' => $type)); $data = $STH->fetchAll(); if ($data) { foreach($data as $row) { echo "Row Name:".$row['name']."<br />"; } } else { echo "None found"; }
There are two options I would use. Option one, similar to what you are doing: $STH = $this->database->prepare('SELECT * FROM table WHERE type = :type '); $STH->execute(array(':type' => $type)); if ($STH->rowCount() > 0) while($row = $STH->fetch(PDO::FETCH_ASSOC)){ echo "Row Name:".$row['name']."<br />"; } } else { echo "None found"; } Note that the PHP manual for PDOStatement::rowCount() warns that this might not return the number of rows from a SELECT query on all database types. What I actually do, is separating the SQL logic from the display, usually by using the template engine Smarty. In that case you have two separate files: PHP: $STH = $this->database->prepare('SELECT * FROM table WHERE type = :type '); $STH->execute(array(':type' => $type)); $objects = $STH->fetchAll(); $template->assign("objects", $objects); // this assigns the array with all returned rows to the template. Smarty Template: {foreach from=$objects item=object} Row Name: {$object.name}<br /> {foreachelse} None found {/foreach} This will basically output the same, with separated logic. Both methods will prevent doing unnessecary queries or doing the same query twice.
I would do it this way, if anyone sees anything wrong please point it out: I prefer foreach because I can access the field name I like to get used to use count() instead of rowCount() because rowCount() can return 2 for an updated row, even if this query is a select, I feel like I could get used to it and have mistakes. I like to check if it returns false to debug. Normally I do a one-liner for this, so I can comment it out or remove it easily on production function myQuery(){ $STH = $this->database->prepare('SELECT * FROM table WHERE type = :type '); $STH->execute(array(':type' => $type)); $data = $STH->fetchAll(PDO::FETCH_ASSOC); if($data === false) return "SQL query Error"; // or a method/function that returns the actual error code/message"; if($data){ foreach($data as $k => $v) echo "$k: $v<br>"; // I actually prefer to return the array $data and handle the info elsewhere } else { "None Found"; } }
Generic while loop through mysql query result
I'm wondering if there's a way - using php - to loop through a mysqli query result and display the column name, and the data... so, Name => Joe Bloggs, Age => 23 effectively allowing me to change the query, without having to echo out each row individually.
You can get the column names by fetching the result rows 'associatively': $mysqli = new mysqli('localhost', 'user', 'password', 'dbname'); $result = $mysqli->query("SELECT Name, Age FROM user"); while (($row = $result->fetch_assoc()) !== null) { $output = array(); foreach ($row as $columnName => $columnValue) { $output[] = $columnName . ' => ' . $columnValue; } echo implode(', ', $output) . PHP_EOL; } Would output something like: Name => Joe Bloggs, Age => 23 Name => Another User, Age => 5 if you have two users in the user table.
Not sure what you mean. Then only way I understand your question (that makes sense to me) is to suggest you use "fetch_assoc" to iterate over your result set in order to gain easy access to the column names with which you can do as you please from then on. Maybe the "using php" is tripping me over.
Live search engine logic behind query
I have problems creating a multiple field live search engine using AJAX and PHP. Up to now there was no need to search for multiple fields, so I had a simple query that worked fine for only one field. Because of a live search using onkeyup function I recognized some problems. The first problem i need to explain: The structure of the table is quite simple: zipcode | city For example, someone enters 12345; of course this would be the zipcode. But what in case if someone enters 12345 hometown so the first keyword would be the zipcode, second the city? The keywords will be split by using preg_split('/[\s]+/', $search_term) so as a result I receive an array with the single keywords that will be searched for. in the case above it would be: key[0] => 12345 and key[1] => hometown. The query I use is like: $where = ""; $search_term = preg_split('/[\s]+/', $search_term); //splits the whole string into single keywords $total_search_terms = count($search_term); //counts the array-keys from $search_term foreach ($search_term as $key=>$single_term) { $where .= "`zipcode` LIKE '$single_term%' OR `city` LIKE '$single_term%' "; if ($key != ($total_search_terms - 1)){ //adds AND to the query in case in case of a non empty array-key $where .= " AND "; } } $query = $db->query("SELECT COUNT(*) FROM table WHERE $where"); ... Okay, so far so good. Now the problem is that the keywords can match each field again and again. To give further example: In case from above entering 12345 hometown it means that key[0] => 12345 can match field zipcode OR city. This condition is egual to key[1] => hometown, even this can match field zipcode OR city. So ,even when entering other way round: hometown 12345 means the same. And this is the first problem I have. I'm looking for a logic to structure the query. So in case of entering 12345 hometown I would like to have something like that: When key[0] => 12345 matches field zipcode dont check key[1] => hometown if that matches in zipcode OR city because key[0] matches already in zipcode so it´s quite logical that key[1] needs to be city. UPDATE Okay, to tell my second problem I would like you to have a look at the answer from david strachan He mentioned that a problem will be caused when the city contains more than one string. Let's say the search string would be something like: 12345 New York The keys would be: key[0] => 12345, key[1] => New, key[2] => York Okay, now the problem is that I could check if one of the keys contains integers or not and in case of a string-length of exactly 5 I know that it will be the zipcode. key[0] => 12345 //if ( stringlen(key[0|) === 5) === true && is_int(key[0]) === true) {zipcode} So far so good but the real problem is the logic behind the strings of the cities. My first thoughts were that I could say that all keys that do not contain integers must be the city so I could convert them into one key. key[1] => New, key[2] => York //if ( !is_int(key[1|) === true && !is_int(key[2|) === true) {$create_one_key = array_fill_keys(key[1], key[1]+key[2]);} Alright, but what in case I would like to add street names in the future? I do not know how to separate and test for street name and even for the city name.
Another approach is to use JQuery Autocomplete to search MySQL database. The following code uses PDO. <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" /> <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script> <link rel="stylesheet" href="/resources/demos/style.css" /> <script type="text/javascript"> jQuery(document).ready(function(){ $('#zipsearch').autocomplete({source:'suggest.php', minLength:2}); }); </script> <style type="text/css"> li.ui-menu-item { font-size:10px} </style> </head> <body> <h2>jQuery UI Autocomplete - With MySQL </h2> <form onsubmit="return false;"> Search: <input id="zipsearch" type="text" size ="60"/> </form> suggest.php require("dbinfo.php");//db connection strings // if the 'term' variable is not sent with the request, exit if ( !isset($_REQUEST['term']) ) exit; $term = $_REQUEST['term']; if (is_numeric($term)){ $query = "SELECT * from ziptest WHERE zip LIKE ? OR address LIKE ? LIMIT 0,10"; }else{ $query = "SELECT * from ziptest WHERE city LIKE ? OR state LIKE ? LIMIT 0,10"; } $term.="%"; // connect to the database try { $dbh = new PDO("mysql:host=$host;dbname=$database", $username, $password); $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); // Prepare statement $stmt = $dbh->prepare($query); // Assign parameters $stmt->bindParam(1,$term); $stmt->bindParam(2,$term); // setting the fetch mode $stmt->setFetchMode(PDO::FETCH_ASSOC); $stmt->execute(); $data = array(); while($row = $stmt->fetch()) { $data[] = array( 'label' => $row['address'] .', '. $row['city'] .', '. $row['state'] .', '.$row['zip'] , 'value' => "ID ".$row['id'] .': '.$row['address'] .', '. $row['city'] .', '. $row['state'] .', '.$row['zip'] ); } echo json_encode($data); } catch(PDOException $e) { echo "I'm sorry I'm afraid you can't do that.". $e->getMessage() ;// Remove or modify after testing file_put_contents('PDOErrors.txt',date('[Y-m-d H:i:s]'). $e->getMessage()."\r\n", FILE_APPEND); } // close the connection $dbh = null; DEMO
Check to see if $search_term[0] is string(city) or int(zipcode) by addition of 0 Then format query accordingly. $search_term = '1234 paisley'; $search_term = preg_split('/[\s]+/', $search_term); //splits the whole string into single keywords $total_search_terms = count($search_term); //counts the array-keys from $search_term $test = $search_term[0]+0;//If string returns 0 if($total_search_terms == 1){ if ($test == 0 ){ $where = "WHERE `city` LIKE `%$search_term[0]%`"; }else{ $where = "WHERE `zipcode` LIKE `%$search_term[0]%` "; } }else{ if ($test == 0 ){ $where = "WHERE `zipcode` LIKE `%$search_term[1]%` AND `city` LIKE `%$search_term[0]%`"; }else{ $where = "WHERE `zipcode` LIKE `%$search_term[0]%` AND `city` LIKE `%$search_term[1]%`"; } } $query = "SELECT COUNT(*) FROM table $where"; echo $query; One problem will be how you treat New York. I will leave you how to work this out. EDIT New York $total_search_terms > 2