Hacker News new | ask | show | jobs
by TrispusAttucks 1670 days ago
I never had to do this and I don't believe you can do this directly via a language construct but you can do it within a class via a method or trait or static function. This trait can then be applied to any class. Probably be better though to just have a create function that takes an input of type and coverts to class.

Anyway I was curious so I wanted to try this out with the trait method here is working code that illustrates this.

    <?php

    /* trait to cast from any iterable to class */
    /* reusable - close to what I think you are asking for */
    trait castFrom
    {
        static function castFrom($data)
        {
            if (!is_iterable($data) and !is_array($data) and !is_object($data)) return null;
            $class = new self();
            foreach((array)$data as $key => $value)
            {
                if (!property_exists($class, $key)) continue;
                $class->$key = $value;
            }
            return $class;
        }
    }

    class Foo
    {
        use castFrom; // use the castFrom trait
        public string $str = 'blah';
        public int $num = 5;
        public function hello() { echo "{$this->str} : {$this->num}\n"; }
    }

    class Bar
    {
       use castFrom; // we can use the castFrom trait again and again
       public int $x = 0;
       public int $y = 0;
       public function hello() { echo ($this->x * $this->y) . "\n"; }
    }

    $data = ['str' => 'foo', 'num' => 7, 'x' => 3, 'y' => 7];

    $foo = Foo::castFrom($data);
    $foo->hello();

    print_r($foo);

    $obj = (object)$data;

    $bar = Bar::castFrom($obj);
    $bar->hello();

    print_r($bar);

    /* you could just use create functions form the class */
    class Creator
    {
        static public function createFromArray($data)  {} // create from array
        static public function createFromObject($data) {}   // create from object
        static public function createFromSerial($data) {}   // etc..
        static public function createFromJson($data)   {}
    }

EDIT: Added ugly check to make sure the type can be iterated over.