Pergunta

Contexto

  • PHP 5.3.x

Visão geral

Depois de fazer uma revisão de código com um associado que usa php e Ruby rotineiramente, surgiu um desafio divertido sobre a interpolação de strings em php em comparação com Ruby.

Pergunta

Suponha que color = "laranja";

Rubi:

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.");

Desafio: alguém pode especificar uma maneira de fazer com que a versão do PHP se comporte como Ruby?

Embargo

Este desafio pretende ser um exercício divertido com a restrição de usar apenas PHP puro.Isto não se destina a projetos sérios de PHP.Para projetos PHP sérios, o desenvolvedor deverá considerar bibliotecas adicionais, como GALHO.

Foi útil?

Solução

Você não pode chamar funções simples dentro de strings como essa, mas pode convencer o analisador a fazer coisas estranhas:

<?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"
?>

Contanto que veja uma variável válida no início, ele continuará em frente e interpolará uma instrução inteira sem reclamar.

Para aqueles que estavam se perguntando, sim, isso também funciona ...

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

Outras dicas

Você está perto, você pode incorporar variáveis ​​em strings, mas não em chamadas de função.

eu uso printf() (e sprintf()) para isso, que é um invólucro fino em torno da função C de mesmo nome:

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

Veja isso %s lá?Esse é o espaço reservado para o tipo de dados string que você está passando como segundo argumento.

sprintf() funciona da mesma maneira, mas retorna a string formatada em vez de imprimi-la.

As únicas outras opções são:

A.Executando as chamadas de função primeiro e atribuindo o resultado final à variável:

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

B.Usando concatenação, que é um pouco feia na IMO:

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

Você deve ter notado meu uso de aspas simples (também conhecidas como ticks) e aspas duplas.

No PHP, literais entre aspas duplas são analisados ​​para variáveis, como você pode ver em “A” acima.

Literais entre aspas simples não são analisados.Por causa disso, eles são mais rápidos.Você deve, como regra, usar aspas duplas apenas em torno de literais quando houver uma variável a ser analisada.

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

Eu não acho que o PHP suporta expressões completas interpoladas em cordas. Faz um tempo desde que eu fiz algum PHP.

Se isso for algo, ...

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.";

E a versão hiper -avançada

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.

Não é tão bonito, mas você pode usar uma função anônima.

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

Meus projetos geralmente têm uma função auxiliar que retorna a função anônima acima, por isso não precisa ser recriada sempre.

function returner() {
    static $returner;

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

    return $returner;
}

$e = returner();

Não é possivel. Mas se você realmente insiste, sempre pode criar uma classe de string com uma interface fluente ... mas isso é loucura :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top