Search code examples
phpvalidationmysqlifilteringkeyword-search

How to filter keyword for integer, string and integer, string with dashes and integer based on keyword


I have implemented the search whose work is to find out the property records from database. The search is somewhat totally depends on typed keyword from user.

Suppose,

If user types keyword like 1234 or 4775 or 773 it should search records from zip column from database.

Next, If user types keyword like 6 S Surfway or 70 N Grove St or 1661-114 Old Country Rd it should search records from address column only from database.

Next, If user types keyword like Calverton or Freeport or Riverhead it should search records from town column only from database.

So, my problem is I am unable to filter these records based on the keyword user types in. My issue is to filter keyword based records from desired columns.

Here is the code I am using:

<?php
header('Content-Type: application/json');

$key        = $_REQUEST['keyword'];
$searchOp   = $_REQUEST['searchOp'];

if($searchOp==1 || $searchOp==6)
{
        $searchChk = "(`property_chk` = '1' OR `property_chk` = '6')";
    }else{
        $searchChk = "(`property_chk` = '$searchOp')";
    }

$data = array(
              'locations' => array(),
              'errors'=>array(),
              'success'=> true,
              );

if($db->connect_errno > 0){
    $data['errors'][] = $db->connect_error;
    die(json_encode($data));
}

$index = 0;

if(intval($key) >= 3){

$zipQuery = $db->query("SELECT zip FROM tbl_property WHERE zip like '%$key%' AND $searchChk GROUP BY zip LIMIT 0,5");
if($zipQuery->num_rows>0){
    while($row = $zipQuery->fetch_assoc()){
    $data['locations'][] = array(
        "value"=> $row['zip'],
        "altValue"=> null,
        "display"=> $row['zip'],
        "type"=> "zip",
        "propertyIndex"=> "",
        "index"=> $index
    );
    $index = $index + 1;
        }
    }

}elseif (!intval($key) && count($key) > 4){

$cityQuery = $db->query("SELECT ste,town FROM tbl_property WHERE town like '%$key%' AND $searchChk GROUP BY town LIMIT 0,5");
if($cityQuery->num_rows>0){
    while($row = $cityQuery->fetch_assoc()){
    $data['locations'][] = array(
        "value"=> $row['town'].', '.$row['ste'],
        "altValue"=> null,
        "display"=> $row['town'].', '.$row['ste'],
        "type"=> "city",
        "propertyIndex"=> "",
        "index"=> $index
    );
    $index = $index + 1;
        }
    }

}elseif (count($key) > 1){

$addrQuery = $db->query("SELECT addr FROM tbl_property WHERE addr like '%$key%' AND $searchChk GROUP BY addr LIMIT 0,5");
if($addrQuery->num_rows>0){
    while($row = $addrQuery->fetch_assoc()){
    $data['locations'][] = array(
        "value"=> $row['addr'],
        "altValue"=> null,
        "display"=> $row['addr'],
        "type"=> "address",
        "propertyIndex"=> "",
        "index"=> $index
    );
    $index = $index + 1;
        }
    }
}
$db->close();

header('Content-Type: application/json');
echo json_encode($data);

Solution

  • You could achieve this with some regex testing. Assuming the rules you are stated are that strict.

    $matches = array(); // We do not use it but has to be defined
    if (preg_match("/^([a-zA-Z ])+$/", $key, $matches)) {
    
        // Do search by city here
    
    } else if (preg_match("/^([0-9])+$/", $key, $matches)) {
    
        // Do search by postal code here
    
    } else if (preg_match("/^([a-zA-Z])*([0-9 -])+([a-zA-Z \.])+$/", $key, $matches)) {
    
        // Do search by address here
    
    }
    

    Example regex fiddles:

    Postal - https://regex101.com/r/qK8pL7/2

    City - https://regex101.com/r/yS1oF1/2

    Address - https://regex101.com/r/pZ7dT3/2

    These examples assume Postalcodes are always numbers and do not contain ANY other characters. Cities are assumed to always be alpha characters and/or spaces any other characters would make the match fail.

    Use the fiddles to update to possible other characters you want to allow to make for a better suited test for your needs

    In stead of a open else statement, you could also create a regex for address. That would be a little more tricky though and perhaps not applicable