You're doing it backwards. First put in the words you want, then put in the random letters.
Before you put in each successive word, choose the random path for that word, and then along that path, check that there aren't any non-matching letters. (E.g. if 'alphabet' crosses the word 'graph' in a place where they both have a letter 'a', it's okay; otherwise, find a different spot for 'alphabet'). Finally, after all the words are in place, go through the whole thing and put random letters in the spots that don't have letters. Or, if you can't find a place for all the words, start over again.
EDIT:
How to find letters in particular spots. Okay. So, taking a look at your code, you are doing something illogical here:
$rc['r'.$r.'c'.$c] = $characters[mt_rand(0,$max)];
You are creating a one-dimensional array out of, essentially, the product of two keys. Instead, you want to do a two-dimensional array. This makes complete sense because a) you have two keys, and b) word searches have two dimensions.
$rc[$r][$c] = $characters[mt_rand(0,$max)];
So, let's start at the beginning with everything rearranged. Please note that I have rewritten things to start your row/column count at 0 instead of 1 because that's the programming convention for arrays, and I'm not going to try to bend my brain around counting from 1 just for this.
$wrdList =array('four', 'banana', 'howl');
$row = 5; //six rows counting from 0
$col = 5; //six columns counting from 0
$rc = array(); //our tableau array
$directions = array('H', 'V', 'D');
foreach ($wrdList as $wrd)
{
$found = false; // by default, no spot has been found
$tries = $row*$col; // we will try a reasonable number of times to find a spot
while(!$found && $tries > 0) {
$wrdLen = strlen($wrd);
$dir = $directions[mt_rand(0,2)];
if ($dir =="H")
{
$limitRow = $row;
$limitCol = $col - ($wrdLen - 1);
}
elseif($dir=="D")
{
$limitRow = $row - ($wrdLen - 1);
$limitCol = $col - ($wrdLen - 1);
}
elseif ($dir=="V")
{
$limitRow = $row - ($wrdLen - 1);
$limitCol = $col;
}
$temprow = mt_rand(0,$limitRow);
$tempcol = mt_rand(0,$limitCol);
//this is my temporary placement array
$placement = array();
//let's use for loop so we can capitalize on having numeric keys
$r = $temprow;
$c = $tempcol;
for($w = 0; $w < $wrdLen; $w++) {
$thisChar = $wrd{$w};
//find array keys
if($dir == 'V' || $dir == 'D') {
$r = $temprow + $w;
}
if($dir == 'H' || $dir == 'D') {
$c = $tempcol + $w;
}
//look at the current tableau
if(isset($rc[$r][$c])) { //the intended spot has a letter
if($rc[$r][$c] == $thisChar) { //the intended spot's letter is the same
$placement[$r][$c] = $thisChar;
if($w == $wrdLen-1) { // this is the last letter
$found = true; // we have found a path
}
} else {
break; //this path doesn't work
}
} else {
$placement[$r][$c] = $thisChar;
if($w == $wrdLen-1) { // this is the last letter
$found = true; // we have found a path
}
}
}
if($found) {
//put the letters out of the temporary array and into the tableau
foreach($placement as $r=>$set) {
foreach($set as $c=>$letter) {
$rc[$r][$c] = $letter;
}
}
}
$tries--;
}
//handle the error where no spot was found for the word
if(!$found) {
//your error handling here
}
}
//random fillers
$characters = range('a','z');
$max = count($characters) - 1;
for($r = 0; $r <= $row; $r++) {
for($c = 0; $c <= $col; $c++) {
if(!isset($rc[$r][$c])) {
$rc[$r][$c] = $characters[mt_rand(0,$max)];
}
}
}