Kategorien
Development

PHP: Under_Score-Namen erzeugen (u.a. mit Laravel 4)

Für ein aktuelles Projekt musste ich in Laravel 4 einen sogenannten Under_Score-Dateinamen erzeugen.

Underscore vs. CamelCase

Es gibt im wesentlichen zwei Arten wie man Dateinamen erzeugen kann:

  • CamelCase = DasIstEinTestName
  • Underscore = Das_Ist_Ein_Test_Name

Es gibt tatsächlich einige Diskussionen was nun besser ist, aber das sei hier mal egal. Für mein Projekt benötigte ich auf jeden Fall explizit einen Underscore-Dateinamen.

Laravel 4 Bordmittel

Laravel 4 (ein PHP-Framework das ich verwende) bietet eine kleine Hilfsfunktion namens camel_case welche Zeichenketten in camelCase convertiert. Will man nun aber einen underscore-Namen bedarf es einer eigenen Umsetzung.

Class Helpers/UnderScoreName

Ich habe mir eine kleine Helfer-Klasse für diese Funktionalität geschrieben und werde diese nun kurz vorstellen. Die Klasse ist nicht Laravel-Spezifisch und kann mit vermutlich jedem PHP-Framework verwendet werden. Einige der verwendeten Syntax-Elemente (zB. [] als Kurzschreibweise für Arrays) sind allerdings nur in neueren PHP 5-Versionen verfügbar, könnten aber leicht ersetzt werden.

Für alle die den Artikel überspringen wollen: Die fertige Klasse findet ihr hier auf GitHub.

Idee

Die Idee ist ganz simpel. Ich will nur eine gewisse Anzahl Zeichen erlauben (a-z,A-Z,0-9,einige Sonderzeichen). Außerdem sollen Umlaute und manche Satzzeichen durch oe usw. ersetzt werden. Alle anderen Zeichen sollen rücksichtslos gelöscht bzw ignoriert werden. Zu guter letzt will ich, dass der erzeugte Name ein anständiges Ende hat, also nicht mit einem – oder _ o.ä. aufhört.

Umsetzung

Zuerst einmal definiere ich 3 Variablen, die in Arrays die erlaubten, zu ersetzenden und am Ende der Kette nicht erlaubten Zeichen enthalten. Dazu kommen noch zwei Variablen um später den (Datei)-Namen und die Dateiendung zu speichern.

class UnderScoreName {

 protected $allow = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
 '1','2','3','4','5','6','7','8','9','0','_','-'];

 protected $replace = ['ä'=>'ae','ö' => 'oe','ü' => 'ue', 'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue', '.' => '-', ':' => '-', ' ' => '_', '?' => '', '!' => '',',' => '-'];

 protected $forbidAtEnd = ['.',',','_','-'];

 protected $filename = '';
 protected $extension = '';

Als implementiere ich zwei Standard-Methoden: Der Konstruktor speichert über zwei Setter-Methoden (hier nicht eingefügt) die übergebenen Parameter in den zuvor angelegten Variablen. Der Weg über die Setter-Methoden ermöglicht es später einfach eine Validierung o.ä. hinzuzufügen.

Die __toString-Methode erlaubt es das Objekt später wie eine normale Zeichenkette zu benutzen. Sie ruft die render-Methode auf, die wir nachfolgend programmieren werden.

public function __construct($filename, $extension = null){
	$this->setFilename($filename);
	$this->setExtension($extension);
}

public function __toString(){
	return $this->render($this->filename,$this->extension);
}

Nun müssen wir natürlich noch den Under_Score_Namen erzeugen:

public function render($filename = null,$extension = null){

	// Split and walk string
	$array = str_split(trim($filename));
	$underScoreName = '';
	foreach ($array as $char) {
		if(array_key_exists($char, $this->replace) !== false){
			$underScoreName .= $this->replace[$char];
		}elseif(array_search($char, $this->allow) !== false){
			$underScoreName .= $char;
		}
	}

	// Remove unwanted chars from the end of the string
	while(array_search(mb_substr($underScoreName, -1), $this->forbidAtEnd)){
		$underScoreName = mb_substr($underScoreName, 0, -1);
	}

	// Add extionsion (lowercase)
	if($extension !== false){
		$underScoreName .= '.' . strtolower($extension);
	}

	return $underScoreName;

}

Im wesentlichen teilen wir die Zeichenkette in ein Array auf, das wir dann Zeichen für Zeichen durchlaufen.

Als erstes überprüfen wir, ob das aktuelle Zeichen im $replace-Array enthalten ist und demnach durch ein anderes ersetzt werden muss. Falls dies nicht der Fall ist, überprüfen wir, ob die Zeichenkette ein erlaubtes Zeichen in $allow ist. Wenn dem der Fall ist, wird es an die Zeichenkette angehängt. Falls beides nicht zustimmt wird es sich wohl um ein „verbotenes Zeichen“ handeln und demnach ignoriert.

Am Ende wird nun so lange unsere Zeichenkette gekürzt, bis am Ende der Kette kein Zeichen ist, das in $forbidAtEnd enthalten ist.

Sofern eine Dateiendung in $extension gespeichert ist, wird diese nun (in Kleinbuchstaben umgewandelt) angefügt.

Jetzt arbeitet die Klasse so, wie wir es wollen:

// Output 1: Name with illegal characters
$datename = new UnderScoreName('Ein §%$beispielhafter $Dateiname','jpEg');

echo $datename; // Output: Ein_beispielhafter_Dateiname.jpeg

echo '<br /><br />';

// Output 2: Change Extension
$datename->setExtension('pNg');

echo $datename; // Output: Ein_beispielhafter_Dateiname.png

echo '<br /><br />';

In Laravel 4 einbinden

Um diese Klasse möglichst „sauber“ in Laravel 4 benutzten zu können habe ich im app-Verzeichnis einen helpers -Ordner angelegt mit diversen Hilfsklassen. Um diesen in den Autoloader von Laravel mit einzufügen muss man die composer.json -Datei editieren und danach eventuell ein php artisan dump-autoload  ausführen.

    "autoload": {
        "classmap": [
            "app/commands",
            "app/controllers",
            "app/models",
            "app/database/migrations",
            "app/database/seeds",
            "app/tests/TestCase.php",

            // Add this line:
            "app/helpers"
        ]
    },

 

Download von GitHub

Ich habe die Klasse noch ein wenig um einige Funktionen erweitert und ordentlich dokumentiert. Wer diese Klasse gerne in seinem Projekt verwenden möchte findet sie, zusammen mit Beispielen und einigen erweiterten Klassen auf GitHub oder kann sie direkt hier downloaden.


Falls ihr die Klasse in einem eurer Projekte verwendet würde es mich freuen, wenn ihr davon in den Kommentaren berichten würdet.

Von Luke

Blogautor, Webdesigner, Programmierer, Tontechniker, Kameramann, Musiker, Christ, und vieles mehr

1 Antwort auf „PHP: Under_Score-Namen erzeugen (u.a. mit Laravel 4)“

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.