0

I have about twenty different classes that are segregated in an assoc array similar to this:

class a {public $val = 1;}
class b {public $val = 2;}
$classes = array("one"=>'a', "two"=>'b');
var_dump(new $classes["one"]()); // object(a)#1 (1) { ["val"]=> int(1) }
var_dump(new $classes["two"]()); // object(b)#1 (1) { ["val"]=> int(2) }

But now I want to do the array constant.

I can make it using const VAL = array(); just fine. The problem lies in making new objects using those classes

class a {public $val=1;}
class b {public $val=2;}
const CLASSES = array("one"=>'a', "two"=>'b');
var_dump(new CLASSES["one"]());

fails with Parse error: syntax error, unexpected '[', expecting ')' error.

I figured that I could reverse const array to variable again and it works fine:

class a {public $var = 1;}
class b {public $var = 2;}
const CLASSES = array("one"=>'a', "two"=>'b');
$tempClasses = CLASSES;
var_dump(new $tempClasses["one"]()); // works

but why doesn't it work with a constant array?

I tried playing with parenthesis and constant() too. Neither new (CLASSES)["one"](), new (CLASSES["one"])(), new constant(CLASSES)["one"]() nor new constant(CLASSES["one"])() work.

Is there something I'm missing?

SkillGG
  • 647
  • 4
  • 18
  • 3
    `new (CLASSES["one"])()` works in PHP 8+. Demo: https://3v4l.org/BUJ8H. Otherwise, you can do `$one = CLASSES['one']; new $one();` in all versions. Demo: https://3v4l.org/89PP3 – M. Eriksson Aug 11 '21 at 17:45
  • so it wasn't implemented before... that sucks. – SkillGG Aug 11 '21 at 17:52
  • I don’t know what you are exactly doing, but your code looks like it is going down an enum-like path which is [coming in 8.1](https://stitcher.io/blog/php-enums) and has existing support using many libraries, including [this](https://github.com/myclabs/php-enum) – Chris Haas Aug 12 '21 at 01:47
  • If you aren’t going down enum path, this feels like a general factory pattern decide – Chris Haas Aug 12 '21 at 01:48
  • https://stackoverflow.com/q/20278476/2943403 , https://stackoverflow.com/q/534159/2943403 – mickmackusa Aug 12 '21 at 04:22
  • I get user input word, then `strtolower` it and then do `CLASSES[$input]`. Because I don't want my classes to be all lowercase, and because I don't want to make a large switch statement (or regex if hell) with all possible inputs pointing to correct classes I just made an assoc array with "input"=>"ClassName" pairs. I of course check with `isset(CLASSES[$input])` if the input has a class corresponding to it. – SkillGG Aug 13 '21 at 17:26
  • At first I did it with `$classes` array but then I thought "Could I do it const?" and I failed to do it without making additional variable to "convert" constant array to a variable one – SkillGG Aug 13 '21 at 17:33

1 Answers1

1

I don't know why you would, but yes you can:

<?php

class a {public $val=1;}
class b {public $val=2;}
const CLASSES = array("one"=>'a', "two"=>'b');


$obj = (new ReflectionClass(CLASSES["one"]))->newInstance();

var_dump($obj);
Erik
  • 384
  • 1
  • 9
  • That looks way worse than php8.0 additional parenthesis solution, but it works for php<8.0 so thanks! I just changed to php8.0 – SkillGG Aug 13 '21 at 17:39