0
votes

but, composer DOES autoload same baseclass in the same folder.

My error: Fatal error: Class 'VendorName\ParentFolder\Enums\BasicEnum not found in C:\VendorName\www\src\ParentFolder\Enums\MyEnumeration.php on line 5.

MyEnumeration.php:

<?php
  namespace VendorName\ParentFolder\Enums;


  abstract class MyEnumeration extends BasicEnum {
      const ConstantOne = 1;
      const ConstantTwo = 2;
      const ConstantThree = 3;
}

and BasicEnum.php:

<?php
namespace VendorName\ParentFolder;

abstract class BasicEnum {
    private static $constCacheArray = NULL;

    private function __construct() { }

    private static function getConstants() {
        if (self::$constCacheArray == NULL) {
            self::$constCacheArray = [];
        }
        $calledClass = get_called_class();
        if (!array_key_exists($calledClass, self::$constCacheArray)) {
            $reflect = new ReflectionClass($calledClass);
            self::$constCacheArray[$calledClass] = $reflect->getConstants();
        }
        return self::$constCacheArray[$calledClass];
    }

    public static function isValidName($name, $strict = false) {
        $constants = self::getConstants();

        if ($strict) {
            return array_key_exists($name, $constants);
        }

        $keys = array_map('strtolower', array_keys($constants));
        return in_array(strtolower($name), $keys);
    }

    public static function isValidValue($value, $strict = true) {
        $values = array_values(self::getConstants());
        return in_array($value, $values, $strict);
    }
}

My folder structure:

+ VendorName
  + www
    + src
      + ParentFolder
        + Enums
              MyEnumeration.php
          BasicEnum2.php

And, the autoload is built via:

composer dump-autoload

with composer.json:

{
    "autoload": {
        "psr-4": { "VendorName\\": "src/"}

    }
}

My .php page:

<h1>Composer Autoload Test</h1>
<p>Trying to load a class where base class is in parent folder.
<p>(Using the PHP.net BasicEnum example).
<br/>
<?php
    require __DIR__ . '/vendor/autoload.php';

    use VendorName\ParentFolder;
    use VendorName\ParentFolder\Enums;



    echo '<br/><br/>';
    if (class_exists('MyEnumeration')) {
        echo 'MyEnumeration exists';
    }
    else {
        echo 'MyEnumeration does NOT exist';   // This line prints out in browser.
    }
    echo '<br/><br/>';

    echo '<br/><br/>';
    if (class_exists('VendorName\ParentFolder\Enums\MyEnumeration')) {  // This line blows up because BaseEnum is not found in MyEnumeration.php.
        echo 'VendorName\ParentFolder\Enums\MyEnumeration exists';
    }
    else {
        echo 'VendorName\ParentFolder\Enums\MyEnumeration does NOT exist';
    }
    echo '<br/><br/>';


    echo '<br/><br/>';
    if (defined('VendorName\ParentFolder\Enums\MyEnumeration::ConstantOne')) {
        echo 'VendorName\ParentFolder\Enums\MyEnumeration::ConstantOne exists';
    }
    else {
        echo 'VendorName\ParentFolder\Enums\MyEnumeration::ConstantOne does NOT exist';
    }
    echo '<br/><br/>';  


    echo 'NotExist:' . (MyEnumeration::isValidName('NotExist') ? 'true' : 'false') . '<br/>';
    echo 'ConstantOne:' . (MyEnumeration::isValidName('ConstantOne') ? 'true' : 'false') . '<br/>';
    echo 'ConstantTwo:' . (MyEnumeration::isValidName('ConstantTwo') ? 'true' : 'false') . '<br/>';
    echo 'ConstantThree:' . (MyEnumeration::isValidName('ConstantThree') ? 'true' : 'false') . '<br/>';

?>

Lastly, I have to full qualify the MyEnumeration with the namespace or it's not found even though I've got a 'use' statement and using composer autoload.

2
I'm a little lost by your folder structure. Which directory is your composer.json in?Matt Gibson
(Also, is "BasicEnum2.php" just a typo?)Matt Gibson
composer.json is in same folder as 'src' folder.user8628995
Yes, BasicEnum2.php is a typo.user8628995

2 Answers

0
votes

Your MyEnumeration class is in the namespace VendorName\ParentFolder\Enums. Hence it cannot find BasicEnum as a symbol as that's in the namespace above, \VendorName\ParentFolder. You can specify it absolutely in your child class:

abstract class MyEnumeration extends \VendorName\ParentFolder\BasicEnum {

You'll also need to indicate the global namespace for ReflectionClass in your BasicEnum:

$reflect = new \ReflectionClass($calledClass);

Note also that you can't just import everything from a namespace using use. You need to use particular classes. For example, in your php page, specify:

use VendorName\ParentFolder\Enums\MyEnumeration;

...to allow the use of MyEnumeration without a qualifier.

0
votes

It looks like you have
file src\ParentFolder\Enums\BasicEnum2.php
with class BasicEnum in namespace VendorName\ParentFolder

but you must have file src\ParentFolder\Enums\BasicEnum.php (without 2)
and in your MyEnumeration.php script you have to have this use block:

use VendorName\ParentFolder\BasicEnum;