脚本中的elseif语句太多了

I have just written a php script where I have had to use many elseif statements (i.e. some 300 or so); this makes the script very lengthy, and reduces code readability, which makes code debugging quite daunting. My query is under such circumstances how to do you handle long elseifs? Do you suggest something else apart from using elseif? I would love to hear.

I have found below a small excerpt of my php script where I check each line for specific words and process them.

while (! feof($readfile)) {
    //Read in the file line by line    
    $line = fgets($readfile, 4096);

    if (preg_match("/gold/", $line)) {

        //Call the user-defined function
        $line = myfunction($line, "gld");

        if(is_writable($file2)) { //Confirm that the file is writable.
             file_put_contents($file2, $line . PHP_EOL, FILE_APPEND);
             // Write the data
        }

    } elseif (preg_match("/men/", $line)) {

        //Call the user-defined function
        $line = myfunction($line, "mdo");

        if(is_writable($file2)) { //Confirm that the file is writable.
            file_put_contents($file2, $line . PHP_EOL, FILE_APPEND);
            // Write the data
        }

    } elseif (preg_match("/sac/", $line)) {

        //Call the user-defined function
        $line = myfunction($line, "sac");

           if(is_writable($file2)) { //Confirm that the file is writable.
               file_put_contents($file2, $line . PHP_EOL, FILE_APPEND);
               // Write the data
           }

    } else {
          echo "No match: " . $line;
    }

Using a foreach, were an array stores each pattern would make the code shorter and more readable. The code is not tested, but you should understand how to fix it if there is anything wrong.

$patterns = array(
    array('/gold/', 'gld'),
    array('/men/', 'mdo'),
    array('/sac/', 'sac')
);

while (!feof($readfile)) {
    $match = false;
    foreach($patterns as $pattern) {
        if(preg_match($pattern[0])) {
            $line = myfunction($line, $pattern[1]);
            if(is_writable($file2)) {
                file_put_contents($file2, $line . PHP_EOL, FILE_APPEND);
            }
            $match = true;
            break;
        }
    }
    if($match === false) {
        echo "No match: " . $line;
    }
}

Aside from efficient coding you can have a readable style of coding. By that i mean you write your code clean and for example you always use {} with your ifs or you always use : with your ifs and use good indents.

With your IDE you can define a style for yourself and reformat your codes. Of course you need a neat style.

i suggest you search about efficient PHP.

Good Luck

This is basically a variant of what @Karl already posted. Assuming the patterns to match are simple strings, using preg_match is overkill:

$rules = array(
    'gold' => 'gld',
    'men'  => 'mdo',
    'sac'  => 'sac',
);

while (!feof($readfile)) {
    $chunk = fgets($readfile, 4096);
    $result = null;
    foreach ($rules as $k => $v) {
        if (strpos($chunk, $k) !== false) {
            $result = myfunction($chunk, $v);
            break;
        }
    }
    if (! is_null($result))
        echo 'No match: ' . $chunk;
    elseif (is_writable($file2))
        file_put_contents($file2, $result . PHP_EOL, FILE_APPEND);
}

@Karl's answer is much more efficient, using the DRY principle, but if you are just looking for an alternative in other situations where you find yourself buried in elseif's, perhaps you will find switch() cleaner and easier to follow.

I agree that elseifs nested inside each other can get confusing. In the switch, your last "else" result would be the "default:" case switch.

    switch($line){

     case(preg_match("/gold/", $line)):

        //Call the user-defined function
        $line = myfunction($line, "gld");

        if(is_writable($file2)) { //Confirm that the file is writable.
             file_put_contents($file2, $line . PHP_EOL, FILE_APPEND);
             // Write the data
        break;

     case(preg_match("/men/", $line)) :

          //....   rest of cases and logic below


}