When $q['phrases'] has multiple elements it generates (PhraseA|PhraseB|PhraseC) and checks for preg_match. It only checks once with the $regex. So queries like "PhraseA" "PhraseB" "PhraseC" matches documents which only includes one of three phrases, though the document still should include every WORDS in three phrases.
So instead of using $regex, added one more loop for phrases and checks preg_match for each one.