语境

  • PHP 5.3.x

概述

与Ruby相比,与同时使用PHP和Ruby同时使用PHP和Ruby的同事进行代码审查后,在PHP中的字符串插值中出现了一个有趣的挑战。

问题

假设颜色=“橙色”;

红宝石:

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

挑战: 任何人都可以指定一种使PHP版本像Ruby一样行为的方法吗?

警告

这项挑战旨在作为有趣的练习,其限制仅使用直PHP。这不是针对认真的PHP项目。对于认真的PHP项目,开发人员将需要考虑插件库,例如 枝条.

有帮助吗?

解决方案

您不能在类似的字符串中调用普通功能,但是您可以哄骗解析器做奇怪的事情:

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

只要它在开始时看到一个有效的变量,它就会继续前进并在不抱怨的情况下插入整个声明。

对于那些想知道的人,是的,这也有效...

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

其他提示

您很接近,您可以将变量嵌入字符串中,而不是函数调用。

我用 printf() (和 sprintf()),这是围绕同名C函数的薄包装器:

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

看到 %s 在那里?这是您作为第二参数传递的字符串数据类型的占位符。

sprintf() 以相同的方式工作,但它返回格式化的字符串而不是打印。

唯一的其他选项是:

答:首先执行函数调用并将最终归值分配给变量:

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

B.使用串联,这有点丑陋的IMO:

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

您可能已经注意到我对单引号(又名tick)和双引号的使用。

在PHP中,您在上面的“ A”中看到的变量中,双引号内的文字被解析。

单引号中的文字没有解析。因此,它们更快。通常,您应该只在有一个要解析的变量时才使用围绕文字的双重报价。

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

我认为PHP不支持将完整的表达方式插入字符串中。自从我做任何PHP以来已经有一段时间了。

如果这是什么...

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

和超级高级版本

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.

并不是那么漂亮,但是您可以使用匿名功能。

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

我的项目通常具有辅助功能,该功能返回上述匿名功能,因此每次都不需要重新创建它。

function returner() {
    static $returner;

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

    return $returner;
}

$e = returner();

不可能。但是,如果您真的坚持认为,您总是可以创建一个带有流利界面的字符串类...但是这太疯狂了:)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top