Versteckte Funktionen von PHP? [geschlossen]


174

Ich weiß, das klingt nach einer punktgenauen Frage, aber lassen Sie mich erklären, woher ich komme.

Nach dem College bekam ich einen Job in einem PHP-Shop. Ich habe dort anderthalb Jahre gearbeitet und dachte, ich hätte alles gelernt, was man über Programmieren lernen muss.

Dann bekam ich einen Job als Ein-Mann-Entwicklungshaus bei einem großen Unternehmen, in dem die ganze Arbeit in C # war. In meinem Engagement für diese Position begann ich eine Menge Blogs und Bücher zu lesen und erkannte schnell, wie falsch ich war zu glauben, ich wüsste alles. Ich habe etwas über Unit-Tests, Abhängigkeitsinjektions- und Dekorationsmuster, das Designprinzip der losen Kopplung, die Zusammensetzung über die Erbschaftsdebatte usw. gelernt und so weiter und so fort - ich nehme immer noch alles in mich auf. Unnötig zu erwähnen, dass sich mein Programmierstil im letzten Jahr grundlegend geändert hat.

Jetzt nehme ich ein PHP-Projekt in die Hand, das für das Start-up eines Freundes programmiert, und fühle mich im Gegensatz zur Programmierung in C # völlig eingeschränkt. Es stört mich wirklich, dass auf alle Variablen in einem Klassenbereich verwiesen werden muss, indem '$ this->' angehängt wird. Es ärgert mich, dass keine der IDEs, die ich ausprobiert habe, eine sehr gute Intelligenz hat und dass meine SimpleTest-Unit-Test-Methoden mit dem Wort "Test" beginnen müssen. Es macht mich verrückt, dass ich durch dynamische Typisierung nicht implizit angeben kann, welchen Parametertyp eine Methode erwartet, und dass Sie eine switch-Anweisung schreiben müssen, um Methodenüberladungen durchzuführen. Ich kann es nicht ertragen, dass Sie keine verschachtelten Namespaces haben können und den Operator :: verwenden müssen, um den Konstruktor der Basisklasse aufzurufen.

Jetzt habe ich nicht die Absicht, eine Debatte zwischen PHP und C # zu beginnen. Ich möchte vielmehr sagen, dass ich sicher bin, dass es einige PHP-Funktionen gibt, die ich entweder nicht kenne oder die ich noch nicht richtig benutze. Ich bin in meinem C # -Universum und habe Probleme, außerhalb der Glasschale zu sehen.

Also frage ich, was sind deine Lieblingsfunktionen von PHP? Was können Sie darin tun, was Sie in den .NET-Sprachen nicht können oder schwieriger sind?


Gebrochenes OO-Paradigma? Für mich ist es das schlimmste "versteckte" Feature, das Sie entdecken.
Knoopx

Diese Threads sind irgendwie lustig ... Weil für das Team, mit dem ich arbeite, "versteckte Funktion" eine Codephrase ist, die "Fehler" bedeutet. Und weißt du was ... Manchmal ist es nicht unbedingt gut, ein verstecktes Merkmal zu entdecken ...
Ganesh Shankar

@ Ganesh der Fehler eines Mannes ist ein verstecktes Merkmal eines anderen Mannes ...
Xeoncross

Antworten:


328

Dokumentation . Die Dokumentation bekommt meine Stimme. Ich habe keine gründlichere Online-Dokumentation für eine Programmiersprache gefunden - alles andere muss ich aus verschiedenen Websites und Manpages zusammensetzen.


60
Genau. Es ist großartig, www.php.net/function_name eingeben zu können und die meiste Zeit eine Referenz zu erhalten.
Allain Lalonde

1
Dies ist eine großartige Funktion von PHP, aber ich würde es nicht wirklich als versteckt bezeichnen ... Wenn Sie jemals nach Methodenparametern usw. gegoogelt haben, würden Sie auf php.net landen.
John Bubriski

27
Ich stimme auch zu. Das Beste am Handbuch sind die Benutzerkommentare. Ich habe selten gesehen, dass andere Dokumentationen diese haben. Sie können echte Edelsteine ​​enthalten. Der einzige Nachteil ist, dass sie meiner Meinung nach etwas zu früh beschnitten wurden.
Sander Marechal

3
@Phoexo "etwas weniger lesbar" ??? Ich habe MSDN nie verstanden und werde es auch nie verstehen, während PHP-Dokumente einfach und klar sind.
Lauris

3
Nicht zustimmen. Der einzige Grund, warum die Dokumentation "gut" ist, ist, dass einige der Benutzerkommentare alle Lücken in den offiziellen Notizen schließen.
Rob Howard

179

Arrays . Nach den Antworten auf diese Frage zu urteilen, glaube ich nicht, dass die Leute genau wissen, wie einfach und nützlich Arrays in PHP sind. PHP-Arrays fungieren gleichzeitig als Listen, Karten, Stapel und generische Datenstrukturen. Arrays sind im Sprachkern implementiert und werden überall verwendet, was zu einer guten CPU-Cache-Lokalität führt. Perl und Python verwenden beide separate Sprachkonstrukte für Listen und Karten, was zu mehr Kopieren und möglicherweise verwirrenden Transformationen führt.


11
PHP-Array-Elemente sind geordnet.
user8134

117
Mein erster Wechsel von PHP zu C # hätte mich fast umgebracht. In C # sind Arrays nur eine einfache Struktur mit einer statischen Größe und einem numerischen Index. In PHP sind Arrays das Klebeband des Universums!
Dinah

4
Ich stimme auch zu. Als ich mit Java für eine Uni-Aufgabe spielte, war ich verblüfft darüber, wie starr sie waren, überhaupt keine Flexibilität. Ich habe wirklich geschätzt, wie gut PHP-Arrays sind.
Christian

11
Ich bin sicher, PHP-Arrays sind großartig, aber 40 Stimmen für den Kommentar, der C # -Arrays schlägt? Wenn ein C # -Array nicht den Anforderungen entspricht, gibt es viele Optionen. ArrayList und generische Sammlungen sind beide sehr leistungsfähig. Es gibt zahlreiche Arten von Sammlungen für spezielle Anforderungen. Der einzige tatsächliche Vorteil von PHP in dieser Hinsicht ist, dass es keine Optionen bietet, aus denen sich ein Programmierer entscheiden muss. Sie verwenden entweder ein Array oder Sie haben keine indizierbare Variable.
G-Wiz

24
Auf der anderen Seite ist die Syntax für Arrays völlig schlecht. In vielen Skriptsprachen können Sie ein einfaches 2D-Array wie folgt erstellen: [[1, 2], [3, 4]]Vergleichen Sie dies mit der PHP-Version : array(array(1, 2), array(3, 4)).
Rene Saarsoo

167

Mit Stream-Handlern können Sie das "FileSystem" mit einer Logik erweitern, die meines Wissens in den meisten anderen Sprachen nur schwer möglich ist.

Mit dem MS-Excel Stream-Handler können Sie beispielsweise eine MS Excel-Datei folgendermaßen erstellen:

$fp = fopen("xlsfile://tmp/test.xls", "wb");
if (!is_resource($fp)) { 
    die("Cannot open excel file");
}

$data= array(
    array("Name" => "Bob Loblaw", "Age" => 50),  
    array("Name" => "Popo Jijo", "Age" => 75),  
    array("Name" => "Tiny Tim", "Age" => 90)
); 

fwrite($fp, serialize($data));
fclose($fp);

Ich glaube, dass Sie dies auch mit dem KIO-Framework tun können, aber das ist nur für KDE-basierte Desktop-Anwendungen verfügbar.
MiffTheFox

21
IMHO wäre ein richtiger OO-Ansatz viel sinnvoller als dieses Durcheinander mit Stream-Handlern. Ja, es ist niedlich, Excel-Dateien lesen / schreiben zu können, aber muss es so funktionieren?
Anti Veeranna

3
Vielleicht, aber dieser Ansatz fasst die Komplexität in einer Schnittstelle zusammen, die den meisten PHP-Entwicklern gemeinsam ist ... ohne dass sie objektorientierte Konzepte lernen müssen, die möglicherweise darüber hinausgehen.
Allain Lalonde

13
Wenn Sie mit Amazon S3 arbeiten, lesen Sie Zend_Amazon_S3, das eine Stream-Schnittstelle für URLs wie 's3: // {Bucket-Name} / Pfad' bietet.
Davidtbernal

Ich habe dies verwendet, um ein einfaches DSL für meine Ansichtsebene zu erstellen, indem ich einfach die PHP-Datei gelesen, einige Zeichenfolgen ersetzt und durch eval () übergeben habe. ZB habe ich es so gemacht, dass ich Short-Tags verwenden kann, wann immer ich möchte - und @ -> someVar mache, damit ich auf Daten auf Ansichtsebene zugreifen kann.
Jasper Bekkers

131

Magische Methoden sind Fall-Through-Methoden, die aufgerufen werden, wenn Sie unter anderem eine nicht vorhandene Methode aufrufen oder eine nicht vorhandene Eigenschaft zuweisen oder lesen.

interface AllMagicMethods {
    // accessing undefined or invisible (e.g. private) properties
    public function __get($fieldName);
    public function __set($fieldName, $value);
    public function __isset($fieldName);
    public function __unset($fieldName);

    // calling undefined or invisible (e.g. private) methods
    public function __call($funcName, $args);
    public static function __callStatic($funcName, $args); // as of PHP 5.3

    // on serialize() / unserialize()
    public function __sleep();
    public function __wakeup();

    // conversion to string (e.g. with (string) $obj, echo $obj, strlen($obj), ...)
    public function __toString();

    // calling the object like a function (e.g. $obj($arg, $arg2))
    public function __invoke($arguments, $...);

    // called on var_export()
    public static function __set_state($array);
}

Ein C ++ - Entwickler hier könnte bemerken, dass PHP das Überladen einiger Operatoren erlaubt, z . B. ()oder (string). Tatsächlich erlaubt PHP noch mehr Überladung, zum Beispiel den []Operator ( ArrayAccess ), das foreachSprachkonstrukt ( Iterator und IteratorAggregate ) und die countFunktion ( Countable ).


4
Als nützliches Beispiel dafür, was mit magischen Methoden erreicht werden kann, gehen Sie zu phpcodetips.blogspot.com/2008/07/domain-model-validation.html
grom

6
Nicht zustimmen. Dies ist weitaus schwächer als ähnliche Einrichtungen in Smalltalk, Ruby & Python (und vermutlich wurde es von einer dieser kopiert)
finnw

34
Die Tatsache, dass die Implementierung dieser Funktionalität durch PHP schwächer ist als in diesen anderen Sprachen, macht sie in PHP nicht weniger nützlich.
Allain Lalonde

2
__call()ist großartig in Frameworks mit map domain.com/controller/method/
alex

7
Magische Methoden sind auch langsam wie die Hölle. Verwenden Sie sie vorsichtig.
Alex Weinstein

95

Die Standardklasse ist ein ordentlicher Container. Ich habe erst kürzlich davon erfahren.

Anstatt ein Array zum Speichern mehrerer Attribute zu verwenden

$person = array();
$person['name'] = 'bob';
$person['age'] = 5;

Sie können eine Standardklasse verwenden

$person = new stdClass();
$person->name = 'bob';
$person->age = 5;

Dies ist besonders hilfreich, wenn Sie auf diese Variablen in einer Zeichenfolge zugreifen

$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";

43
"{$ person ['name']} ist {$ person ['age']} Jahre alt" funktioniert.
Kornel

27
"Person [Name] ist $ Person [Alter] Jahre alt" wird auch funktionieren ... Keine Anführungszeichen, keine Klammern :)
Majelbstoat

16
$ string = sprintf ("% s ist% d Jahre alt.", $ person ['name'], $ person ['age']);
Daniel Sloof

60
Während wir uns mit dem Thema befassen: (Objekt-) Array ("Name" => 'Bob', 'Alter' => 5)
Annika Backstrom

30
@majelbstoat: Das Herausnehmen der Anführungszeichen würde das Skript verlangsamen, da der PHP-Interpreter prüft, ob 'name' und 'age' mit define (...) festgelegt wurden. Es ist auch eine schlechte Praxis, wenn man bedenkt, dass es möglich ist, die Schlüssel, auf die jeweils zugegriffen wird, vollständig umzudrehen: define ('age', 'name'); definieren ('Name', 'Alter');
Brianreavis

90

Include-Dateien können einen Rückgabewert haben, den Sie einer Variablen zuweisen können.

// config.php
return array(
    'db' => array(
        'host' => 'example.org',
        'user' => 'usr',
        // ...
    ),
    // ...
);

// index.php
$config = include 'config.php';
echo $config['db']['host']; // example.org

@Peter SEHR nützlich für die Fehlerbehandlung von db-> localhost-Ausnahmen.
Talvi Watia

Es ist praktisch, um eine schnelle und schmutzige Konfigurationsdatei einzurichten.
Frank Farmer

Warum geben Sie dieses Array zurück? Wenn eine eingeschlossene Datei ein Array enthält, kann sie sofort beim Einschließen verwendet werden.
Fabrik

5
@fabrik, weil es eine globale Variable wäre und im gesamten Hauptbereich verfügbar wäre. Das ist ziemlich unangenehm, das ist viel besser.
Mikulas Dite

Ich habe an einem Projekt im Yii-Framework gearbeitet und dieses Projekt hat eine Konfigurationsdatei, in der das Array so zurückgegeben wurde. Jetzt verstehe ich, warum die Datei so war.
Oditiwebs.com

83

Sie können die Tatsache ausnutzen, dass der orOperator eine niedrigere Priorität hat als =dies:

$page = (int) @$_GET['page'] 
  or $page = 1;

Wenn der Wert der ersten Zuweisung ausgewertet wird, truewird die zweite Zuweisung ignoriert. Ein anderes Beispiel:

$record = get_record($id) 
  or throw new Exception("...");

7
Davon bin ich meiner Meinung nach nicht ganz überzeugt; Auch wenn es nicht fehleranfällig zu sein scheint, ist es kontraintuitiv und kann an sich zu Fehlern führen.
Thomasrutter

14
@Pies: Eine Möglichkeit ist der folgende, ziemlich unordentliche Code, um ehrlich zu sein: $ page = isset ($ _ GET ['page'])? (int) $ _ GET ['Seite']: 1; // Vorteil davon ist, dass keine Fehlerunterdrückung erforderlich ist.
DisgruntledGoat

3
Wenn Sie nach einer Ganzzahl suchen, können Sie stattdessen Folgendes verwenden: $ page = is_int ($ _ GET ['page'])? $ _GET ['page']: 1;
DisgruntledGoat

4
Es ist erwähnenswert, dass der Code nach ausgeführt orwird, wenn der Code vor orden numerischen Wert ergibt 0. So semantisch mag es bei so etwas weniger wahrscheinlich sein $_GET['page'], aber offensichtlich kann der Umstand eintreten und es ist gut, darauf zu achten.
Augenlidlosigkeit

3
Es ist auch erwähnenswert, dass der orOperator eine niedrigere Version des ||Operators ist. Außerdem +1, weil dies sehr ausdrucksstark ist und ich oft vergesse, dass es möglich ist. Es sollte öfter verwendet werden und es ist absolut klar, was es tut. Ich weiß allerdings nicht, wie "echte Männer" codieren, daher kann ich das nicht kommentieren.
Augenlidlosigkeit

80

__autoload()(Klassen-) Dateien unterstützt von set_include_path().

In PHP5 ist es jetzt nicht mehr erforderlich, lange Listen mit "include_once" -Anweisungen anzugeben, wenn eine anständige OOP ausgeführt wird.

Definieren Sie einfach eine kleine Gruppe von Verzeichnissen, in denen Klassenbibliotheksdateien ordnungsgemäß strukturiert sind, und legen Sie den Pfad für das automatische Einschließen fest:

set_include_path(get_include_path() . PATH_SEPARATOR . '../libs/');`

Nun die __autoload()Routine:

function __autoload($classname) {
    // every class is stored in a file "libs/classname.class.php"

    // note: temporary alter error_reporting to prevent WARNINGS
    // Do not suppress errors with a @ - syntax errors will fail silently!

    include_once($classname . '.class.php');
}

Jetzt wird PHP die benötigten Dateien bei Bedarf automatisch einbinden, wodurch Analysezeit und Speicherplatz gespart werden.


ist spl_autoload_register () besser zu verwenden?
alex

19
Natürlich! __autoload () ist PHP4, aber spl_autoload_register () ist eine zerstörungsfreie "Verkettung" von Autoloading-Methoden.
Willem

3
Eine praktische Funktion, aber die einzige Einschränkung ist, dass es etwas schwieriger ist, den Speicherort einer Klassendatei zu ermitteln, wenn Sie eine Instanz einer bestimmten Klasse finden. Durch die explizite Definition von Includes oben erhalten Sie eine endliche Liste der beteiligten Klassen und deren genaue Position.
Cory House

Es ist eine nette Funktion, aber nur, um die Situation zu umgehen, dass Code nicht vorkompiliert wurde, sodass es nicht weiß, wo die Klasse sein wird. Der große Nachteil dabei ist, dass Sie nicht zwei Klassen mit demselben Namen haben können, selbst wenn sie sich in unterschiedlichen Namespaces befinden.
Kibbee

3
Bitte beachten Sie das PSR-0-Angebot der PHP Standards Working Group (mit Entwicklern von ZF, Symfony, Doctrine, CakePHP, Solar usw.), wenn Sie das automatische Laden
Philippe Gerber

76

Leichtigkeit . Das Beste ist, wie einfach es für neue Entwickler ist, sich hinzusetzen und "funktionierende" Skripte zu schreiben und den Code zu verstehen.

Das Schlimmste ist, wie einfach es für neue Entwickler ist, sich hinzusetzen und "funktionierende" Skripte zu schreiben und zu glauben, den Code zu verstehen.

Die Offenheit der Community rund um PHP und die enorme Menge an PHP-Projekten, die als Open Source verfügbar sind, sind für jemanden, der in die Entwicklungswelt eintritt, viel weniger einschüchternd und können wie Sie ein Sprungbrett in reifere Sprachen sein.

Ich werde nicht so viele technische Fragen diskutieren wie ich, aber wenn Sie PHP als Community und nicht als Web-Sprache betrachten, eine Community, die Sie zu Beginn Ihrer Entwicklung eindeutig umarmte, sprechen die Vorteile wirklich für sich.


3
Auf jeden Fall ein guter Kommentar. Python war meine Muttersprache und es war großartig, aber der Mangel an Projekten, die ich verstehen konnte, hat eine Barriere geschaffen. Mit PHP kann ich so ziemlich alles in der Dokumentation nachschlagen und herausfinden ... die im Web verfügbaren Ressourcen sind erstaunlich.
Dscher

76

Variable Variablen und Funktionen ohne Zweifel!

$foo = 'bar';
$bar = 'foobar';
echo $$foo;    //This outputs foobar

function bar() {
    echo 'Hello world!';
}

function foobar() {
    echo 'What a wonderful world!';
}
$foo();    //This outputs Hello world!
$$foo();    //This outputs What a wonderful world!

Das gleiche Konzept gilt für Objektparameter ($ some_object -> $ some_variable);

Sehr sehr nett. Machen Sie das Codieren mit Schleifen und Mustern sehr einfach und es ist schneller und kontrollierter als eval (Thanx @Ross & @Joshi Spawnbrood!). T.


111
Variable Variablen machen den Code weniger lesbar und fehleranfälliger.
Elzo Valugi

8
Und die Leute benutzen das wirklich? Mann, ich würde es hassen, diese Quellen zu lesen.
Gary Willoughby

27
Variable Variablen sind eine der schlechtesten Funktionen, die PHP bietet.
Davidtbernal

10
9 Von 10 Variablenvariablen werden besser durch Arrays ersetzt, sodass Sie alle Daten an einem Ort haben und darüber iterieren können. Nur unter bestimmten Umständen können sie nützlich sein.
Jasper Bekkers

7
Bitte lassen Sie Neulinge diese "Funktion" nicht nutzen.
whiskeysierra

68

Mit dem können Sie Funktionen mit einer undefinierten Anzahl von Argumenten verwenden func_get_args().

<?php

function test() {

    $args = func_get_args();
    echo $args[2]; // will print 'd'
    echo $args[1]; // will print 3
}

test(1,3,'d',4);

?>

1
War gerade dabei dies zu posten. Ähnlich wie die Argumente-Eigenschaft in JS-Funktionen.
Alex

67

Ich liebe entfernte Dateien . Für die Webentwicklung ist diese Art von Funktion außerordentlich nützlich.

Müssen Sie mit dem Inhalt einer Webseite arbeiten? Eine einfache

$fp = fopen('http://example.com');

und Sie haben ein Dateihandle bereit, genau wie jede andere normale Datei.

Oder wie wäre es, eine entfernte Datei oder Webseite direkt in eine Zeichenfolge einzulesen?

$str = file_get_contents('http://example.com/file');

Die Nützlichkeit dieser speziellen Methode ist schwer zu übertreiben.

Möchten Sie ein Remote-Image analysieren? Wie wäre es über FTP?

$imageInfo = getimagesize('ftp://user:password@ftp.example.com/image/name.jpg');

Fast jede PHP-Funktion, die mit Dateien arbeitet, kann mit einer entfernten Datei arbeiten. Auf diese Weise können Sie Dateien sogar remote include()oder require()codieren.


2
Das ist so schön! Um dies zum Beispiel in Java zu tun, müssen Sie eine Unmenge von JAR-Dateien einschließen und dann viel Boilerplate-Code schreiben.
Kimble

16
"Auf diese Weise können Sie sogar Codedateien remote einschließen () oder anfordern ()." Natürlich ist es eine schreckliche, schreckliche Idee, eine Datei auf einem Server einzuschließen, den Sie nicht kontrollieren.
Frank Farmer

4
@Frank - ja, na ja, würde man davon ausgehen , dass Sie Code von einem Server Sie würden einschließlich tat Kontrolle.
Zombat

1
Die Aufnahme von Remote-Dateien ist ein häufiges Problem bei der PHP-Sicherheit: en.wikipedia.org/wiki/Remote_File_Inclusion#PHP .
Frank Farmer

63

strtr ()

Es ist extrem schnell, so sehr, dass Sie erstaunt sein würden. Intern verwendet es wahrscheinlich eine verrückte B-Baum-Struktur, um Ihre Übereinstimmungen nach ihren gemeinsamen Präfixen zu ordnen. Ich benutze es mit über 200 Such- und Ersetzungszeichenfolgen und es geht immer noch durch 1 MB in weniger als 100 ms. Für alle bis auf trivial kleine Strings ist strtr () sogar deutlich schneller als strtolower (), wenn es darum geht, genau dasselbe zu tun, selbst unter Berücksichtigung des Zeichensatzes. Sie könnten wahrscheinlich einen ganzen Parser mit aufeinanderfolgenden strtr-Aufrufen schreiben und es wäre schneller als die übliche Übereinstimmung mit regulären Ausdrücken, den Token-Typ herauszufinden, dies oder jenes auszugeben, die nächste Art von regulären Ausdrücken.

Ich schrieb einen Textnormalisierer, um Text in Wörter aufzuteilen, Kleinbuchstaben zu setzen, Satzzeichen zu entfernen usw. und strtr war mein Schweizer Taschenmesser, es schlug die Hosen aus regulären Ausdrücken oder sogar str_replace ().


1
Es ist wahrscheinlich schneller, weil es einzelne Zeichen ersetzt.
Statik

10
strtr () ersetzt nicht nur einzelne Zeichen. Es kann Teilzeichenfolgen beliebiger Länge durch andere Teilzeichenfolgen beliebiger Länge ersetzen, und es scheint immer noch sehr schnell zu sein.
Thomasrutter

1
Sie haben erwähnt, dass es in einigen Fällen schneller als strtolower war. Können Sie das beweisen? Ich habe einen kleinen Benchmark durchgeführt und festgestellt, dass er falsch ist.
Der Pixel-Entwickler

1
Ich fand heraus, dass es bei kleinen Zeichenfolgen mit beispielsweise 80 Zeichen langsamer als strtolower war und bei großen Zeichenfolgen mit beispielsweise 1 MB schneller. Es gibt wahrscheinlich jedes Mal einen Fixkosten-Overhead, wenn er aufgerufen wird. Ich habe einfach strtr verwendet ($ this-> string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); Die Zeichenfolge, an der ich arbeitete, war ein typischer englischer Text ("The quick brown fox", so etwas).
Thomasrutter

Ich habe gerade diesen Beitrag gelesen und dann bei Google gesucht und gefunden: simplemachines.org/community/index.php?topic=175031.0 Irgendeine Idee, welche richtig ist?
Flipper

61

Eine nicht so bekannte Funktion von PHP ist extract()eine Funktion, die ein assoziatives Array in den lokalen Namespace entpackt. Dies existiert wahrscheinlich für die autoglobale Abormination, ist aber sehr nützlich für das Templating:

function render_template($template_name, $context, $as_string=false)
{
    extract($context);
    if ($as_string)
        ob_start();
    include TEMPLATE_DIR . '/' . $template_name;
    if ($as_string)
        return ob_get_clean();
}

Jetzt können Sie verwenden render_template('index.html', array('foo' => 'bar'))und nur $foomit dem Wert "bar"erscheint in der Vorlage.


15
Ich würde mich über dich ärgern, weil du vorgeschlagen hast, dass extract () in irgendeiner Weise eine gute Funktion ist. Aber ich denke, dass die Verwendung ziemlich praktisch ist. Ich nehme an, es ist das einzige Mal, dass ich es dort gesehen habe, wo es eine gute Idee ist!
Thomasrutter

5
extrahieren () macht es kinderleicht, Ihr eigenes extrem leichtes Schablonensystem zu rollen. +1
Dinah

14
Die Umkehrung, compact (), ist ebenfalls gut: $ a = 1; $ b = 2; kompakt ('a', 'b'); // == Array ('a' => $ a, 'b' => $ b)
Annika Backstrom

2
Ja, das ist wahrscheinlich die einzig wirklich gute Verwendung von extract ().
Statik

4
Ich würde vorschlagen, in diesem Fall keine gebräuchlichen Wörter als Funktionsargumentnamen zu verwenden, da der $ -Kontext, aus dem Sie () extrahieren (), Werte in den Indizes 'as_string' oder 'template_name' enthalten könnte. Die Verwendung von EXTR_SKIP ist akzeptabel, verschiebt das Problem jedoch nur an eine andere Stelle (dh wenn die Vorlage einen $ as_string erwartet, erhält sie den falschen Wert dafür.)
Michał Tatarynowicz

52

Range () ist an sich nicht versteckt, aber ich sehe immer noch viele Leute, die iterieren mit:

for ($i=0; $i < $x; $i++) { 
    // code...
}

wann sie verwenden könnten:

foreach (range(0, 12) as $number) {
    // ...
}

Und Sie können einfache Dinge wie tun

foreach (range(date("Y"), date("Y")+20) as $i)
{
print "\t<option value=\"{$i}\">{$i}</option>\n";
}

3
Sie können foreach ($ array als $ key => $ value) {} ausführen, was noch einfacher ist.
SilentGhost

15
Es mag eine Mikrooptimierung sein, aber es ist erwähnenswert, dass sie für und während viel schneller und weniger speicherintensiv sind als foreach.
JAL

3
Sie sollten Python ausprobieren. Es ist so einfach wie "für i in Bereich (12)", oder Sie können den effizienteren xrange verwenden.
Ponkadoodle

2
@ SilentGhost: Sie benötigen zunächst noch ein Array, was nicht immer der Fall ist. @Newbie: bitte ausarbeiten?
Alec

1
@flexxy, anscheinend ist es NICHT. Beachten Sie Folgendes : phpbench.com scrollen Sie nach unten zu Read Loop.
Buddy

44

PHP-fähiger Webspace ist normalerweise günstiger als etwas mit (asp) .net. Man könnte das eine Funktion nennen ;-)


3
Es ist auch viel billiger, mehrere Server einzurichten, wenn Sie nicht auf jedem Server für Windows Server bezahlen müssen.
MiffTheFox

4
Ich weiß nur, wo Windows kostengünstig ist, an einer Universität, die STEEEEP-Rabatte auf die Serversoftware erhält, da es für meine Abteilung billiger ist, 100 Kopien von Windows zu kaufen, als unsere Administratoren unter Linux zu schulen (was teilweise der Fall ist) macht mich traurig, aber das Windows-Setup ist sauber und gut eingerichtet).
Dcousineau

4
Vorerst, aber Sie müssen den Wechsel nur einmal vornehmen, während Sie früher oder später neue Lizenzen kaufen müssen ...
e-satis

42

Das staticSchlüsselwort ist außerhalb eines OOP-Standpunkts nützlich. Sie können schnell und einfach 'Memoization' oder Funktions-Caching implementieren, und zwar mit etwas so Einfachem wie:

<?php
function foo($arg1)
{
    static $cache;

    if( !isset($cache[md5($arg1)]) )
    {
        // Do the work here
        $cache[md5($arg1)] = $results;
    }

    return $cache[md5($arg1)];
}
?>

Das staticSchlüsselwort erstellt eine Variable, die nur im Rahmen dieser Funktion nach der Ausführung erhalten bleibt. Diese Technik eignet sich hervorragend für Funktionen, die die Datenbank treffen get_all_books_by_id(...)oder get_all_categories(...)die Sie beim Laden einer Seite mehrmals aufrufen würden.

Vorsichtsmaßnahme: Stellen Sie sicher, dass Sie herausfinden, wie Sie am besten einen Schlüssel für Ihren Hash erstellen können. Unter fast allen Umständen ist das md5(...)oben Gesagte KEINE gute Entscheidung (Geschwindigkeits- und Ausgabelängenprobleme). Ich habe es zur Veranschaulichung verwendet. sprintf('%u', crc32(...))oder spl_object_hash(...)kann je nach Kontext viel besser sein.


7
Nur eine kopierte Funktion von C / C ++
GetFree

2
@ GetFree Ich glaube nicht, dass irgendjemand leugnen würde, dass fast das gesamte PHP von C, C ++, Perl usw. kopiert wurde
Frank Farmer

1
Kopieren ist das Beste, was man machen kann.
NikiC

1
Schlechtes PHP. Es werden immer Funktionen von anderen kopiert. Es sollte stattdessen alles von Grund auf neu schreiben! (Im Falle der geringsten Möglichkeit, dass dies ernst genommen wird: Ich scherze)
Halil Özgür

42

Eine nette Funktion von PHP ist die CLI . Es ist in der Dokumentation nicht so "beworben", aber wenn Sie Routine-Skripte / Konsolen-Apps benötigen, ist die Entwicklung von cron + php cli sehr schnell!


Ich sollte mir das wirklich ansehen, ich habe mehrere Cron-Jobs, die ein PHP-Skript wget http://example.com...
abrufen

CLI ist auch eine hervorragende Möglichkeit zum Spot-Debuggen, da Warnungen / Fehler angezeigt werden, ohne dass Sie Ihre Einstellungen für die Fehlerberichterstattung ändern müssen.
Gletscher

40

Dann "und drucken" Trick

<?php $flag and print "Blah" ?>

Gibt Blah wieder, wenn $ flag wahr ist. ARBEITET NICHT MIT ECHO.

Dies ist sehr praktisch in Vorlage und ersetzen die? : das sind nicht wirklich leicht zu lesen.


24
Ich selbst finde den ternären Operator viel offensichtlicher als das Ausnutzen des Bewertungskurzschlusses eines logischen und.
Vicent Marti

26
Eigentlich ist das die gleiche Anzahl von Zeichen wie <? Php, wenn ($ flag) "Blah" druckt
zu viel PHP

3
Klammern sind nicht so einfach zu tippen wie "und", besonders auf meiner blutigen französischen Tastatur ;-)
e-satis

7
@all Kommentare - Hier geht es nicht darum, wie kurz du es bekommen kannst! Es geht um Lesbarkeit und Benutzerfreundlichkeit für Vorlagen, die manchmal nicht einmal Programmierer sind.
Tor Valamo

6
Ich würde kommentieren, dass die if () - Anweisung einfacher und lesbarer ist. Es ist sicherlich einfacher für mich, den Kopf herumzukriegen, als im Wesentlichen einen Nebeneffekt des Operators 'und' in PHP auszunutzen, wo es leicht ist, einen Fehler zu machen (oder so auszusehen, als wäre es ein Fehler, wenn Sie den Code später lesen). Wie bereits erwähnt, funktioniert dies beispielsweise mit "Echo" nicht wie gewünscht. Mit if () gibt es solche Fallstricke nicht.
Thomasrutter

37

Sie können Minuszeichen in Variablennamen wie diesen verwenden:

class style
{
  ....
  function set_bg_colour($c)
  {
    $this->{'background-color'} = $c;
  }
}

Warum es benutzen? Keine Ahnung: vielleicht für ein CSS-Modell? Oder ein seltsamer JSON, den Sie ausgeben müssen. Es ist eine seltsame Funktion :)


2
Funktioniert das mit Methodennamen? Könnte nützlich sein für Frameworks, die einen Router verwenden und ich möchte domain.com/something-with-minuses/view/
alex

6
Mit den geschweiften Klammern können Sie auf Objekteigenschaften zugreifen, die Bindestriche, Punkte und andere nicht alphanumerische Entitäten enthalten. Ein Grund für die Verwendung ist XML, bei dem die Entitätsnamen wie in NITF / NewsML <body.content> gepunktet werden können. Wenn Sie SimpleXML verwenden, würden Sie wie folgt darauf zugreifen $item->DataContent->body->{'body.content'}.
Jesse Kochis

2
PHP-Variablen können auf diese Weise beliebige Zeichen annehmen, auch Leerzeichen und Zeilenumbrüche.
Neuling

Dies wäre sehr nützlich, wenn Sie in SimpleXML verwenden ... fantastisch. Danke für das Teilen.
KyleFarris

34

Die HEREDOC- Syntax ist meine Lieblingsfunktion. Immer schwer zu finden, da Sie nicht für <<< googeln können, aber es verhindert, dass Sie großen HTML-Blöcken entkommen müssen, und Sie können trotzdem Variablen in den Stream ablegen.

echo <<<EOM
  <div id="someblock">
    <img src="{$file}" />
  </div>
EOM;

2
HEREDOC ist meine Lieblingsmethode zum Erstellen und Verwenden von SQL-Anweisungen.
Bdl

11
Hinweis: das schließende EOM; kann nicht eingerückt werden.
Micahwittman

Gut, aber sinnlos, wenn Sie Vorlagen verwenden. Außerdem steht es der richtigen Einrückung im Wege.
Manos Dilaverakis

7
Lieber Gott, das ist der hässlichste Code, den ich je gesehen habe. Wenn Sie HEREDOCs verwenden, haben Sie die Präsentation nicht von der Logik getrennt.
Lotus Notes

@Byron: Sie müssen es nicht für die Präsentation verwenden, es kann für jede Zeichenfolge verwendet werden. Siehe den Kommentar von bdl.
Tom Pažourek

34

Wahrscheinlich wissen nicht viele, dass es möglich ist, konstante "Variablen" als Standardwerte für Funktionsparameter anzugeben:

function myFunc($param1, $param2 = MY_CONST)
{
//code...
}

Strings können so verwendet werden, als wären sie Arrays :

$str = 'hell o World';
echo $str; //outputs: "hell o World"

$str[0] = 'H';
echo $str; //outputs: "Hell o World"

$str[4] = null;
echo $str; //outputs: "Hello World"

3
Der letzte ist geschickt. Obwohl ich keine Ahnung habe, wann es besser wäre als eine andere Methode, ein Zeichen zu entfernen. +1 trotzdem
George Mauer

3
Es ist wahrscheinlich effizienter als das Aufrufen einer Funktion, um dies zu tun. Strings werden normalerweise zusammenhängend im Speicher gespeichert, daher ist es trivial, zu $ ​​str [4] zu gelangen. Das Speichern von Zeichenfolgen als Array von Zeichen ist in den meisten Sprachen, die von C.
sjobe abgeleitet sind, üblich

1
Sie müssen keine definierte Konstante als Standardwert verwenden. Folgendes ist ebenfalls vollkommen gültig: Funktion foot ($ param1, $ default = array ('key' => 'value'), $ default_s = 'String', $ default_i = 10, $ default_b = false). Sie haben jedoch zu Recht festgestellt, dass Sie eine Variable nicht als Standardargument verwenden können.
Dcousineau

@dcousineau Ihr Beispiel ist vollkommen gültig, da array () keine Funktion, sondern ein Sprachkonstrukt ist. Funktionsaufrufe sind als Standardwerte für Argumente nicht zulässig.
Jamol

4
Seien Sie vorsichtig mit der Behandlung von Zeichenfolgen als Arrays, wenn Sie
Mehrbyte

33

Das Nützlichste an PHP-Code ist, dass ich, wenn ich eine Funktion, die ich sehe, nicht ganz verstehe, sie mithilfe eines Browsers nachschlagen und Folgendes eingeben kann:

http://php.net/function

Letzten Monat habe ich die Funktion "range" in einem Code gesehen. Es ist eine der Hunderten von Funktionen, die ich nie benutzt habe, die sich jedoch als sehr nützlich herausstellen:

http://php.net/range

Diese URL ist ein Alias ​​für http://us2.php.net/manual/en/function.range.php . Diese einfache Idee, Funktionen und Schlüsselwörter URLs zuzuordnen , ist fantastisch.

Ich wünschte, andere Sprachen, Frameworks, Datenbanken und Betriebssysteme hätten einen so einfachen Mechanismus zum Nachschlagen von Dokumentation.


5
range()kann nützlich seinforeach( range(1, 10) as $i) { };
alex

Wenn Sie FireFox haben; PHP functionGeben Sie einfach die Adressleiste ein, um eine Google-Suche "Ich fühle mich glücklich" durchzuführen, und Sie landen fast immer auf der richtigen PHP-Dokumentationsseite.
Kolky

30

Schnelle Blockkommentare

/*
    die('You shall not pass!');
//*/


//*
    die('You shall not pass!');
//*/

Mit diesen Kommentaren können Sie umschalten, wenn ein Codeblock mit einem Zeichen kommentiert ist.


14
Dies ist nicht wirklich spezifisch für PHP. Dies funktioniert in jeder Sprache, die // ...Zeilenkommentare und /* ... */Blockkommentare unterstützt.
Jordan Ryan Moore

Alle Dienstprogramme zur Codebereinigung hassen Sie am Ende dafür, dass Sie diese verwenden ...;)
Talvi Watia

3
Ich habe auch /** /vorher und /**/nachher verwendet. Sie können den Block umschalten, indem Sie das Leerzeichen im ersten entfernen und hinzufügen. Dies hat einen zusätzlichen Vorteil bei der Arbeit mit CSS (und anderen Sprachen, die keine // ... Kommentare unterstützen).
Kingjeffrey


@aleemb, nehmen Sie keine weiteren Änderungen an dieser Frage vor.
Sam152

29

Meine Liste ... die meisten von ihnen fallen mehr unter die "versteckten Funktionen" als unter die "Lieblingsfunktionen" (ich hoffe!), Und nicht alle sind nützlich, aber ... ja.

// swap values. any number of vars works, obviously  
list($a, $b) = array($b, $a);

// nested list() calls "fill" variables from multidim arrays:  
$arr = array(  
  array('aaaa', 'bbb'),  
  array('cc', 'd')  
);  
list(list($a, $b), list($c, $d)) = $arr;  
echo "$a $b $c $d"; // -> aaaa bbb cc d  

// list() values to arrays  
while (list($arr1[], $arr2[], $arr3[]) = mysql_fetch_row($res)) { .. }  
// or get columns from a matrix  
foreach($data as $row) list($col_1[], $col_2[], $col_3[]) = $row;

// abusing the ternary operator to set other variables as a side effect:  
$foo = $condition ? 'Yes' . (($bar = 'right') && false) : 'No' . (($bar = 'left') && false);  
// boolean False cast to string for concatenation becomes an empty string ''.  
// you can also use list() but that's so boring ;-)  
list($foo, $bar) = $condition ? array('Yes', 'right') : array('No', 'left');

Sie können auch ternäre Operatoren verschachteln, was manchmal nützlich ist.

// the strings' "Complex syntax" allows for *weird* stuff.  
// given $i = 3, if $custom is true, set $foo to $P['size3'], else to $C['size3']:  
$foo = ${$custom?'P':'C'}['size'.$i];  
$foo = $custom?$P['size'.$i]:$C['size'.$i]; // does the same, but it's too long ;-)  
// similarly, splitting an array $all_rows into two arrays $data0 and $data1 based  
// on some field 'active' in the sub-arrays:  
foreach ($all_rows as $row) ${'data'.($row['active']?1:0)}[] = $row;

// slight adaption from another answer here, I had to try out what else you could  
// abuse as variable names.. turns out, way too much...  
$string = 'f.> <!-? o+';  
${$string} = 'asdfasf';  
echo ${$string}; // -> 'asdfasf'  
echo $GLOBALS['f.> <!-? o+']; // -> 'asdfasf'  
// (don't do this. srsly.)

${''} = 456;  
echo ${''}; // -> 456  
echo $GLOBALS['']; // -> 456  
// I have no idea.  

Richtig, ich höre erstmal auf :-)


Hmm, es ist schon eine Weile her ..

// just discovered you can comment the hell out of php:
$q/* snarf */=/* quux */$_GET/* foo */[/* bar */'q'/* bazz */]/* yadda */;

Soeben entdeckt, können Sie eine beliebige Zeichenfolge als Methodennamen übergeben, wenn Sie sie in geschweifte Klammern setzen. Sie können leider keine Zeichenfolge als Methode definieren, aber Sie können sie mit __call () abfangen und nach Bedarf weiterverarbeiten. Hmmm....

class foo {
  function __call($func, $args) {
    eval ($func);
  }
}

$x = new foo;
$x->{'foreach(range(1, 10) as $i) {echo $i."\n";}'}();

Fand dieses kleine Juwel in Reddit Kommentare:

$foo = 'abcde';
$strlen = 'strlen';
echo "$foo is {$strlen($foo)} characters long."; // "abcde is 5 characters long."

Sie können Funktionen in {} nicht direkt so aufrufen, aber Sie können Variablen verwenden, die den Funktionsnamen enthalten, und diese aufrufen! (* und * Sie können auch variable Variablen verwenden)


2
Bitte verwenden Sie den ternären Vergleichsoperator nicht zu häufig. Dies führt zu einer Verschleierung des Codes.
Statik

Beeindruckend. Das könnte Ihre $ GLOBALS-Liste völlig zerstören. Schlechte Praxis. Ernsthaft.
Talvi Watia

Gibt es schon einen verschleierten PHP-Wettbewerb?
Lotus Notes

Trick mit Tausch - beeindruckend und nützlich, danke.
OZ_

1
${''} = 456;hahaha .... ziemlich der Missbrauch.
Skurmedel

26

Array-Manipulation.
Tonnenweise Werkzeuge zum Arbeiten und Bearbeiten von Arrays. Es ist vielleicht nicht nur für PHP verfügbar, aber ich habe noch nie mit einer Sprache gearbeitet, die es so einfach gemacht hat.


wie was zum Beispiel? Mir scheint, dass die Funktionen alle umständlich benannt und im globalen Namespace positioniert sind. Außerdem fällt mir nichts ein, was in einer anderen Sprache nicht so einfach ist, außer vielleicht $ arr [] = $ newvalue für das Hinzufügen von Werten - das ist cool
George Mauer

8
Nun, das PHP-Array ist eine Datenstruktur, die leicht als Stapel, Warteschlange, Deque, Liste, Hashtabelle usw. verwendet werden kann. Es ist in der Tat für die meisten gängigen Anforderungen ziemlich flexibel, ohne auf etwas anderes als array_ * -Funktionen zurückzugreifen.
Camilo Díaz Repka

6
Python macht Arrays (als Listen und Tupel) viel besser als PHP.
zu viel PHP

26

Ich bin ein bisschen wie du, ich habe PHP seit über 8 Jahren codiert. Ich musste vor ungefähr einem Jahr einen .NET / C # -Kurs belegen und ich mochte die C # -Sprache (hasste ASP.NET) sehr, aber sie machte mich zu einem besseren PHP-Entwickler.

PHP als Sprache ist ziemlich schlecht, aber ich bin extrem schnell damit und der LAMP-Stack ist fantastisch. Das Endprodukt überwiegt bei weitem die Summe der Teile.

Das heißt, als Antwort auf Ihre Frage:

http://uk.php.net/SPL

Ich liebe die SPL , die Sammlungsklasse in C # hat mir gefallen, als ich damit angefangen habe. Jetzt kann ich meinen Kuchen haben und ihn essen.

Andrew


24

Ich bin ein wenig überrascht, dass es noch niemand erwähnt hat, aber einer meiner Lieblingstricks mit Arrays ist die Verwendung des Plus-Operators. Es ist ein bisschen wiearray_merge() aber ein bisschen einfacher. Ich habe festgestellt, dass es normalerweise das ist, was ich will. Tatsächlich werden alle Einträge in der RHS übernommen und in einer Kopie der LHS angezeigt, wobei sie bei Bedarf überschrieben werden (dh nicht kommutativ sind). Sehr nützlich, um mit einem "Standard" -Array zu beginnen und einige echte Werte mit einem Schlag hinzuzufügen, während die Standardwerte für nicht bereitgestellte Werte beibehalten werden.

Codebeispiel angefordert:

// Set the normal defaults.
$control_defaults = array( 'type' => 'text', 'size' => 30 );

// ... many lines later ...

$control_5 = $control_defaults + array( 'name' => 'surname', 'size' => 40 );
// This is the same as:
// $control_5 = array( 'type' => 'text', 'name' => 'surname', 'size' => 40 );

$defaultssollte sein$control_defaults
diEcho

3
Ich denke, es ist nicht so klar wie array_merge, wenn Sie viel Code pflegen müssen. Wenn Sie die Funktion array_merge verwenden, ist es zumindest offensichtlich, dass es sich um Arrays handelt.
Sylvain

Und diese Tatsache, die Sie tun ... + array( ..., reicht nicht aus, um darauf hinzuweisen? :-)
staticsan

Welche Version von PHP benötigen Sie dafür?
Lotus Notes

Dies ist eine großartige Funktion, und es sollte beachtet werden, dass das Array auf der "rechten" Seite des "+" vorhandene Schlüssel des Arrays nicht auf die "linke" Seite des "+" überschreibt.
Wil Moore III

21

Ich mag, wie das Festlegen von Standardwerten für nicht bereitgestellte Funktionsparameter viel einfacher ist:

function MyMethod($VarICareAbout, $VarIDontCareAbout = 'yippie') { }

4
Lustigerweise habe ich diese "versteckte Funktion" letzte Woche in Google Reader gesehen. Ich verstehe nicht, was daran verborgen ist - es ist die grundlegende Syntax. Versuchen Sie zum Beispiel, ob ($ var = true).
Ross

8
Einfacher als was? Die meisten Sprachen haben diese Funktion.
Christian Davén

10
Einfacher als C # (und ich denke C ++ und Java)
George Mauer

8
C ++ unterstützt Standardparameterwerte.
Sjobe

2
c # unterstützt überhaupt keine Standardwerte. Sie müssen eine überladene Funktion schreiben und immer den Wert deklarieren, der einfach nur umständlich ist
DeveloperChris

21

Schnell und schmutzig ist die Standardeinstellung.
Die Sprache ist mit nützlichen Verknüpfungen gefüllt. Dies macht PHP zum perfekten Kandidaten für (kleine) Projekte mit einer kurzen Markteinführungszeit. Nicht dass sauberer PHP-Code unmöglich ist, es erfordert nur zusätzlichen Aufwand und Erfahrung.

Aber ich liebe PHP, weil ich damit ausdrücken kann, was ich will, ohne einen Aufsatz zu schreiben.

PHP:

if (preg_match("/cat/","one cat")) {
   // do something
}

JAVA:

import java.util.regex.*;
Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat")
if (m.find()) {
  // do something
}

Und ja, dazu gehört auch, Int nicht einzugeben .


4
Sie sollten stattdessen strpos verwenden: if (false! == strpos ("eine Katze", "Katze")) {
OIS

17
@OIS Der Zweck seines Beispiels war es, den Ablauf eines schnellen Regex-Matches zu veranschaulichen und zu vergleichen, und nicht, wie die Zeichenfolge "cat" in "one cat" gefunden wird.
Dcousineau

19
Java: if (Pattern.matches ("cat", "one cat")) {// mach etwas} Hör auf, dich über Java zu beschweren, wenn du es nicht weißt.
Whiskysierra

3
+1 Willi wie machst du preg_replace ('/ ([<[]! - \ s *) (\ S *?) (\ S * - [>]]?) / Se', "\ $ this- > Wählen Sie ('\\ 1', '\\ 2', '\\ 3', \ $ data) ", $ text); in Java? Dies findet einen Kommentar im Eingabetext und ruft dann eine Funktion mit den übereinstimmenden Elementen auf, die in diesem Fall $ this-> select (...) entscheidet, durch was die Übereinstimmung ersetzt werden soll, und die Ergebnisse zurückgibt.
DeveloperChris

1
Regex ist PHP ist ziemlich beschissen ... Ich hätte lieber Regex im Perl- oder JavaScript-Stil, wo das //in die Sprache eingebaut ist.
CDMckay
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.