programing

PHP에는 구조 데이터 타입이 있습니까?

sourcejob 2022. 9. 21. 23:29
반응형

PHP에는 구조 데이터 타입이 있습니까?

PHP에 구조 데이터 타입 같은 것이 있습니까?이를 보다 잘 이해할 수 있도록 구조 데이터 유형의 예를 들어줄 수 있는 사람이 있습니까?

이러한 데이터 유형이 없는 경우 구조체처럼 작동하는 데이터 유형은 어떻게 얻을 수 있습니까?

구조물에 가장 가까운 것은 모든 구성원이 공개되어 있는 물체입니다.

class MyStruct {
    public $foo;
    public $bar;
}

$obj = new MyStruct();
$obj->foo = 'Hello';
$obj->bar = 'World';

PHP Class Documentation을 볼 가치가 있다고 생각합니다.일회성 구조가 필요한 경우 Alex의 답변에 나와 있는 StdObject를 사용합니다.

어레이를 사용할 수 있습니다.

$something = array(
   'key' => 'value',
   'key2' => 'value2'
);

또는 표준 오브젝트를 사용합니다.

$something = new StdClass();

$something->key = 'value';
$something->key2 = 'value2';

저는 두 가지를 추천합니다.첫 번째는 연관 배열입니다.

$person = Array();
$person['name'] = "Joe";
$person['age'] = 22;

두 번째는 수업입니다.

상세한 것에 대하여는, http://php.net/manual/en/language.oop5.php 를 참조해 주세요.

이것은 구글에서 상당히 높은 수치이기 때문에 PHP8 구문을 사용한 의사 구조의 실장을 공유하려고 합니다.toArray() 메서드는 Illuminate\에 의존합니다.Support\Str 키를 snake case로 변환합니다(Laravel 모델에 대한 대량 할당에 유용). 단, 사용 사례에 맞지 않는 경우에는 삭제합니다.

기본 클래스:

<?php

namespace App\Infrastructure\Structs;

use App\Infrastructure\Exceptions\CannotMutateStructException;
use App\Infrastructure\Exceptions\ClassPropertyNotFoundException;
use Illuminate\Support\Str;
use ReflectionClass;

abstract class Struct
{
    /**
     * @param string $name
     * @param mixed $value
     * @throws CannotMutateStructException
     */
    public function __set(string $name, mixed $value): void
    {
        throw new CannotMutateStructException(
            'Structs are immutable. If you need mutable data then use a class instead.'
        );
    }

    public function all(): array
    {
        $reflector = new ReflectionClass(static::class);
        $response = [];

        foreach ($reflector->getProperties() as $property) {
            $response[$property->name] = $this->{$property->name};
        }

        return $response;
    }

    public function toArray(bool $snakeCase = false): array
    {
        $all = self::all();

        if ($snakeCase === false) {
            return $all;
        }

        $snakeCaseAll = [];

        foreach ($all as $key => $value) {
            $snakeCaseAll[Str::snake($key)] =  $value;
        }

        return $snakeCaseAll;
    }
}

사용방법:

<?php

namespace App\Infrastructure\Structs;

class Person extends Struct
{
    public function __construct(
        public string $name,
        public int $age,
        public int $heightInCentimetres,
    ) {}
}

조작 방법:

>>> $t = new \App\Infrastructure\Structs\Person('Max', 26, 182);

>>> $t->age
=> 26

>>> $t->age = 40
App\Infrastructure\Exceptions\CannotMutateStructException with message 'Structs are immutable. If you need mutable data then use a class instead.'

>>> $t->toArray(true)
=> [
     "name" => "Max",
     "age" => 26,
     "height_in_centimetres" => 182,
   ]

이게 도움이 됐으면 좋겠는데

편집: PHP8.1에서는 이를 더욱 간결하게 할 수 있는 읽기 전용 속성을 갖게 되었습니다.

편집: PHP8.2를 통해 보다 간결한 방법으로 이 작업을 수행할 수 있게 되었습니다.이 기사 전체를 읽어보시는 것이 좋습니다.https://stitcher.io/blog/evolution-of-a-php-object

으로는 이렇게 게 일반적입니다.readonly class Foo {}각 속성에 대해 추가할 필요가 없습니다.

저는 오늘 '다이나믹' 구조 클래스를 만들고, 오늘 밤 살펴보았습니다.그리고 누군가 컨스트럭터 파라미터를 더 잘 다루는 비슷한 것을 썼기 때문에 볼 가치가 있을지도 모릅니다.

http://code.activestate.com/recipes/577160-php-struct-port/

이 페이지의 코멘트 중 하나는 PHP의 흥미로운 점을 언급하고 있습니다.배열을 오브젝트로 캐스팅할 수 있다고 합니다.이것에 의해, C의 Structure 포인터와 같이 화살표 표기법을 사용해 어레이 요소를 참조할 수 있습니다.코멘트의 예는 다음과 같습니다.

$z = array('foo' => 1, 'bar' => true, 'baz' => array(1,2,3));
//accessing values as properties
$y = (object)$z;
echo $y->foo;

저는 아직 시도해보지 않았지만, 캐스팅만 하면 원하는 표기법을 얻을 수 있을지도 모릅니다.이는 물론 해시 내의 키/값 쌍에 액세스하기 위한 통사적 설탕인 '동적' 데이터 구조입니다.

만약 당신이 실제로 정적인 타입을 찾고 있다면, AS펜서의 대답은 당신이 찾고 있는 드로이드입니다(Obi-Wan이 말하는 것처럼).

아무래도...struct데이터형은 SOAP에서 일반적으로 사용됩니다.

var_dump($client->__getTypes());

array(52) {
  [0] =>
  string(43) "struct Bank {\n string Code;\n string Name;\n}"
}

기본 PHP 데이터 형식이 아닙니다!

의 특성은 다음과 같습니다.structSOAP에서 참조되는 유형은 단순한 PHP로 액세스할 수 있습니다.stdClass오브젝트:

$some_struct = $client->SomeMethod();
echo 'Name: ' . $some_struct->Name;

연관 배열만이 PHP의 구조체입니다.

그리고 당신은 그들을 스스로 엄격하게 만들 수 없습니다.

그러나 클래스나 인터페이스에서는 구조적인 엄격함을 가장할 수 있지만 구조와는 달리 클래스 인스턴스는 인수로 전달되지 않으며 식별자는 그렇지 않다는 점에 유의하십시오.


인터페이스를 통해(또는 적어도 그 근처에) 구조체를 정의할 수 있습니다.

구조는 개체에 특정 구조를 적용합니다.

PHP(<= 7.3)는 네이티브 구조를 가지고 있지 않지만 인터페이스를 사용하여 회피할 수 있으며 다음과 같이 입력할 수 있습니다.

interface FooStruct 
{
    public function name() : string;
}
interface BarStruct 
{
    public function id() : int;
}
interface MyStruct 
{
   public function foo() : FooStruct;
   public function bar() : BarStruct;
}

구현 중인 모든 클래스MyStruct가 될 것이다MyStruct.

구축 방식은 구조에 따라 달라지지 않으며 반환된 데이터가 정확함을 보장할 뿐입니다.


데이터를 설정하는 것은 어떨까요?

구조 데이터를 설정하는 것은 게터나 세터로 끝나기 때문에 문제가 있으며 빈혈 객체나 DTO에 가깝고 일부 사람들에 의해 안티 패턴으로 간주됩니다.

잘못된 예:

interface FooStruct 
{
    public function getName() : string;
    public function setName(string $value) : FooStruct;
}
interface BarStruct 
{
    public function getId() : int;
    public function setId(int $value) : BarStruct;
}
interface MyStruct 
{
   public function getFoo() : FooStruct;
   public function setFoo(FooStruct $value) : MyStruct;
   public function getBar() : BarStruct;
   public function setBar(BarStruct $value) : MyStruct;
}

그 후 클래스 구현이 이루어지며, 구조체는 변이되어서는 안 됩니다.이것은, 다음과 같이 「데이터 타입」으로 하기 위해서입니다.int,string그러나 PHP의 인터페이스에서는 이를 제한할 방법이 없습니다.즉, 사람들은 구조가 아닌 클래스에서 당신의 구조 인터페이스를 구현할 수 있습니다.인스턴스를 불변 상태로 유지하십시오.

또한 올바른 데이터 없이 구조가 인스턴스화되어 데이터에 액세스하려고 할 때 오류가 트리거될 수 있습니다.

PHP 구조 클래스에서 데이터를 설정하는 쉽고 신뢰할 수 있는 방법은 생성자를 사용하는 것입니다.

interface FooStruct 
{
    public function name() : string;
}
interface BarStruct 
{
    public function id() : int;
}
interface MyStruct 
{
   public function foo() : FooStruct;
   public function bar() : BarStruct;
}

class Foo implements FooStruct 
{
   protected $name;
   public function __construct(string $name)
   {
       $this->name = $name;
   }
   public function name() : string
   {
       return $this->name;
   }
}

class Bar implements BarStruct 
{
   protected $id;
   public function __construct(string $id)
   {
       $this->id = $id;
   }
   public function id() : int
   {
       return $this->id;
   }
}

class My implements MyStruct 
{
   protected $foo, $bar;
   public function __construct(FooStruct $foo, BarStruct $bar)
   {
       $this->foo = $foo;
       $this->bar = $bar;
   }
   public function foo() : FooStruct
   {
       return $this->foo;
   }
   public function bar() : BarStruct
   {
       return $this->bar;
   }
}

인터페이스를 사용한 힌트 입력: (IDE가 지원하는 경우)

엄격한 타입 체크가 필요 없는 경우는, IDE 에 코멘트가 있는 인터페이스나 클래스를 사용하는 것도 가능합니다.

/**
 * Interface My
 * @property Foo $foo
 * @property Bar $bar
 */
interface My 
{

}

/**
 * Interface Foo
 * @property string|integer $id
 * @property string $name
 */
interface Foo 
{

}

/**
 * Interface Bar
 * @property integer $id
 */
interface Bar
{

}

클래스가 아닌 인터페이스를 사용하는 이유는 인터페이스가 존재하는 이유와 같은 이유입니다.이는 많은 실장을 가진 많은 클래스가 동일한 구조를 가질 수 있으며 이를 사용하는 각 메서드/함수가 이 인터페이스를 가진 모든 클래스를 지원하기 때문입니다.

IDE에 따라 다르므로 클래스를 대신 사용하거나 IDE 없이 살아야 할 수 있습니다.

주의: 코드의 다른 위치에 있는 인스턴스에서 코멘트를 일치시키려면 데이터를 검증/위생해야 합니다.

퍼블릭 클래스도 옵션 중 하나입니다.더 캡슐화된 것을 원할 경우 추상/익명의 클래스 조합을 사용할 수 있습니다.제가 가장 좋아하는 부분은 (PhpStorm의 경우) 자동완성이 여전히 작동한다는 것입니다만, 저는 공개수업을 하고 있지 않습니다.

<?php

final class MyParentClass
{
    /**
     * @return MyStruct[]
     */
    public function getData(): array
    {
        return array(
            $this->createMyObject("One", 1.0, new DateTime("now")),
            $this->createMyObject("Two", 2.0, new DateTime("tommorow"))
        );
    }

    private function createMyObject(string $description, float $magnitude, DateTime $timeStamp): MyStruct
    {
        return new class(func_get_args()) extends MyStruct {
            protected function __construct(array $args)
            {
                $this->description = $args[0];
                $this->magnitude = $args[1];
                $this->timeStamp = $args[2];
            }
        };
    }
}

abstract class MyStruct
{
    public string $description;
    public float $magnitude;
    public DateTime $timeStamp;
}

언급URL : https://stackoverflow.com/questions/3861353/does-php-have-a-struct-data-type

반응형