Nick
Nick

Reputation: 93

Search Partial Query Given Array in PHP

I am trying to write a php function that displays people given a partial query of an ID. I currently have the code working to accept a fully query of the ID but cannot figure out a way to manipulate my code to return values for a partial string.

The Code

function display_person($id) {
    global $people;
    if(array_key_exists($id, $people)) {
        header('Content-type: application/json');
        echo json_encode($people[$id]);
    } else {
        header('HTTP/1.1 404 Not Found');
    }
}

The Array

$people = array(
'jjones' => array(
    'firstName' => 'Jim', 
    'lastName' => 'Jones', 
    'age' => 20, 
    'major' => 'Computer Science', 
    'phone' => '212-460-9393', 
    'email' => '[email protected]', 
    'state' => 'OH'
),
'asmith' => array(
    'firstName' => 'April', 
    'lastName' => 'Smith', 
    'age' => 19, 
    'major' => 'Mechanical Engineering', 
    'phone' => '913-939-3929', 
    'email' => '[email protected]', 
    'state' => 'WY'
),
'pstemple' => array(
    'firstName' => 'Pat', 
    'lastName' => 'Stemple', 
    'age' => 21, 'major' => 
    'Theater Performance', 
    'phone' => '917-222-2232', 
    'email' => '[email protected]', 
    'state' => 'NY'
),
'jjones1' => array(
    'firstName' => 'Janet', 
    'lastName' => 'Jones', 
    'age' => 22, 
    'major' => 'Botany', 
    'phone' => '817-332-9392', 
    'email' => '[email protected]', 
    'state' => 'CA'
),
'llerner' => array(
    'firstName' => 'Leon', 
    'lastName' => 'Lerner', 
    'age' => 18, 
    'major' => 'Biology', 
    'phone' => '315-444-3494', 
    'email' => '[email protected]', 
    'state' => 'OH'
),
'mmeyer' => array(
    'firstName' => 'Margret', 
    'lastName' => 'Meyer', 
    'age' => 24, 
    'major' => 'Interactive Media Studies', 
    'phone' => '219-333-0303', 
    'email' => '[email protected]', 
    'state' => 'OH'
),
'achaudhry' => array(
    'firstName' => 'Anik', 
    'lastName' => 'Chaudhry', 
    'age' => 19, 
    'major' => 'Management Information Systems', 
    'phone' => '914-555-5555', 
    'email' => '[email protected]', 
    'state' => 'NY'
),
'sdogg' => array(
    'firstName' => 'Snoop', 
    'lastName' => 'Dogg', 
    'age' => 42, 
    'major' => 'Botany', 
    'phone' => '414-333-2433', 
    'email' => '[email protected]', 
    'state' => 'CA'
),
'bclinton' => array(
    'firstName' => 'Bill', 
    'lastName' => 'Clinton', 
    'age' => 25, 
    'major' => 'Political Science', 
    'phone' => '933-440-3033', 
    'email' => '[email protected]', 
    'state' => 'AK'
)
);

Upvotes: 4

Views: 117

Answers (4)

Srinu M
Srinu M

Reputation: 76

function display_person($id)
{
    global $people;

    foreach ($people as $key => $value)
    {
        if (strpos($key, $id) === 0)
        {
            header('Content-type: application/json');
            echo json_encode($people[$key]) . "<br>";
        } else
        {
            header('HTTP/1.1 404 Not Found');
        }
    }
}

Upvotes: 0

Use similar_text() for your example...

Explanation :

Set a percentage of 80 for the similarity between the matches and those matched strings will be added in the $sim array. You can then json_encode() it finally.

The code...

function display_person_new($id,$people) {
    $arr = array_keys($people);
    foreach($arr as $v)
    {
        similar_text($id,$v,$percent);
        if($percent>80)
        {
            $sim[$v]=$people[$v];
        }
    }
    if(!empty($sim))
    {
    header('Content-type: application/json');
    echo json_encode($sim,JSON_PRETTY_PRINT);
    } else { header('HTTP/1.1 404 Not Found'); }
}

display_person_new('jjone',$people);

OUTPUT :

{
    "jjones": {
        "firstName": "Jim",
        "lastName": "Jones",
        "age": 20,
        "major": "Computer Science",
        "phone": "212-460-9393",
        "email": "[email protected]",
        "state": "OH"
    },
    "jjones1": {
        "firstName": "Janet",
        "lastName": "Jones",
        "age": 22,
        "major": "Botany",
        "phone": "817-332-9392",
        "email": "[email protected]",
        "state": "CA"
    }
}

Upvotes: 2

Phil
Phil

Reputation: 164796

First, create an array of matching keys. For example

$matchingIds = array_filter(array_keys($people), function($pid) use ($id) {
    // perform a case insensitive search for $id in $pid
    return stripos($pid, $id) !== false;
});

then, intersect this array with your $people keys

$matches = array_intersect_key($people, array_flip($matchingIds));
// array_flip allows us to flip the matching ID values into keys
// so we can intersect with the $people keys

if (count($matches)) {
    header('Content-type: application/json');
    echo json_encode($matches);
} else {
    http_response_code(404);
    echo 'No matches found';
}

and finally, I would do away with the global variable. Using them makes testing difficult and adds a dependency on global state (this is bad). Instead, inject the $people array into the function when you call it

function display_person($id, array $people) {
    ...
}

Upvotes: 1

Iłya Bursov
Iłya Bursov

Reputation: 24146

if you want to provide only 1 output, you can slightly modify your code to:

function display_person($query) {
global $people;

$foundid = false;
foreach ($people as $k => $v)
    if (stripos($k, $query) !== false)
    {
        $foundid = $k;
        break;
    }

if($foundid !== false) {
    header('Content-type: application/json');
    echo json_encode($people[$foundid]);
} else {
    header('HTTP/1.1 404 Not Found');
}
}

another approach is to find all possible variants (for this you need temporary array)

function display_person($query) {
global $people;

$foundid = array();
foreach ($people as $k => $v)
    if (stripos($k, $query) !== false)
    {
        $foundid[$k] = $v;
    }

if(count($foundid) > 0) {
    header('Content-type: application/json');
    echo json_encode($foundid); // NOTE: you need to change your JS code to accept array instead of 1 person
} else {
    header('HTTP/1.1 404 Not Found');
}
}

also, I suggest you to check whether $query is long enough, usually 3+ symbols

Upvotes: 3

Related Questions