如何将自动完成添加到使用自定义函数实例化的 类?

How to add auto complete to classes instantiated with custom function?

我通过自定义函数实例化我的 classes。

classes 在 app/code/core/ 中,例如

app/code/core/属性/Helper/Property.php

require_once("Core/Helper.php");

class Property_Helper_Property extends Core\Helper
{
    public function __construct($con)
    {
        parent::__construct($con);
    }

    public function test()
    {
        return "hello";
    }

}

app/code/core/核心/Helper.php

<?php
namespace Core;

abstract class Helper
{
    protected $con;

    public function __construct($con)
    {
        $this->con = $con;
    }
}

我可以像这样从任何文件调用 class Property_Helper_Property 的方法 test()

require_once 'app/Main.php';  // always needed

Main::getHelper("Property/Property")->test();

app/Main.php

此文件包含最终的 class "Main",它具有静态方法 getHelper

if (!defined('DS')) define('DS', DIRECTORY_SEPARATOR);
if (!defined('PS')) define('PS', PATH_SEPARATOR);
if (!defined('BP')) define('BP', dirname(dirname(__FILE__)));

/**
 * Set include path
 */
    Main::register('original_include_path', get_include_path());

    $paths = array();
    $paths[] = Main::CORE_PATH;
    $paths[] = Main::LOCAL_PATH;
    $paths[] = BP . DS . 'lib';
    $paths[] = BP . DS . 'inc';

    $appPath = implode(PS, $paths);
    set_include_path($appPath . PS . Main::registry('original_include_path'));

final class Main
{
    const CORE_PATH = BP . DS . 'app' . DS . 'code' . DS . 'core';
    const LOCAL_PATH = BP . DS . 'app' . DS . 'code' . DS . 'local';

    /**
     * Registry collection
     *
     * @var array
     */
    static private $_registry = array();

    public static function getDbConnection()
    {
        return self::registry("db_connection");
    }

    /**
     * Register a new variable
     *
     * @param string $key
     * @param mixed $value
     * @param bool $graceful
     */
    public static function register($key, $value, $graceful = false)
    {
        if (isset(self::$_registry[$key])) {
            if ($graceful) {
                return;
            }
            self::throwException('Main registry key "'.$key.'" already exists');
        }
        self::$_registry[$key] = $value;
    }

    /**
     * Unregister a variable from register by key
     *
     * @param string $key
     */
    public static function unregister($key)
    {
        if (isset(self::$_registry[$key])) {
            if (is_object(self::$_registry[$key]) && (method_exists(self::$_registry[$key], '__destruct'))) {
                self::$_registry[$key]->__destruct();
            }
            unset(self::$_registry[$key]);
        }
    }

    /**
     * Retrieve a value from registry by a key
     *
     * @param string $key
     * @return mixed
     */
    public static function registry($key)
    {
        if (isset(self::$_registry[$key])) {
            return self::$_registry[$key];
        }
        return null;
    }

    public static function getHelper($name)
    {
        $classPath = self::getClassPath($name, "Helper");
        if (!$classPath) { return false; }

        $fullClassPath = self::getFullClassPath($classPath);
        if (!$fullClassPath) { return false; }

        $obj = self::getClassInstance($fullClassPath, $classPath);
        if (!$obj) { return false; }

        return $obj;
    }

    public static function getModel($name)
    {
        $classPath = self::getClassPath($name, "Model");
        if (!$classPath) { return false; }

        $fullClassPath = self::getFullClassPath($classPath);
        if (!$fullClassPath) { return false; }

        $obj = self::getClassInstance($fullClassPath, $classPath);
        if (!$obj) { return false; }

        return $obj;
    }

    private function getClassInstance($fullClassPath, $classPath)
    {
        if (!$classPath) { return false; }

        require_once($fullClassPath);

        $className = str_replace("/", "_", $classPath);

        if (class_exists($className)) {
            return new $className(self::getDbConnection());
        } else {
            return false;
        }
    }

    private function getFullClassPath($classPath)
    {
        $modulPaths = [self::CORE_PATH, self::LOCAL_PATH];
        return self::checkIfFileExistInModule($modulPaths, $classPath);
    }

    private function getClassPath($modelName, $identifier="Model")
    {
        if (strpos($modelName, '/') === false) { return false; }

        if (substr_count($modelName, "/") == 1) {
            $exp = explode("/", $modelName);
            return $exp[0] . "/$identifier/" . $exp[1];
        } else {
            return false;
        }
    }

    private function checkIfFileExistInModule($modulPaths, $modelname)
    {
        foreach($modulPaths as $path) {
            $path = $path . DS . $modelname . ".php";
            if (file_exists($path)) {
                return $path;
            }
        }

        return "0";
    }

}

这很好用...现在是真正的问题。

如果我在写...

$obj = Main::getHelper("Property/Property");
$obj->

...然后我的 IDE (NetBeans) 不会自动建议我可以使用的 public methods/properties。

有没有办法 "teach" 我的逻辑添加自动建议/自动完成,以便它自动显示对象中所有可用的 public methods/properties?

您需要使用 phpdoc blocks。很确定它们受 NetBeans 支持:

/** @var Property_Helper_Property $obj */
$obj = Main::getHelper("Property/Property");

从那时起,自动完成和静态分析将起作用,因为可以理解 $obj 将是 Property_Helper_Property.

的实例