jobo: Codeoptimierung - wiederkehrende Elemente

Beitrag lesen

Hallo,

in meiner Search-Klasse habe ich zwei private Funktionen, die zu teilen im Code identisch sind:

  
	// sucht aus einer Datei alle Zeilen, in denen die übergebenen Wert in der Spalte zutriffen  
	private static function _getRowsByColsValue($tablePath, $colsHash) {  
		$fileHandle = @fopen($tablePath,"r");  
		$rows = array();  
		$firstRow = false;  
		if ($fileHandle) {  
			while (($row = fgetcsv($fileHandle)) !== false) {  
				//exclude empty lines  
				if (!is_array($row)) {  
					continue;  
				}  
				// Whitespaces/Leerzeichen am Anfang und Ende einer jeden Zelle entfernen  
				// keine Leerzeichen überhaupt in einer Zeile  
				if(trim(implode($row))) {  
					$row = array_map("trim",$row);  
					if($firstRow === false) {  
						$firstRowFlipped = array_flip($row);  
						$firstRow = $row;  
					} else {  
						$filter = true;  
						foreach($colsHash as $colName => $searchValue) {  
							if($row[$firstRowFlipped[$colName]] != $searchValue) {  
								$filter = false;  
							}							  
						}  
						if($filter) {  
							foreach ($row as $colNr => $cellValue) {  
								$rowAssoc[$firstRow[$colNr]] = $cellValue;  
							}  
							$rows[] = $rowAssoc;  
						}  
					}				  
				}  
			}	  
			// merci handle, go free  
			fclose($fileHandle);  
		}  
		self::$_rowsByColsValue = array_merge(self::$_rowsByColsValue, $rows);  
	}	  

Die Funktion öffnet eine CSV-Datei zum Lesen, durchläuft die Zeilen, kickt Zeilen mit nur Whitespaces raus, merkt sich dann, wann die erste verwertbare Zeile kommt, registriert diese als "erste Zeile" (weil sich daraus der Spaltentitel ergibt) und sucht dann in den weiteren Zeilen, das ist der "individuelle Teil", ob Zeilen mit bestimmten Spaltenwerten vorhanden sind und trägt diese dann ins Ausgabearray ein.

Die Funktion, die alle möglichen Werte einer Spalte in eine Liste füllt, ist im oberen Teil ident (Filehandle, while-Schleife, trimmen und kicken der Leerzeilen, merken der ersten Zeile). Erst ab da differiert sie:

  
	private static function _getValuesPerColumn($tablePath) {  
		$fileHandle = @fopen($tablePath,"r");  
		$rows = array();  
		$firstRow = false;  
		if ($fileHandle) {  
			while (($row = fgetcsv($fileHandle)) !== false) {  
				//exclude empty lines  
				if (!is_array($row)) {  
					continue;  
				}  
				// Whitespaces/Leerzeichen am Anfang und Ende einer jeden Zelle entfernen  
				// keine Leerzeichen überhaupt in einer Zeile  
				if(trim(implode($row))) {  
					$row = array_map("trim",$row);  
					if($firstRow === false) {  
						$firstRow = $row;  
					} else {  
						foreach($row as $colNr => $cellValue) {  
							if($firstRow[$colNr] != "Text" && $cellValue != "") {  
								self::$_possibleValuesPerColumn[$firstRow[$colNr]][$cellValue] = $cellValue;  
							}							  
						}  
					}				  
				}  
			}	  
			// merci handle, go free  
			fclose($fileHandle);  
		}  
	}  

1. Diesen doppelten (gecopied und gepasteten) Teil, kann ich ja nicht wirklich in eine Funktion auslagern. Oder?

2. Die Funktion _getValuePerColumn - die mir alle möglichen Werte eine bestimmten Zeile liefert, wird auf der Suchseite immer aufgerufen, weil damit die Selectbox befüllt wird. Für die View habe ich also:
$possibleValuesPerColumn = Search::getAllPossibleValuesPerColumn();

Wenn das Formular abgeschickt wurde, habe ich zusätlich noch

$possibleValuesPerColumn  Search::getRowsByColsValue($suchWerte);  

Schön wäre natürlich, wenn die Funktion "_getAllPossibleValuesPerColumn" beim Durchlaufen der CSV-Datei(en) gleich die passenden gesuchten Zeilen mitliefert, die mit getRowsByColsValue() ausgegeben werden - wenn denn das Formular abgeschickt wurde.

Andereseits ist es wohl auch eher unübersichtlich, wenn dann alles in einer "Monsterfunktion" steckt, der ich per Parameter noch mitgeben muss, ob nun Suchzeilen mit ausgegeben werden sollen oder nicht, um dann wohlmöglich als Rückgabe noch ein Hash-of-Hashes zu haben mit:

  
$possibleValuesPerColumn_AND_searchedRows = Search::getAllPossibleValuesPerColumnAndRowByColsValue($suchWerte);  
$possibleValuesPerColumn = $possibleValuesPerColumn_AND_searchedRows["possibleValuesPerColumn"];  
$row = $possibleValuesPerColumn_AND_searchedRows["rows"];  

Vielleicht ists auch manchmal einfach einfacher, mit redundantem Code zu leben?

Gruß

jobo