Raymond
Raymond

Reputation: 115

Eclipse can not resolve classes autoloaded by Kohana framework (PHP framework)

I am assigned to work on maintaining an old PHP project. The PHP project uses Kohana framework. I installed Eclipse Oxygen for PHP developer and created a PHP project to include those PHP codes. But, I found that Eclipse Oxygen marks tons of errors due to unable to resolve the reference to our classes autoloaded by Kohana framework. Because, Kohana utilizes PHP's autoloading feature and change the class name. For example, we have a class called common_Core in common.php. Kohana autoloaded the class and change the class name to common.

In common.php:

class common_Core {
    public static function myFunc1() {
        . . .
    }
}

In client.php, we just reference this class with name common.

$result = common::myFunc1();

Eclipse Oxygen will mark common as not resolved and suggest to change to common_Core. Other Eclipse versions (Mars, Neon) won't mark those as errors but can not use Ctrl-click to jump to that method either. Does anyone use Kohana framework's autoload feature to load your own class? How do you make Eclipse to resolve your class?

As mentioned earlier, this is an old project contains tons of PHP codes. So, changing all reference from common:: to common_Core:: probably is not a good solution.

P.S. I just have an idea to change the class name from common_Core to common and that seems to fix the Eclipse issue. But, that also have the risk of class name conflict with other libraries unless namespace is used. This old PHP project does not use namespace. Anyway, still want to know if there is a way for Eclipse to work with PHP project using Kohana framework.

Upvotes: 0

Views: 643

Answers (2)

Raymond
Raymond

Reputation: 115

It seems that Kohana framework creates alias class names using eval() in runtime for autoloaded classes with certain postfix (e.g. common_Core -> common, email_Core -> email). Not sure why alias names are needed. That practice not only increase risk of name conflicts (some old PHP code don't use namespace), it confuses Eclipse and Eclipse marks those alias names as errors. With eval(), there is no way Eclipse (or any PHP IDE) can verify that alias class name because it is determined in runtime. An easy solution is to drop the postfix. For example, rename the class common_Core to common. Then, you can still use Kohana framework without the side effect.

Kohana.php:

. . .
. . .
        if ($filename = self::find_file($type, self::$configuration['core']['extension_prefix'].$class))
        {
            // Load the class extension
            require $filename;
        }
        elseif ($suffix !== 'Core' AND class_exists($class.'_Core', FALSE))
        {
            // Class extension to be evaluated
            $extension = 'class '.$class.' extends '.$class.'_Core { }';

            // Start class analysis
            $core = new ReflectionClass($class.'_Core');

            if ($core->isAbstract())
            {
                // Make the extension abstract
                $extension = 'abstract '.$extension;
            }

            // Transparent class extensions are handled using eval. This is
            // a disgusting hack, but it gets the job done.
            eval($extension);
        }

. . .
. . .

P.S. After reading Kohana framework in detail, I found the eval() is used to implement the so called Transparent Class Extending feature. Please see the two links below:

Transparent Class Extending: https://v2docs.kohanaframework.org/3.3/guide/kohana/extension

Cascading FileSystem: https://v2docs.kohanaframework.org/3.3/guide/kohana/files

I found it is wrong use of Kohana framework in our old code. We should not declare any class with _Core postfix as they are reserved for Kohana core classes for extending. Since there is no common_Core Kohana class, we should just name it as common. However, there is email_Core Kohana class, we should declare a class email to extend from email_Core.

in application directory:

class common {
// there is no common_Core in Kohana
}

class email extends email_Core {
// there is email_Core in Kohana
}

Anyway, I still think using eval() is bad practice and dangerous. That make Kohana framework not compatible with any other PHP IDE if you use the transparent class extension incorrectly.

Found other similar posting discussing the same issue: http://forum.kohanaframework.org/discussion/212/can-developers-remove-evalclass-class-extends-class-_core-/p1

Upvotes: 0

Rasclatt
Rasclatt

Reputation: 12505

It sounds like you have strange autoloading, especially if you have file named common.php that has a class named common_Core in it. Can you not make a newer standard in your new scripts with namespaces? I imagine your autoloader can handle this standard.

/vendor/Common/Core.php

namespace Common;

class Core
    {
        public static myFunc()
            {
            }
    }

client.php

# Reassign the class to "common" if need be
use \Core\Common as common;
# Assign
$result = common::myFunc();

Or perhaps just using the use might work?

# Reassign the class to "common" if need be
use \common_Core as common;
# Assign
$result = common::myFunc();

Also, if you see their manual here, it says:

When calling a class that has not been loaded (eg: Session_Cookie), Kohana will search the filesystem using Kohana::find_file for a file named classes/session/cookie.php.

If your classes do not follow this convention, they cannot be autoloaded by Kohana. You will have to manually included your files, or add your own autoload function.

Upvotes: 0

Related Questions