String Concatenation Contest!
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
array
benutzen
code
expo
file
first
form
funktion
funktionieren
idee
komma
match
output
quellcode
regel
regeln
sektor
string
verbinden
zeichen
-
Einen schönen Abend an alle PHP-Entwickler!
Hier mal ein kleiner Contest zum Thema String Concatenation!
Vorweg: Was gibt es zu gewinnen? Nix. Ist nur so aus Spaß.
Also, worum gehts?
Ganz einfach: Man soll zwei Strings - in den Variablen $a und $b enthalten - aneinanderfügen und in eine Variable $c schreiben.
Gut, das ist nicht sonderlich schwer, ein $c = $a . $b; und man ist fertig.
Daher gibt es einige weitere Bedingungen:
* Keine Punkte (.)
* Keine Kommata (,)
* Keine Variablen in Strings (Der Einfachkeit halber sind daher "-Strings und HEREDOC verboten, '-Strings und NOWDOC sind weiterhin erlaubt!)
* Kein eval, sowie kein include und require [Neu dazugekommen]
* Kein Output Buffering
Ich bin gespannt auf Lösungen :D
Bitte prüft, ob euer Script den Anforderungen entspricht, bevor ihr es postet
Prüfen könnt ihr einfach indem ihr folgendes Script vor eurem Code einfügt und es laufen lässt:
<?php $source = stream_get_contents(fopen(__FILE__, 'r'), -1, __COMPILER_HALT_OFFSET__); if (!preg_match('/[.,"]|eval|require|include|ob_|<<<(?!\')/', $source, $matches, PREG_OFFSET_CAPTURE)) { echo 'Script passed!'; } else { echo 'Script did NOT pass: Unexpected "', $matches[0][0] , '" at offset ', $matches[0][1]; } __halt_compiler();
Beitrag zuletzt geändert: 24.6.2010 15:40:08 von nikic -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
<?php $a = 'Foo'; $b = 'Bar'; for( $i = 0; $i < strlen( $b ); $i++ ) { $a[ $i + strlen( $b ) ] = $b[ $i ]; } echo $a; ?>
edit: Das ganze für beliebige String Inhalte optimiert
Beitrag zuletzt geändert: 24.6.2010 15:40:45 von nikic -
<?php $a = array(); $a[0] = 'blablabla'; $a[1] = 'albalbalb'; $c = join($a); echo $c; ?>
edit: und jetzt kommt ja nicht damit, dass keine arrays verwendet werden dürfen
€dit by nikic: $a = array(); hinzugefügt.
Beitrag zuletzt geändert: 24.6.2010 15:41:04 von nikic -
Ich hab die beiden Varianten am Anfang gelöscht, die nicht den Bedingungen entsprachen.
@cbhp: Die HEREDOC Variante fällt auch unter den Punkt "Keine Variablen in Strings".
@bladehunter: Ja, genau so hätte ich das auch gemacht. Ich war mir aber nicht sicher, ob PHP das Erweitern von Strings über Array Access ohne E_NOTICEs zulässt. Scheinbar tuts das :D Also erste gültige Lösung!
@syberspace: Nachdem ich die eine Zeile in deinen Code eingefügt hab, stellt das die zweite gültige Lösung dar! Dass join/implode auch ohne den glue Parameter funktioniert wusste ich net, mal wieder was dazugelernt.
Beitrag zuletzt geändert: 24.6.2010 15:41:38 von nikic -
So, da poste ich mal gleich selber eine Lösung:
<?php $a = 'Foo'; $b = 'Bar'; require urldecode('data://text/plain;base64%2CPD9waHAgJGM9JGEuJGI7'); echo $c; ?>
Zugegeben, damit das geht, muss man allow_url_include in der php.ini auf On setzen. Aber danach gehts ;)
Beitrag zuletzt geändert: 23.6.2010 16:21:18 von nikic -
mal sehen, die aufgabe ist ja die strings irgendwie zu verbinden, ohne die verbotenen Zeichen zu benutzen, da hätte ich noch das hier anzubieten, leider kommen da aber ein paar zeichen dazu...
aber vielmehr geht bei deinen einschränkungen auch nicht mehr, zumindest nicht mit dem php-core.<?php class strings { public $foo = 'foo'; public $bar = 'bar'; } $data = new strings(); $data = http_build_query($data); echo( $data ); ?>
-
Jo, wie ich schon geschrieben hatte, vielmehr geht nicht, im php-core gibts keine Funktionen mehr die Strings verbinden, ohne zumindest ein Komma benutzen zu müssen, ansonsten könnte man noch lustige Sachen mit Dateihandels veranstalten, aber da braucht man ständig Kommas.
Appropot bei einem solchen Thema wünscht man sich doch irgendwie wieder das Karma zurück, ich hätte schon 1-2 Beiträge, zu denen ich Karma gegeben hätte.
Übrigens ist mir grade aufgefallen, dass man die Variante von @bladehunter auch noch unter den jetzigen Regeln verwenden kann, wenn man die eckigen Klammern gegen geschweifte austauscht, sollte so auch funktionieren:<?php $a = "Foo"; $b = "Bar"; for( $i = 0; $i < strlen( $b ); $i++ ) { $a{ $i + strlen( $b ) } = $b{ $i }; } echo $a; ?>
-
Ui, hier war ja richtig Aktivität... ich habe wieder einige ungültige Versionen gelöscht und auch alle Beiträge, die keine weiteren Lösungen einsenden.
@fabo:Sagtest du nicht, dass , verboten wäre? =)
Argh. Da hast du Recht. Ich hab es jetzt so angepasst, dass statt dem Komma ein %2C da steht und ich das decodiere.
Ebenso folgendes: Kein eval(), sowie kein include und require [Neu dazugekommen]
Daher steht da auch "Neu dazugekommen". Das habe ich nach meiner Lösung verboten. Arrays und ArrayAccess habe ich nach bladehunters Lösung und nach dem implode() Variante aus dem Spiel genommen ;)
Dein Script
<?PHP $a = "Foo"; $b = "Bar"; $c = "{$a}{$b}"; echo $c; ?>
geht nicht, da es gegen "* Keine Variablen in Strings (damit ist etwas gemeint wie "$a". '$a' ist natürlich weiterhin erlaubt.)" verstößt.
@thomasba:
* Keine Arrays und kein ArrayAccess jeglicher Form [Neu dazugekommen]
Streng genommen ist ein String doch eine Form von Array
Ja, ich wusste nicht wie ich das ausdrücken sollte. Gemeint ist, dass '[' verboten ist. Deine Variante mit dem implode entspricht der Variante von syperspace, die hast du sicher übersehen ;)
@nemoinho: Es sollten eigentlich wirklich nur die Zeichen selbst zusammengefügt werden. Aber ich lass es erstmal stehen.
@wagnerm: Siehe thomasba.
@ggame: Sorry, deine Variante ist leider auch ungültig, du hast da ein Komma drin beim Öffnen des File Handles. (ggames Variante findet ihr in seinem Gästebuch: http://www.lima-city.de/profile/ggamee#guestbook)
@nemoinho: Ah ja, das ist auch nice. Das wird dann gleich das nächste Verbot :D
Ich bin mal gespannt, ob es noch irgendwelche verrückten Lösungen gibt :D
€dit: Ich glaube die Beschränkung keine Arrays zu nutzen ist wirklich zu hart. Ich habe die wieder aus den Regeln genommen ;) Jetzt sollten noch Lösungen möglich sein.
Arrays sind wieder erlaubt!
Beitrag zuletzt geändert: 23.6.2010 16:49:34 von nikic -
nikic: Allesamt UNGÜLTIG!
@sektor:
Mist! Die Idee mit der Datei hatte ich auch ...
Dann eben in der HONK-Version:
// init $a = 'fred'; $b = 'barney'; // concat $file = tempnam('', ''); file_put_contents($file, $a, FILE_APPEND); file_put_contents($file, $b, FILE_APPEND); $c = file_get_contents($file); // view echo $c;
str_pad():
// init $a = 'fred'; $b = 'barney'; // concat $c = str_pad($a, strlen($a) + strlen($b), $b); // view echo $c;
Output-Buffering:
Oder ist das verboten?
// init $a = 'fred'; $b = 'barney'; // concat ob_start(); echo $a; echo $b; $c = ob_get_clean(); // view echo $c;
preg_replace_callback():
// init $a = 'fred'; $b = 'barney'; // concat function _callback($hits) { return $GLOBALS['b']; } $c = preg_replace_callback('/\z/', '_callback', $a); // view echo $c;
Noch schöner:
// init $a = 'fred'; $b = 'barney'; // concat $c = implode( array_intersect_key( $GLOBALS, array_flip(preg_grep('/\A[ab]\z/', array_keys($GLOBALS))) ) ); // view echo $c;
Beitrag zuletzt geändert: 24.6.2010 15:51:08 von nikic -
Äh, alopex und sektor, habt ihr euch die Regeln überhaupt durchgelesen? Es geht darum eine Möglichkeit zu finden ohne Kommata und die weiteren oben genannten Zeichen.
Da dauernd Scripts, die nicht den Regeln entsprechen gepostet werden, habe ich mal oben ein Script gepostet, um seinen Quellcode zu prüfen.
alopex, ich behalte deinen Beitrag bei, weil die letzen beiden Varianten durchaus interessant sind - auch wenn sie zu 300% gegen obige Regeln verstoßen. -
Ist zwar nur eine Teillösung, aber...
Die Komma-Regel ist echt ein wenig störend. Da würde mir sonst noch einiges witziges einfallen. ;) Ansonsten ist da denke ich nicht mehr viel heraus zu holen.<?php // predefine $a = "123456789"; $b = "01234"; $subtotal = 0; $expo=1; for($i=1;$i<=strlen($b);$i++) $expo*=10; (int)$subtotal+=(int)$a*$expo+(int)$b; (string)$c=(string)$subtotal; echo $c; // check if($c == $a.$b) echo "\nworks for all strings (with numbers as values and a combined length of max 14 and where the first char of the first value is a 1 or above). :p" ?>
Beitrag zuletzt geändert: 25.6.2010 23:08:38 von tplus -
nikic schrieb:
Äh, alopex und sektor, habt ihr euch die Regeln überhaupt durchgelesen? Es geht darum eine Möglichkeit zu finden ohne Kommata und die weiteren oben genannten Zeichen.
Sorry, ich hab gerne mal das Problem, dass ich zwischen dem Verfassen eines Posts und dessen Abschicken eine "Offline-Pause" einlege, und dabei das Reloaden vergesse. Bei dynamisch angepassten Regelwerken versagt diese Methode kläglich.
Und die Komma-Regel hatte ich auch ursprünglich so interpretiert, dass man das Komma nicht zum "Concatenieren" benutzen darf, wie in sprintf('%s%s', $a, $b) oder so ...
Das ob_-Beispiel ist nur durch Copy-N-Paste reingerutscht, eigentlich wollte ich es wieder entfernen.
Ich war mit zu vielen Ablenkungen nebenbei beschäftigt ...
Da dauernd Scripts, die nicht den Regeln entsprechen gepostet werden, habe ich mal oben ein Script gepostet, um seinen Quellcode zu prüfen.
Gute Idee, aber laut dem Script ist implode()|joint() jetzt wieder erlaubt? Dann hätte ich noch folgende Idee:
// init $a = 'fred'; $b = 'barney'; // concat $o = (object) NULL; //new Object(); $o->a = $a; $o->b = $b; $c = implode((array)$o); // view echo $c;
Fast kein Array verwendet ...
Und dein Test-Script mokiert auch in Stringliteralen (mit einfachen Hochkommas) eingebettete Punkte und Kommas[1].
Ist das so gewollt?
alopex, ich behalte deinen Beitrag bei, weil die letzen beiden Varianten durchaus interessant sind - auch wenn sie zu 300% gegen obige Regeln verstoßen.
Das ist nett.
Ich hätte auch noch zwei Vorschläge, die ich aber mangels Zeit und Lust noch nicht komplett ausgearbeitet habe:
1. Wenn es eine Möglichkeit gibt, per SQL zwei Strings zu verknüpfen, und es eine Datenbankerweiterung gibt, die mit prepared-Statements arbeitet, müsste man damit etwas bauen können. Prepared-Statements sind leider wegen der Komma-Regel nötig. So kann man jede der beiden Variablen mit einem Befehl ohne Komma hinzufügen.
2. Die COM-Extension. Damit kann man beliebige externe Scripts schreiben oder PHP-Strings zu Windows-Scripting-Host-Scripts machen und dann ausführen. Man muss dem Script nur beibringen, wie es mehrere unterschiedliche Parameter entegegennimmt und zwischenspeichert. Ist ein bisschen umständlich, müsste aber funktionieren.
Damit wird es aber immer absurder -- das Komma als Trennzeichen von Funktions-Argumenten ist nun mal ein essentieller Bestandteil der meisten Programmiersprachen und PHP lebt von der Unzahl der Funktionen seiner Standardlibrary und deren ellenlangen Parameterlisten.
Das ist wie einhändiges Fahrradfahren -- auf die Dauer nicht gesund.
==
[1] Ich weiß, der gebildete Mensch schreibt "Kommata". Aber ich sage schließlich auch Koalas und nicht Koalata. -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage