title: Creating a Search Function in PHP
body: <p><strong>TL;DR</strong></p>
  
  <p>How can I filter a mega-array based on exploded <code>$_POST['search']</code> to match search terms in the database?</p>
  
  <p><strong>Full spiel</strong></p>
  
  <p>I'm trying to build a search algorithm but I seem to be getting stuck with terms bigger than one word.</p>
  
  <p>The logic behind it (or desired logic I'm trying to implement) is this:</p>
  
  <p>I have 7 Fields to check against:</p>
  
  <blockquote>
    <p>Make <br />
    Model <br />
    Misc Name <br />
    Street Name <br />
    ID <br />
    CC <br />
    Year</p>
  </blockquote>
  
  <p>When a user only types a single search term it will check against these fields, then filter out the duplicates and return the results. I got it this far and then tried to implement "stricter search" where if the user types something like "Honda XL" then it should only return results with Honda and XL in the rows.</p>
  
  <p>I thought I could use <code>array_diff</code> and <code>array_filter</code> to achieve this (maybe I can, just not using it correctly) but results still appear with terms that <strong>don't include XL</strong>.</p>
  
  <p>Here are the important parts of my script:</p>
  
  <p>1) individual field search:</p>
  
  <pre><code>if (is_numeric($search)) {
      foreach ($numericFields as $key =&gt; $field)
      {
          $res = $handler-&gt;prepare($sql. '`'. $field .'` LIKE :search');
          $res-&gt;execute(array(':search' =&gt; '%'. $search[0] .'%'));
  
          $rows[$key. '-data'] = $res-&gt;fetchAll(PDO::FETCH_ASSOC);
      }
  } else {
      foreach ($fields as $key =&gt; $field)
      {
          $res = $handler-&gt;prepare($sql. '`'. $field .'` LIKE :search');
          $res-&gt;execute(array(':search' =&gt; '%'. $search[0] .'%'));
  
          $rows[$key. '-data'] = $res-&gt;fetchAll(PDO::FETCH_ASSOC);
      }
  }
  </code></pre>
  
  <p><strong>Note: <code>$search</code> is generated by <code>$search = explode(' ', $_POST['serach']);</code></strong></p>
  
  <p>2) Remove dupe values</p>
  
  <pre><code>$rows = array_map('unserialize', array_unique(array_map('serialize', $rows)));
  </code></pre>
  
  <p>3) where I try to match the exploded search terms to the values in the array:</p>
  
  <pre><code>foreach ($rows as $result)
  {
      $result = array_filter(
          $result,
          function($value)
          {
              return (count(array_diff($value, explode(' ', $_POST['search']))) &gt; 0);
          }
      );
  
      # then use the $result to build shizzle
  }
  </code></pre>
  
  <p>Let's say for examples sake, we keep using <code>Honda XL</code> as our search term, but things like <code>Honda CR</code> keep returning (and XL doesn't appear anywhere within the string).</p>
  
  <p>So it essentially builds a mega-array of the first search term then uses the other terms to filter down the results. Where am I going wrong?</p>
  
  <p><strong>Edit: JSON output as req. (generated from search term: Honda XL)</strong></p>
  
  <pre><code>[0…99]
  ​    0: {…}
  ​​​        attributes: {…}
  ​​​​            "data-cc": "600"​​​​
              "data-epid": "219723301"​​
              "data-make": "Honda"
  ​​​            "data-model": "XL"
  ​​​​            "data-street": "Transalp"
  ​​​​            "data-sub": "V"
  ​​​​            "data-year": "1999"
  ​​​​        &lt;prototype&gt;: Object { … }
  ​​​        checked: false
  ​​​        name: "Honda XL 600 1999 V Transalp"
  ​​​        value: "219723301"
  ​​​        &lt;prototype&gt;: Object { … }
  ​​    1: Object { name: "Honda CR 80 1980 R --", value: "219723391", checked: false, … }
  ​​    2: Object { name: "Honda SH i 150 2009 D --", value: "219723931", checked: false, … }
  ​​    3: Object { name: "Honda FJS 400 2012 A Silver Wing", value: "219723971", checked: false, … }
      4: Object { name: "Honda XL 250 1987 R --", value: "219723981", checked: false, … }
  </code></pre>
  
  <p>(only an example as real count of data is >3k) </p>