IT story

PHP 7 이전에“문자열, 문자열이 주어져야한다”를 어떻게 해결합니까?

hot-time 2020. 5. 5. 19:39
반응형

PHP 7 이전에“문자열, 문자열이 주어져야한다”를 어떻게 해결합니까?


내 코드는 다음과 같습니다.

function phpwtf(string $s) {
    echo "$s\n";
}
phpwtf("Type hinting is da bomb");

이 오류가 발생하는 원인은 다음과 같습니다.

잡을 수있는 치명적 오류 : phpwtf ()에 전달 된 인수 1은 문자열의 문자열이어야합니다.

PHP가 같은 호흡에서 원하는 유형을 인식하고 거부하는 것을 보는 것은 조금 Orwellian 이상입니다. 5 개의 조명이 있습니다.

PHP에서 문자열에 대한 유형 힌트와 동등한 것은 무엇입니까? 여기서 무슨 일이 일어나고 있는지 정확하게 설명하는 답변에 대한 보너스 고려.


PHP 7 이전에는 타입 힌트 를 사용하여 객체와 배열의 타입을 강제 할 수 있습니다. 스칼라 형식은 형식이 불가능합니다. 이 경우 클래스의 객체 string가 예상되지만 (스칼라) 제공 string합니다. 오류 메시지가 재미있을 수도 있지만 처음부터 작동하지는 않습니다. 다이나믹 한 타이핑 시스템을 감안할 때, 이것은 실제로 일종의 왜곡 된 의미를 갖습니다.

스칼라 유형은 수동으로 "힌트 힌트" 만 할 수 있습니다 .

function foo($string) {
    if (!is_string($string)) {
        trigger_error('No, you fool!');
        return;
    }
    ...
}

에서 PHP 설명서 :

타입 힌트는 객체와 배열 (PHP 5.1부터) 타입 만 될 수 있습니다. int 및 string을 사용한 전통적인 유형 힌트는 지원되지 않습니다.

그래서 당신은 그것을 가지고 있습니다. 오류 메시지는 실제로 도움이되지 않습니다.

** 2017 년 편집 **

PHP7은 더 많은 함수 데이터 유형 선언을 도입했으며, 위에서 언급 한 링크는 함수 인수 : 유형 선언 으로 이동되었습니다 . 해당 페이지에서 :

유효한 유형

  • 클래스 / 인터페이스 이름 : 매개 변수는 지정된 클래스 또는 인터페이스 이름의 인스턴스 여야합니다. (PHP 5.0.0부터)
  • self : 매개 변수는 메소드가 정의 된 클래스와 동일한 클래스의 인스턴스 여야합니다. 이것은 클래스 및 인스턴스 메소드에서만 사용할 수 있습니다. (PHP 5.0.0부터)
  • array : 매개 변수는 배열이어야합니다. (PHP 5.1.0부터) callable이 매개 변수는 유효한 호출 가능해야합니다. PHP 5.4.0
  • bool : 매개 변수는 부울 값이어야합니다. (PHP 7.0.0부터)
  • float : 매개 변수는 부동 소수점 숫자 여야합니다. (PHP 7.0.0부터)
  • int : 매개 변수는 정수 여야합니다. (PHP 7.0.0부터)
  • string : 매개 변수는 문자열이어야합니다. (PHP 7.0.0부터)
  • iterable : 매개 변수는 Traversable의 배열 또는 인스턴스 여야합니다. (PHP 7.1.0부터)

경고

위의 스칼라 유형에 대한 별명은 지원되지 않습니다. 대신 클래스 또는 인터페이스 이름으로 취급됩니다. 예를 들어, 부울을 매개 변수 또는 리턴 유형으로 사용하려면 bool 유형이 아닌 클래스 또는 인터페이스 부울의 인스턴스 인 인수 또는 리턴 값이 필요합니다.

<?php
   function test(boolean $param) {}
   test(true);
 ?>

위의 예는 다음과 같이 출력됩니다.

 Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of boolean, boolean given, called in - on line 1 and defined in -:1

The last warning is actually significant to understand the error "Argument must of type string, string given"; since mostly only class/interface names are allowed as argument type, PHP tries to locate a class name "string", but can't find any because it is a primitive type, thus fail with this awkward error.


PHP allows "hinting" where you supply a class to specify an object. According to the PHP manual, "Type Hints can only be of the object and array (since PHP 5.1) type. Traditional type hinting with int and string isn't supported." The error is confusing because of your choice of "string" - put "myClass" in its place and the error will read differently: "Argument 1 passed to phpwtf() must be an instance of myClass, string given"


As others have already said, type hinting currently only works for object types. But I think the particular error you've triggered might be in preparation of the upcoming string type SplString.

In theory it behaves like a string, but since it is an object would pass the object type verification. Unfortunately it's not yet in PHP 5.3, might come in 5.4, so haven't tested this.


As of PHP 7.0 type declarations allow scalar types, so these types are now available: self, array, callable, bool, float, int, string. The first three were available in PHP 5, but the last four are new in PHP 7. If you use anything else (e.g. integer or boolean) that will be interpreted as a class name.

See the PHP manual for more information.


I got this error when invoking a function from a Laravel Controller to a PHP file.

After a couple of hours, I found the problem: I was using $this from within a static function.


(originally posted by leepowers in his question)

The error message is confusing for one big reason:

Primitive type names are not reserved in PHP

The following are all valid class declarations:

class string { }
class int { }
class float { }
class double { }

My mistake was in thinking that the error message was referring solely to the string primitive type - the word 'instance' should have given me pause. An example to illustrate further:

class string { }
$n = 1234;
$s1 = (string)$n;
$s2 = new string();
$a = array('no', 'yes');
printf("\$s1 - primitive string? %s - string instance? %s\n",
        $a[is_string($s1)], $a[is_a($s1, 'string')]);
printf("\$s2 - primitive string? %s - string instance? %s\n",
        $a[is_string($s2)], $a[is_a($s2, 'string')]);

Output:

$s1 - primitive string? yes - string instance? no

$s2 - primitive string? no - string instance? yes

In PHP it's possible for a string to be a string except when it's actually a string. As with any language that uses implicit type conversion, context is everything.


I think typecasting on php on inside block, String on PHP is not object as I know:

<?php
function phpwtf($s) {
    $s = (string) $s;
    echo "$s\n";
}
phpwtf("Type hinting is da bomb");

Maybe not safe and pretty but if you must:

class string
{
    private $Text;
    public function __construct($value)
    {
        $this->Text = $value;
    }

    public function __toString()
    {
        return $this->Text;
    }
}

function Test123(string $s)
{
    echo $s;
}

Test123(new string("Testing"));

참고URL : https://stackoverflow.com/questions/4103480/how-to-resolve-must-be-an-instance-of-string-string-given-prior-to-php-7

반응형