2016-09-22 2 views
0

는 최근 SO에 대한 답변을 작성하고 난 내가 내 (다음) 코딩 스타일로 인해 몰랐 PHP에서 이상한 동작입니다 무슨 생각을 알게되었다 :concat 연산자와 float 식별자의 우선 순위 '.' (T_CONSTANT_ENCAPSED_STRING, T_DNUMBER)

$var = 1; 
echo "test string ". $var+1 ." example"; 

이 내가 1. 사이의 공간을 제거하지만 경우에, 잘 작동 :

echo "test string ". $var+1." example"; 

그것은 예상이 사건을 나에게 T_CONSTANT_ENCAPSED_STRING 구문 분석 오류를주고으로하는 ',' 또는 매우 잘못 ';'.

그리고 네 .. 그것과 같이 작동합니다 :이와 데 문제는 오류 메시지가 구체적으로 무엇의 기본 문제를 반영하지 않는다는 점이다

echo "test string ".($var+1)." example"; 

다른 메시지가 대부분 정확한 위치에 있고 올바른 위치를 원합니다.

나는 처음에 나는 여전히 부동 소수점 연산자는 다음과 같은 시나리오에서 CONCAT 연산자보다 우선 왜 이해 힘든 시간을 이것의 원인으로 포인트를 떠 기대하지 않았지만 :

var_dump(.1, 1, 1., 1.0); 
var_dump(1.."a", "a"..1, 1.0."a"); 

플로트 (0.1), INT (1), 플로트 (1), 플로트 (1)
캐릭터 (2) "1A", 스트링 (4) "± 0.1"캐릭터 (2) "1A"

이제는 산술 연산자가 문자열 연산보다 먼저 수행되어야한다는 것을 이해하지만 여기서는 하지 않습니다

".11.".는 CONCAT 연산자임을 표시해야하고 1.1.는 플로트에 대한 식별자임을 표시해야합니다. 대신 둘 다 구문 분석 오류를 제공합니다. 왜 모든 float로 1.을 분석

var_dump(1 + 1.); // float(2) 
var_dump(1. + 1); // float(2) 

당신은 단순히 플로트에 추가 + 1을 사용할 수 있습니다 : 그것은 변수 유형에 올 때

PHP는 까다 롭고 아닌 언어인가? 구문 분석 오류는 다음 토큰에서 발생합니다.이 토큰에서 숫자는 예상되며 concat 연산자가 될 수 없습니다.echo 1."test" 출력 1test는 현재 기존 코드를 깰 수있는 것인지

그래서 제 질문은, 왜 PHP 렉서는 너무 많은 플로트 식별 강조하고 을 던져 않습니다입니까?

처음에는 부정적인 담당자가 있었기 때문에 내가 무엇을 의미하는지 명확히하기 위해 질문을 편집했습니다. 내가 eval()

+5

그게 전부가 변경됩니다. 문자열'1 '은 유효한 부동 소수점이 아니므로 – DarkBee

+0

https://eval.in/646594 오류가 발생합니다.이'$ var + 1.'는 PHP에서 유형 변환으로 사용되며'.'가 누락되었습니다. 오류가 주어진다. –

+0

나는 '$ var + 1'이 타입 변환으로 작동하고 그 파서가 "example"(문자열)을 얻고 나서 에러를 내고 있다고 말하려고했다. –

답변

2

1.를 사용하지 않고 PHP 코드를 확인하는 방법이 필요하기 때문에 현재 허용 대답은 부동 소수점 숫자 1.0를 의미 여전히 매우 유효합니다.

echo "test string " . $var + 1.0 " example"; 

문자열 " example"T_CONSTANT_ENCAPSED_STRING 토큰 : 그래서 당신이 쓴 무슨 일이 lexed된다. 파서는 부동 소수점 숫자 바로 다음에 기대하지 않습니다.

당신은 token_get_all() 이것을 확인할 수 있습니다 1. 한 토큰, 318 (T_DNUMBER, 이중 수)로 나타

php > var_export(token_get_all('<?php echo "test string ".$var+1." example";')); 
array (
    0 => 
    array (
    0 => 379, 
    1 => '<?php ', 
    2 => 1, 
), 
    1 => 
    array (
    0 => 328, 
    1 => 'echo', 
    2 => 1, 
), 
    2 => 
    array (
    0 => 382, 
    1 => ' ', 
    2 => 1, 
), 
    3 => 
    array (
    0 => 323, 
    1 => '"test string "', 
    2 => 1, 
), 
    4 => '.', 
    5 => 
    array (
    0 => 320, 
    1 => '$var', 
    2 => 1, 
), 
    6 => '+', 
    7 => 
    array (
    0 => 318, 
    1 => '1.', 
    2 => 1, 
), 
    8 => 
    array (
    0 => 323, 
    1 => '" example"', 
    2 => 1, 
), 
    9 => ';', 
) 
php > print token_name(318); 
T_DNUMBER 
php > print token_name(323); 
T_CONSTANT_ENCAPSED_STRING 

하는 것으로.

+0

따라서 우선 순위는 산술 (연산자가 아닌)의 부동 소수점 숫자로 값을 변환하기 위해'.'을 적용하는 것처럼 보이므로'+'우선 순위를가집니다. 나는이 문제가 정상적으로 발생하는 곳에서 플로팅이 일어날 것으로 예상하지 못했을 것입니다. 나는 변수를 직접 잡아낼 것입니다. – Xorifelse

+0

@ Xorifelse 여기에는 우선 순위 문제가 없습니다. 연산자의 우선 순위는 프로그램이 구문 상 올바르다면 적용됩니다. 여기에는 구문 오류가 있습니다. '1'은 부동 소수점 숫자이며, 문자열 연결은 포함되지 않습니다. '1 .'은 문자열 연쇄 연산자가 뒤에 오는 정수입니다. ''abc ''는 숫자 뒤에 문자열이오고 그 사이에는 연산자가 없다 (구문 오류). '1. "abc". ''1. "abc"'는 연결 연산자 뒤에 문자열이 오는 숫자입니다. '1. "abc"' – axiac

+0

@axiac 그 의미는 "(연산자가 아님)"이지만, "1"과 "1.1"사이에는 뚜렷한 차이가 있습니다. 연산자와'1.1'은 그것을 float로 만듭니다.따라서 PHP 인터프리터의 근시는 혼란 스럽지만 이해할 만하다. – Xorifelse

0

성명 :
echo "test string ". $var+1 ." example";
이 예상대로 작동하지 않을 수도 있습니다. test string 2 example 대신 1 example이 인쇄 될 수 있습니다.
"test string ". $var+1 ." example";
첫 번째는 "test string는"(문자열 변수) $var에 연결됩니다 하고 있습니다 결과 string 1에서 (문자열 :

당신은 또한 예상치 못한 결과를 도출하기 위하여 유용

var_dump(1) gives `int 1` and 
var_dump(1.) gives `float 1` and as expected 
var_dump(1.0) gives `float 1` as answer 

이유를 찾을 수 있습니다) 그리고 나서 (이 연결되지 않고이 연결되지 않음) PHP가 **string 1** (문자열)의 유형을 으로 변경하면 다음과 같이됩니다. e 0으로하고 1에 더하여 1 (0 + 1 = 1)이됩니다. 그런 다음 1 (int에서 문자열로 다시 변환 됨)이 example (문자열)에 추가되어 1 example (문자열)이됩니다. 당신이 바로 옆에`integer`에 지점을 가지고 있기 때문에 PHP`는 부동 소수점을 기대하고있다 '때문에 이러한 유형을 피하기 위해

사용 괄호 당신이 마지막 문장에서 같은 enter code here

echo "test string ".($var+1)." example";