Frage

Kontext

  • PHP 5.3.x

Überblick

Nach einer Code-Überprüfung mit einem Mitarbeiter, der routinemäßig sowohl PHP als auch Ruby verwendet, stieg eine unterhaltsame Herausforderung für die String-Interpolation in PHP im Vergleich zu Ruby.

Frage

Annehmen color = "orange";

Rubin:

puts("My favorite color is #{color.downcase() + 'ish'} -- at least for now.");

PHP:

print("My favorite color is {strtolower( $color ) + 'ish'} -- at least for now.");

Herausforderung: Kann jemand eine Möglichkeit angeben, die PHP -Version wie Ruby zu verhalten?

Vorbehalt

Diese Herausforderung ist als unterhaltsame Übung mit der Einschränkung, nur geraden PHP zu verwenden. Dies ist nicht für ernsthafte PHP -Projekte gedacht. Für ernsthafte PHP -Projekte möchte der Entwickler Addon -Bibliotheken in Betracht ziehen, wie z. ZWEIG.

War es hilfreich?

Lösung

Sie können keine einfachen Funktionen in solchen Zeichenfolgen anrufen, aber Sie können den Parser dazu überreden, seltsame Dinge zu tun:

<?php
print "{$a->b()}"; // Works

//Parse error: syntax error, unexpected '(' in Command line code on line 1
print "${time()}";

print "${$a=time()} $a"; // Also works: prints "1234380996"
?>

Solange es zu Beginn eine gültige Variable sieht, wird es weitermachen und eine ganze Aussage interpolieren, ohne sich zu beschweren.

Für diejenigen, die sich gefragt haben, ja, das funktioniert auch ...

<?php
print "${$a or print shell_exec('ls')}";
?>

Andere Tipps

Sie sind nahe, Sie können Variablen in Zeichenfolgen einbetten, aber keine Funktionsaufrufe.

ich benutze printf() (und sprintf()) dafür, was eine dünne Wrapper um die gleichnamige C -Funktion ist:

printf('My favorite color is %sish -- at least for now.', strtolower( $color ));

Siehst du das %s da drin? Das ist der Platzhalter für den String -Datentyp, den Sie als 2. Argument ausgeben.

sprintf() funktioniert genauso, aber es gibt die formatierte Zeichenfolge zurück, anstatt sie zu drucken.

Die einzigen anderen Optionen sind:

A. Ausführen der Funktionsaufrufe zuerst und zuweisen die Endausläufe der Variablen:

$color = strtolower( $color );
print("My favorite color is {$color}ish -- at least for now.");

B. Verwenden von Verkettung, die ein wenig hässlich ist: IMO:

print('My favorite color is ' . strtolower( $color ) . 'ish -- at least for now.');

Möglicherweise haben Sie meine Verwendung von einzelnen Zitaten (auch bekannt als Zecken) und doppelte Zitate bemerkt.

In PHP werden Literale innerhalb von Doppelzitaten für Variablen analysiert, wie Sie in "A" oben sehen.

Literale innerhalb einzelner Zitate werden nicht analysiert. Aus diesem Grund sind sie schneller. Sie sollten in der Regel nur doppelte Zitate um Literale verwenden, wenn eine Variable analysiert werden kann.

'My favorite color is ' . strtolower( $color ) . 'ish-- at least for now.'

Ich glaube nicht, dass PHP Vollausdrücke unterstützt, die in Saiten interpoliert sind. Es ist schon eine Weile her, seit ich einen PHP gemacht habe.

Wenn das etwas geht ....

class ColorIsh {
    var $color;

    function __constructor($color) { $this->color = $color; }
    function __get($prop) {
        if ($prop == 'ish') {
            // code here fixing suffix if needed
            return strtolower($this->color) . 'ish';
        }
        return '';
    }
    function __set($prop) {}
}

$color = new ColorIsh("orange");
$str = "My favorite color is $color->ish -- at least for now.";

Und die Hyper Advanced Version

class ColorIsh {
    private $color;

    function __constructor($color) {$this->color = $color; }
    function __get($prop) {
        if ($prop == 'color') 
            return $this->color;
        if ($prop == 'ish')
            return isset($this->ish) ? $this->ish : $this->color . 'ish';
        return false;
    }
    function __set($prop, $value) {
        if ($prop == 'color') { $this->color = $value; unset($this->ish); }
        if ($prop == 'ish') { $this->ish = $value; }
    }
}

$color = new ColorIsh('orange');
$color->ish = 'orangish';
print "The color is kinda $color->ish";
$color->color = 'green';
print "The color is kinda $color->ish";

output:
The color is kinda orangish.
The color is kinda greenish.

Es ist nicht so hübsch, aber Sie können eine anonyme Funktion verwenden.

$e = function($val) { return $val; };
$foo = 'foo';
echo "Uppercase foo = {$e(strtoupper($foo))}";

Meine Projekte haben normalerweise eine Helferfunktion, die die oben genannte anonyme Funktion zurückgibt, sodass sie nicht jedes Mal nachgebildet werden muss.

function returner() {
    static $returner;

    if (!$returner) {
        $returner = function($val) {
            return $val;
        };
    }

    return $returner;
}

$e = returner();

Nicht möglich. Aber wenn Sie wirklich darauf bestehen, können Sie immer eine String -Klasse mit einer fließenden Schnittstelle erstellen ... aber das ist verrückt :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top