PHP에서 빈 값으로 기본 객체를 만드시겠습니까?


362

PHP 환경을 PHP 5.4 이상으로 업그레이드 한 후에 만이 오류가 나타납니다. 오류는 다음 코드 줄을 가리 킵니다.

오류:

빈 값에서 기본 객체 생성

암호:

$res->success = false;

먼저 $res객체 를 선언해야 합니까?


11
어떻게 / 어디서 시작 $res 합니까?
Naveed

1
@NAVEED 있습니다 .
7heo.tk

답변:


627

새로운 환경 에서 PHP 버전 <= 5.3.x 대해 E_STRICT경고가 활성화error_reporting 되었거나 단순히 PHP 버전> = 5.4로 error_reporting설정 되었을 수 있습니다 E_WARNING. 그 때 오류가 트리거 $res입니다 NULL거나 아직 초기화되지 :

$res = NULL;
$res->success = false; // Warning: Creating default object from empty value

PHP $res는 이미 어떤 값으로 초기화되었지만 객체가 아닌 경우 다른 오류 메시지를보고 합니다 :

$res = 33;
$res->success = false; // Warning: Attempt to assign property of non-object

일반 객체를 생성하고 속성을 할당한다고 가정 할 때 E_STRICTPHP 5.4 이전의 표준 또는 E_WARNINGPHP> = 5.4 의 일반 오류 수준 을 준수 하려면 전역 네임 스페이스에서 객체 success로 선언해야 합니다.$resstdClass

$res = new \stdClass();
$res->success = false;

38
객체가 이미 존재하는지 확인해야합니다 if (!isset($res)) $res = new stdClass();. 그렇지 않으면이 코드는 "오래된 PHP"암시 적 객체 생성을 대체하는 것이 아닙니다.
TMS

6
@Tomas 다시해야합니까? mods는 값을 거의 추가하지 않았기 때문에 주석 스레드를 마지막으로 정리했습니다. "오래된 PHP"암시 적 객체 생성은 없습니다. 5.4에서 항상 E_STRICT에서 E_WARNING으로 변경 되었기 때문에 항상 오류였으며 항상 경고를 표시했습니다.
Michael Berkowski

4
@PeterAlfvin 하나의 특정 실행에 정의되지 않았습니다 ! 그러나 다른 실행 에서 코드의 정확한 위치에서 객체가 이미 정의되었을 수 있습니다! 이것은 사람들이 종종 생각하는 실수이며 이것이 제가 강조하려고하는 이유입니다.
TMS

2
묵시적 객체 생성은 항상 5.4에도 있었으며 여전히 존재합니다. 그리고 BTW PHP <5.3에서는 E_STRICT 나 E_WARNING이 아닙니다. 그리고 BTW, 개조 자들은 그 의견을 복원했고, 그 의견을 거절하라는 말을 들었습니다. 그래서 나는 그것을 다시 게시했습니다.
TMS

3
@tomas 오, 알았어 . 네가 무슨 뜻인지 알 것 같아 당신 / 마이클이 이것에 대해 폐쇄 할 수없는 것은 이상한 것 같습니다. BTW,이 교환은 이탤릭체 <볼드 <모두 "강도"의 관점에서, 그리고 올 캡스-소리와 이탤릭체-폴리 마 엠파시이지만, 굵은 글씨는 수용이 의심스러운 중간 지점에 있다는 것을 깨달았습니다. :-)
Peter Alfvin

57

이 메시지는 E_STRICTPHP <= 5.3에 대한 것입니다. PHP 5.4부터 불행하게도로 변경되었습니다 E_WARNING. E_WARNING메시지는 유용 하기 때문에 완전히 비활성화하지 않으려 고합니다.

이 경고를 없애려면 다음 코드를 사용해야합니다.

if (!isset($res)) 
    $res = new stdClass();

$res->success = false;

이것은 완전히 동등한 대체품 입니다. PHP가 자동으로 수행하는 것과 똑같은 일을 보장합니다-불행히도 경고와 함께 암시 적 객체 생성. 개체가 존재하지 않는지 확실하지 않으면 개체가 이미 존재하는지 항상 확인해야합니다. Michael이 제공하는 코드는 일반적으로 좋지 않습니다. 일부 상황에서는 개체가 상황에 따라 코드의 동일한 위치에 이미 정의되어있을 수 있기 때문입니다.


2
@carlosvini, 이것은 당신에게 줄 것이다 Undefined variable: res.
Pacerier

1
@Pacerier 당신이 옳습니다, 당신이 할 수있는 최선은 : $ res = isset ($ res)? $ res : 새로운 stdClass (); -6 개월 전에 E_NOTICE를 활성화하지 않은 이유는 너무 장황했기 때문입니다.
carlosvini

13

간단히,

    $res = (object)array("success"=>false); // $res->success = bool(false);

또는 다음을 사용하여 클래스를 인스턴스화 할 수 있습니다.

    $res = (object)array(); // object(stdClass) -> recommended

    $res = (object)[];      // object(stdClass) -> works too

    $res = new \stdClass(); // object(stdClass) -> old method

다음으로 값을 채 웁니다.

    $res->success = !!0;     // bool(false)

    $res->success = false;   // bool(false)

    $res->success = (bool)0; // bool(false)

더 많은 정보 : https://www.php.net/manual/en/language.types.object.php#language.types.object.casting


왜 새로운 stdClass ()가 "old"메소드로 간주됩니까? 다른 사람들은 어떻게 든 더 나은가?
Aaron

그것은 단순히 오래된 PHP 버전에서
온다

내 경우에는 $this->route->uri = new stdClass();나를 위해 작동하지 않지만 여전히 경고가 있습니다. 참고 : $this->route기존입니다.
Meloman

어쩌면 이것은 새로운 버전의 PHP와 호환되지 않습니까? 어떤 버전을 사용 했습니까?
pirs

6

"@"문자를 줄의 시작 부분에 넣으면 PHP는이 줄에 대한 경고 / 공지 사항을 표시하지 않습니다. 예를 들면 다음과 같습니다.

$unknownVar[$someStringVariable]->totalcall = 10; // shows a warning message that contains: Creating default object from empty value

이 줄에 대한이 경고를 방지하려면 "@"문자를 다음과 같이 줄의 맨 앞에 두어야합니다.

@$unknownVar[$someStringVariable]->totalcall += 10; // no problem. created a stdClass object that name is $unknownVar[$someStringVariable] and created a properti that name is totalcall, and it's default value is 0.
$unknownVar[$someStringVariable]->totalcall += 10; // you don't need to @ character anymore.
echo $unknownVar[$someStringVariable]->totalcall; // 20

개발할 때이 트릭을 사용하고 있습니다. 경고를 올바르게 처리하지 않으면 모든 경고 메시지를 비활성화하지 않으므로 나중에 큰 오류가 발생합니다.


1
@는 경고를 억제하여 경고를 방지하고 관리 가능한 코드가있는 한 괜찮습니다. 그러나 코드가 더 커지고 문제가 발생하면 이것을 사용하여 후회하게됩니다. 당신이 숨기고 싶은 경고에 대해 모든 "@"을 찾고있는 것을 알게 될 것입니다. 일시적으로 그것이 실제로 당신과 대화하고있을 때 실제로 문제를 해결했다고 생각하고 그 목적은 ' 듣지 마
Vincent Edward Gedaria Binua

나는 이미 알고있다. 이것은 짧고 빠른 답변입니다. 이것에 대한 많은 해결책이 있습니다.
kodmanyagha

2
대박! 그래도 오류를 숨기는 것이 실제로 문제를 해결하지는 않습니다 (Ramy Nasr이 언급 한 것과 같이).
Vincent Edward Gedaria Binua

이 해결 방법은 PHP 7.2에서 유일하게 작동합니다.
Meloman

3

배열이 있고 객체를 추가하면 이것을 시도하십시오.

$product_details = array();

foreach ($products_in_store as $key => $objects) {
  $product_details[$key] = new stdClass(); //the magic
  $product_details[$key]->product_id = $objects->id; 
   //see new object member created on the fly without warning.
}

나중에 사용할 수 있도록 ARRAY of Objects 를 전송 합니다 ~!


감사합니다!!!! 이것이 작업을 완료하는 데 도움이 된 것입니다. 각 요소가 무엇인지 단계별로 PHP에 알려야했습니다. 게으른 lol을 코딩하지 말라고 상기시켜 주셔서 감사합니다.
yanike

2

이 시도:

ini_set('error_reporting', E_STRICT);

1
감사. nusoap과 같은 타사 라이브러리를 사용하고 소스를 원하지 않거나 변경할 수없는 경우에는 전체 사용입니다. 이 경우 다른 소스 파일이 필요하기 바로 전에 error_reporting을 E_STRICT 레벨로 변경할 수 있습니다 .
mtoloo

방금 nusoap 상단에 이것을 추가하여 문제를 해결했습니다.
badweasel

11
응? 이 코드 E_STRICT는 치명적 오류에 대한 메시지 억제를 포함하여 오류를 제외한 모든 오류보고를 비활성화 합니다. 그것은이 특별한 경고를 해결하기위한 합리적인 제안이 아니며, 더 중요한 것은 당신이 거의 원하지 않는 것입니다. 왜 5 명이 이것을 찬성했는지 모르겠습니다.
Mark Amery

1
이것은 매우 나쁘다! ini_set('error_reporting', -1);디버깅 하는 동안 사용 하지만 위와 같이 사용하지 마십시오.
Kzqai

좋아, 그래서 당신은 이것을 숨겨서 문제를 해결합니까? 코드가 예상대로 작동하는지 확실하지 않은 경우 ...
pirs

1

비슷한 문제가 있었는데 문제가 해결 된 것 같습니다. $ res 객체를 클래스로 초기화하면됩니다. 여기서 클래스 이름이 test라고 가정하십시오.

class test
{
   //You can keep the class empty or declare your success variable here
}
$res = new test();
$res->success = false;

1

이것은 PHP 7에서 직면 한 경고입니다.이를 쉽게 해결하는 것은 변수를 사용하기 전에 초기화하는 것입니다

$myObj=new \stdClass();

일단 초기화하면 객체에 사용할 수 있습니다

 $myObj->mesg ="Welcome back - ".$c_user;

0

이 문제점은 시작되지 않은 오브젝트 인스턴스에 지정하기 때문에 발생합니다. 예를 들어 :

너의 경우:

$user->email = 'exy@gmail.com';

해결책:

$user = new User;
$user->email = 'exy@gmail.com';

"User"클래스가 있다고 가정하지 않습니까? 그렇지 않으면 지금 다른 오류가 발생합니까?
Christopher Thomas

1
실제로 나는 User 객체의 인스턴스를 만들지 않았으므로 오류가 발생했습니다. 그러나 인스턴스를 만든 후. 그것은 효과가 있었다. OOPs 개념의 일반적인 문제 :)
Bastin Robin

6
실제로 실제 문제는 예제에서 사용자 클래스가 정의되었다고 가정한다는 것입니다. 이것은 객체 지향의 일반적인 문제가 아니며 핵심 요구 사항입니다.)
Christopher Thomas

1
차라리 "User"라는 전제를 대체하는 일반적인 "stdClass"를 사용하고 싶습니다.
TechNyquist

0

이 오류를 얻는 간단한 방법은 아래 (a)를 입력하는 것입니다.

(ㅏ) $this->my->variable

(비) $this->my_variable

사소하지만, 간과하기 쉽지만 간과하기 쉽지 않습니다.


이것은 원래 질문과 어떤 관련이 있습니까? _->
Nico Haase

0

변수가 선언되었고 올바른 유형인지 확인해야 할 수도 있습니다.

if (!isset($res) || !is_object($res)) {
    $res = new \stdClass();
    // With php7 you also can create an object in several ways.
    // Object that implements some interface.
    $res = new class implements MyInterface {};
    // Object that extends some object.
    $res = new class extends MyClass {};
} 

$res->success = true;

PHP 익명 클래스를 참조하십시오 .


0

API에서 반환 된 객체에 변수를 추가하려고 할 때 비슷한 문제가 발생했습니다. foreach 루프를 사용하여 데이터를 반복하고있었습니다.

foreach ( $results as $data ) {
    $data->direction = 0;
}

Laravel에서 "빈 값으로 기본 객체 생성"예외가 발생했습니다.

나는 아주 작은 변화로 그것을 고쳤다.

foreach ( $results as &$data ) {
    $data->direction = 0;
}

단순히 $ data를 참조로 만들어서.

나는 누군가에게 도움이되기를 바랍니다.


0
  1. 먼저 객체 $ res = new \ stdClass ()를 만들어야한다고 생각하십시오.

  2. 그런 다음 키와 값으로 객체를 할당하십시오. thay $ res-> success = false;


(이해할 수 없습니다 thay.) 일부 내용 다음에 줄 바꿈을 원하는 경우 구분하기 전에 줄의 보이는 내용에 두 개의 공백을 추가하십시오.
greybeard

-1

아니요 .. 개체에 성공 값을 추가하면 생성됩니다. 기본 클래스는 지정하지 않으면 상속됩니다.


4
엄격한 표준 메시지를 반환하지만 ... 먼저 수동으로 객체를 생성하는 것이 좋으며 PHP는 상대적으로 엉뚱한 코딩 관행에 견딜 수 있지만 올바르게 수행하는 것을 무시해서는 안됩니다.
Mark Baker

4
이해, 나는 그냥 예 또는 아니오로 질문에 대답하고 모범 사례를 정의하거나 방어하지 않습니다 :)
Silvertiger

-1

다음을 사용하십시오.

$user = (object) null;

2
일반적으로 코드의 목적과 다른 언어를 도입하지 않고 문제를 해결하는 이유에 대한 설명이 포함되어 있으면 답변이 훨씬 유용합니다.
lucascaro

-12

결함이있는 PHP 파일의 맨 위에 다음을 입력했는데 오류가 더 이상 표시되지 않았습니다.

error_reporting(E_ERROR | E_PARSE);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.