title: Why does PHP preg_match_all with PCRE_UTF8 give different results on CLI and via Apache/mod_php?
body: <p>The following code yields different results when run via CLI and via Apache/mod_php:</p>
  
  <pre><code>&lt;pre&gt;
  &lt;?php
  error_reporting(E_ALL);
  ini_set('display_errors', '1');
  
  echo setlocale(LC_ALL, 0)."\n";
  // echo setlocale(LC_ALL, "en_GB.UTF-8")."\n";
  
  $terms = array
  (
      //Always matches:
      "Label Generation",
      //Doesn't match when using u (PCRE_UTF8) modifier:
      "Receipt of Prescription and Validation of Patient Information",
  
  );
  
  $text       = "Some terms to match: ".implode(", ",$terms);
  $pattern    = "/(".implode(")|(", $terms).")/is";
  $regexps    = array
  (
     "Unicode"     =&gt; $pattern."u", //Add u (PCRE_UTF8) modifier
     "Non-unicode" =&gt; $pattern
  );
  
  echo "Text:\n'$text'\n";
  
  foreach($regexps as $type=&gt;$regexp)
  {
      $matches    = array();
      $total      = preg_match_all($regexp,$text,$matches);
  
      echo "\n\n";
      echo "$type regex:\n'$regexp'\n\n";
      echo "Total $type matches: ";
      var_dump($total);
      echo "\n$type matches: ";
      var_dump($matches[0]);
  }
  ?&gt;
  &lt;/pre&gt;
  </code></pre>
  
  <p>CLI output (correct):</p>
  
  <pre><code>&lt;pre&gt;
  /en_GB.UTF-8/C/C/C/C/C
  Text:
  'Some terms to match: Label Generation, Receipt of Prescription and Validation of Patient Information'
  
  
  Unicode regex:
  '/(Label Generation)|(Receipt of Prescription and Validation of Patient Information)/isu'
  
  Total Unicode matches: int(2)
  
  Unicode matches: array(2) {
    [0]=&gt;
    string(16) "Label Generation"
    [1]=&gt;
    string(61) "Receipt of Prescription and Validation of Patient Information"
  }
  
  
  Non-unicode regex:
  '/(Label Generation)|(Receipt of Prescription and Validation of Patient Information)/is'
  
  Total Non-unicode matches: int(2)
  
  Non-unicode matches: array(2) {
    [0]=&gt;
    string(16) "Label Generation"
    [1]=&gt;
    string(61) "Receipt of Prescription and Validation of Patient Information"
  }
  &lt;/pre&gt;
  </code></pre>
  
  <p>Apache/mod_php webserver results (incorrect - only matches strings when not using /u modifier):</p>
  
  <pre><code>/en_GB.ISO8859-1/C/C/C/C/C
  Text:
  'Some terms to match: Label Generation, Receipt of Prescription and Validation of Patient Information'
  
  
  Unicode regex:
  '/(Label Generation)|(Receipt of Prescription and Validation of Patient Information)/isu'
  
  Total Unicode matches: int(1)
  
  Unicode matches: array(1) {
    [0]=&gt;
    string(16) "Label Generation"
  }
  
  
  Non-unicode regex:
  '/(Label Generation)|(Receipt of Prescription and Validation of Patient Information)/is'
  
  Total Non-unicode matches: int(2)
  
  Non-unicode matches: array(2) {
    [0]=&gt;
    string(16) "Label Generation"
    [1]=&gt;
    string(61) "Receipt of Prescription and Validation of Patient Information"
  }
  </code></pre>
  
  <p>The web server fails to match both strings when using the /u (PCRE_UTF8) option.
  I have tried <code>setlocale(LC_ALL, "en_GB.UTF-8");</code> to match the web server locale to the CLI locale which it does successfully but it has no bearing on the output.
  I suspected an issue with the PCRE library but I don't understand how it can be different between CLI and web server - PHP reports the same library versions in both environments:
  PHP 5.4.14
  PCRE (Perl Compatible Regular Expressions) Support => enabled
  PCRE Library Version => 8.32 2012-11-30</p>
  
  <p>pcretest reports no UTF-8 support but despite this the CLI version yields the correct results</p>
  
  <pre><code>$&gt; pcretest -C
  PCRE version 8.32 2012-11-30
  Compiled with
    8-bit support
    No UTF-8 support
    No Unicode properties support
    No just-in-time compiler support
    Newline sequence is LF
    \R matches all Unicode newlines
    Internal link size = 2
    POSIX malloc threshold = 10
    Default match limit = 10000000
    Default recursion depth limit = 10000000
    Match recursion uses stack
  </code></pre>