문제

문맥

  • PHP 5.3.x

개요

PHP와 Ruby를 정기적으로 사용하는 직원과 코드 검색을 한 후 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 버전이 루비처럼 행동하도록하는 방법을 지정할 수 있습니까?

경고

이 도전은 직선 PHP 만 사용한다는 제약으로 재미있는 운동으로 고안되었습니다. 이것은 심각한 PHP 프로젝트를위한 것이 아닙니다. 심각한 PHP 프로젝트의 경우 개발자는 다음과 같은 Addon 라이브러리를 고려하기를 원할 것입니다. 작은 가지.

도움이 되었습니까?

해결책

당신은 그런 문자열 내부의 평범한 기능을 부를 수는 없지만, 파서를 이상한 일을 할 수 있습니다.

<?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() 동일한 방식으로 작동하지만 인쇄하는 대신 형식의 문자열을 반환합니다.

다른 옵션은 다음과 같습니다.

A. 기능이 먼저 호출되고 변수에 엔드 레지 외를 할당하는 기능을 수행합니다.

$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.');

당신은 나의 단일 따옴표 (일명 진드기)와 이중 인용문을 사용하는 것을 보았을 것입니다.

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