연결하지 않고 문자열에 상수 포함


166

PHP에서 연결하지 않고 문자열에 상수를 포함시키는 방법이 있습니까?

define('MY_CONSTANT', 42);

echo "This is my constant: MY_CONSTANT";

12
직감에 따르면 "이것은 내 상수입니다 : {MY_CONSTANT}"가 작동해야합니다. 그렇지 않습니다. 누군가가 나와 같은 생각을하는 경우에 대비하여 여기에
두십시오

답변:


148

아니.

Strings를 사용하면 PHP가 상수 식별자와 별도로 문자열 데이터를 말할 수있는 방법이 없습니다. 이것은 heredoc을 포함하여 PHP의 모든 문자열 형식에 적용됩니다.

constant() 상수를 얻는 또 다른 방법이지만, 함수 호출은 연결없이 문자열에 넣을 수 없습니다.

PHP 상수에 대한 매뉴얼


1
어쨌든 정답은 +1입니다. 먼저 나는 당신과 같은 것을 쓰고 싶었지만 당신의 것을 읽은 후에 나는 뭔가 다른 것을 제시해야한다고 생각했습니다.)
Felix Kling

3
헤헤! 그러나 창의력을 위해 모두에게 잘되는 +1. :)
Pekka

59
"기능 호출을 문자열에 넣을 수 없습니다"예 가능 :define('ANIMAL','turtles'); $constant='constant'; echo "I like {$constant('ANIMAL')}";
raveren

1
@Raveren은 다른 것들이 불필요하게 함수를 생성하는 간접 변형을 제공하지만, 당신의 함수는 가장 짧고 변수 함수, 과소 평가되고 자주 사용되지 않는 PHP 기능에 의존하는 포인트 솔루션입니다. 이 전체 스레드에서 특정 솔루션을 사용했습니다. 한 번 이상 +1 할 수 있기를 바랍니다.
hndcrftd

4
방금 어느 쪽이 더 나은지에 대해서는 언급하지 않고 가능하다고 지적했습니다.
raveren

111

예, (어떻게 든;)입니다.

define('FOO', 'bar');

$test_string = sprintf('This is a %s test string', FOO);

이것은 아마도 당신이 목표로하는 것이 아니지만 기술적으로 이것은 연결이 아니라 대체이며,이 가정에서 연결하지 않고 문자열의 상수를 포함 한다고 생각 합니다.


5
@Pekka : 알아요 :-D (이번에 ...;))
Felix Kling

1
:) @ juraj.blahunka의 접근 방식은 훨씬 비열합니다. 그것은 편지로 질문에 대답하지만 그 정신은 아닙니다. :)
Pekka

2
@blahunka : 좋은 모토. 아마 매일 사용합니다
Alfabravo

57

문자열 내에서 상수를 사용하려면 다음 방법을 사용할 수 있습니다.

define( 'ANIMAL', 'turtles' ); 
$constant = 'constant';

echo "I like {$constant('ANIMAL')}";


어떻게 작동합니까?

모든 문자열 함수 이름과 임의의 매개 변수를 사용할 수 있습니다

함수 이름을 변수에 넣고 큰 따옴표로 묶은 문자열 안에 매개 변수를 사용하여 호출 할 수 있습니다. 여러 매개 변수와 함께 작동합니다.

$fn = 'substr';

echo "I like {$fn('turtles!', 0, -1)}";

생산

나는 거북이를 좋아한다

익명의 기능들

PHP 5.3 이상을 실행중인 경우 익명 함수를 사용할 수도 있습니다.

$escape   = function ( $string ) {
    return htmlspecialchars( (string) $string, ENT_QUOTES, 'utf-8' );
};
$userText = "<script>alert('xss')</script>";
echo( "You entered {$escape( $userText )}" );

예상대로 올바르게 이스케이프 된 HTML을 생성합니다.

콜백 배열은 허용되지 않습니다!

지금까지 함수 이름이 호출 가능할 수 있다는 인상을 받고 있다면 is_callable문자열 내부에서 사용될 때 치명적인 오류가 발생할 때 true를 반환하는 배열은 아닙니다 .

class Arr
{

    public static function get( $array, $key, $default = null )
    {
        return is_array( $array ) && array_key_exists( $key, $array ) 
            ? $array[$key] 
            : $default;
    }
}

$fn = array( 'Arr', 'get' );
var_dump( is_callable( $fn ) ); // outputs TRUE

// following line throws Fatal error "Function name must be a string"
echo( "asd {$fn( array( 1 ), 0 )}" ); 

명심하십시오

이 방법은 잘못 권장되지만 때로는 훨씬 더 읽기 쉬운 코드가 생성되므로 사용자에게 달려 있습니다. 가능성이 있습니다.


1
이것은 훌륭한 트릭입니다! 다른 답변과 마찬가지로 노력과 가독성 측면에서 실제로 연결에 대한 큰 승리는 아니지만 알기에 좋습니다. 당신이 뭔가를 할 때 심지어 더 섹시합니다 $_ = create_function('$a','return $a;'); $s = "I like {$_(ANIMAL)}". Thetaiko의 버전은 따옴표가 필요 없으며 밑줄이 귀엽습니다.
Beejor

2
나는 이것이 템플릿 엔진을 만드는 데 유용하다는 것을 알 수 있지만 실제로 사용하기에는 너무 비열한 것 같습니다.
Mnebuerquo

21
define( 'FOO', 'bar');  
$FOO = FOO;  
$string = "I am too lazy to concatenate $FOO in my string";

4
이것은 내가 작성해야 할 미친 SQL 문자열이있을 때 가장 많이 사용하는 것입니다. 또한 ... 수동적 공격적입니까? ;-)
Beejor

2
이것은 중복을 찾는 대신 가장 적은 양의 마법을 가지고 있습니다
BrDaHa

훌륭한 솔루션. 간단하고 빠릅니다.
Roger Hill

14
define('FOO', 'bar');
$constants = create_function('$a', 'return $a;');
echo "Hello, my name is {$constants(FOO)}";

13

당신이 정말로 경우 연결없이 에코 일정에 원하는 여기에 솔루션입니다 :

define('MY_CONST', 300);
echo 'here: ', MY_CONST, ' is a number';

참고 :이 예제에서 echo는 많은 매개 변수를 사용합니다 ( 쉼표를보십시오) ) 실제로 연결되지 않습니다

Echo는 함수로 작동하고 더 많은 매개 변수를 사용하며 연결보다 더 효율적입니다. 연결하고 에코 할 필요가 없기 때문에 새로운 String 연결 객체를 만들 필요없이 모든 것을 에코합니다. :))

편집하다

당신이 고려하는 경우도 합치 같은 문자열 지내는 문자열 매개 변수를 나 쓰기 와 전체 문자열을 ", (쉼표 버전)는 항상 가장 빠른, 다음에 간다 . (와 연결 ' 작은 따옴표) 및 방법을 구축하는 가장 느린 문자열은 큰 따옴표를 사용하고 있습니다 " , 이런 식으로 작성된 표현식은 선언 된 변수 및 함수에 대해 평가되어야하기 때문에 ..


11

당신은 할 수 있습니다 :

define( 'FOO', 'bar' );

$constants = get_defined_constants(true); // the true argument categorizes the constants
$constants = $constants[ 'user' ]; // this gets only user-defined constants

echo "Hello, my name is {$constants['FOO']}";

6

가장 쉬운 방법은

define('MY_CONSTANT', 42);

$my_constant = MY_CONSTANT;
echo "This is my constant: $my_constant";

다른 방법으로 (s)printf

define('MY_CONSTANT', 42);

// Note that %d is for numeric values. Use %s when constant is a string    
printf('This is my constant: %d', MY_CONSTANT);

// Or if you want to use the string.

$my_string = sprintf('This is my constant: %d', MY_CONSTANT);
echo $my_string;

나는 이것이 좋은 해결책이라고 생각한다. 내부에 직접 상수를 사용하면 연결 문자열이 작동하지 않는 경우가 있습니다.
kta

5

다른 사람들이 지적했듯이 그렇게 할 수 없습니다. PHP에는 constant()문자열에서 직접 호출 할 수 없는 함수 가 있지만이 문제를 쉽게 해결할 수 있습니다.

$constant = function($cons){
   return constant($cons);
};

사용법에 대한 기본 예 :

define('FOO', 'Hello World!');
echo "The string says {$constant('FOO')}"; 

$constant = 'constant';다른 함수를 정의하는 대신 할 수 있으며 해당 함수가 이미 존재하기 때문에 동일하게 작동합니다.
redreinard

2

다른 답변에 대한 대안은 다음과 같습니다. 주로 "{$}"트릭에 중점을 둔 것 같습니다. 그들의 속도에 대한 보장은 없지만; 이것은 모두 순수한 구문 설탕입니다. 이 예제에서는 아래 상수 세트가 정의되었다고 가정합니다.

define( 'BREAD', 'bread' ); define( 'EGGS', 'eggs' ); define( 'MILK', 'milk' );

extract () 사용
결과는 변수와 동일하기 때문에 좋습니다. 먼저 재사용 가능한 함수를 작성하십시오.

function constants(){ return array_change_key_case( get_defined_constants( true )[ 'user' ] ); }

그런 다음 모든 범위에서 호출하십시오.

extract( constants() );
$s = "I need to buy $bread, $eggs, and $milk from the store.";

여기서는 상수를 소문자로 사용하기가 쉽지만 array_change_key_case ()를 제거하여 그대로 유지할 수 있습니다. 이미 지역 변수 이름이 충돌하는 경우 상수가이를 대체하지 않습니다.

문자열 대체 사용
이것은 sprintf ()와 유사하지만 단일 대체 토큰을 사용하며 무제한의 인수를 허용합니다. 나는 이것을하는 더 좋은 방법이 있다고 확신하지만, 내 어리 석음을 용서하고 그 뒤에 아이디어에 집중하려고 노력하십시오.

이전과 마찬가지로 재사용 가능한 함수를 만듭니다.

function fill(){
    $arr = func_get_args(); $s = $arr[ 0 ]; array_shift( $arr );
    while( strpos( $s, '/' ) !== false ){
        $s = implode( current( $arr ), explode( '/', $s, 2 ) ); next( $arr );
    } return $s;
}

그런 다음 모든 범위에서 호출하십시오.

$s = fill( 'I need to buy /, /, and / from the store.', BREAD, EGGS, MILK );

% 또는 #과 같이 원하는 대체 토큰을 사용할 수 있습니다. 입력하기가 더 쉽기 때문에 슬래시를 사용했습니다.


0

네임 스페이스 쓰레기를 방지하기 위해 키워드 'const'를 함수의 이름으로 사용할 수 있습니다.

define("FOO","foo");
${'const'} = function($a){return $a;};
echo "{$const(FOO)}"; // Prints "foo"
echo const(FOO); // Parse error: syntax error, unexpected T_CONST

$ GLOBALS를 사용하여 코드 전체에 'const'함수를 전파 할 수도 있습니다.

$GLOBALS['const'] = function($a){return $a;};

나중에 사용하기에 안전한지 확실하지 않습니다. 그리고 더 나쁜 것은 여전히 ​​추악한 것처럼 보입니다.


-2

이것이 OP의 원래 질문에 대한 답변이라고 생각합니다. 유일한 것은 globals 인덱스 키가 소문자로만 작동하는 것 같습니다.

define('DB_USER','root');
echo "DB_USER=$GLOBALS[db_user]";

산출:

DB_USER=root

1
대문자를 연속으로 사용하더라도 $ GLOBALS is 작동하지 않습니다 an associative array containing references to all variables.
har-wradim

이 답변은 잘못되었습니다. 이것이 출력을 생성 할 수있는 유일한 방법은 스크립트 어딘가에있는 경우입니다.$db_user = 'root';
Jeff Puckett
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.