非静态方法 self::getModuleById() 不能在带有 php 8.0.1 的 Joomla 模块上静态调用

Posted

技术标签:

【中文标题】非静态方法 self::getModuleById() 不能在带有 php 8.0.1 的 Joomla 模块上静态调用【英文标题】:Non-static method self::getModuleById() cannot be called statically on Joomla Module with php 8.0.1 【发布时间】:2021-11-06 10:18:16 【问题描述】:

我有一个 Joomla 模块,它会在 wampserver 上 helper.php 第 121 行产生一个错误代码,其中包含 php 8.0.1 “错误代码:非静态方法 modSidePanelHelper::getModuleById() 不能静态调用 em>”。这是helper.php

    <?php
 
// no direct access
defined('_JEXEC') or die;
require_once JPATH_SITE . '/components/com_content/helpers/route.php';

if (!class_exists('LofPanelGroupBase')) 
    require_once(dirname(__FILE__) . '/libs/group_base.php');


abstract class modSidePanelHelper 

    /**
     * get list articles
     */
    public static function getList($params) 
        if ($params->get('enable_cache')) 
            $cache = JFactory::getCache('mod_sidepanel_jt1');
            $cache->setCaching(true);
            $cache->setLifeTime($params->get('cache_time', 15) * 60);
            return $cache->get(array('modSidePanelHelper', 'getGroupObject'), array($params));
         else 
            return self::getGroupObject($params);
        
    

    /**
     * get list articles
     */
    public static function getGroupObject($params) 
        $group = $params->get('group', 'file');
        $file = dirname(__FILE__) .'/libs/groups/'. strtolower($group) . '/' . strtolower($group) . '.php';

        if (file_exists($file)) 
            require_once($file);
            $className = 'SidePanelGroup' . ucfirst($group);
            if (class_exists($className)) 
                $object = new $className($group);
                $object->setCurrentPath(dirname(__FILE__) .'/libs/groups/'. strtolower($group) . '/');
            
        
        if ($object) 
            return $object->getListByParameters($params);
         else 
            return array();
        
    

    /**
     * load css - javascript file.
     * 
     * @param JParameter $params;
     * @param JModule $module
     * @return void.
     */
    public static function loadMediaFiles($params, $module, $theme='') 
        $mainframe = JFactory::getApplication();
        // if the verion is equal 1.6.x
        Jhtml::script('modules/' . $module->module . '/assets/script.js');

        if ($theme && $theme != -1) 
            $tPath = JPATH_BASE .'/templates/'. $mainframe->getTemplate() .'/html/'. $module->module . '/' . $theme .'/assets/style.css';

            if (file_exists($tPath)) 
                JHTML::stylesheet('templates/' . $mainframe->getTemplate() . '/html/' . $module->module . '/' . $theme . '/assets/style.css');
             else 
                JHTML::stylesheet('modules/' . $module->module . '/tmpl/' . $theme . '/assets/style.css');
            
         else 
            JHTML::stylesheet('modules/' . $module->module . '/assets/style.css');
        
    

    /**
     *
     */
    public function renderItem(&$row, $params, $layout='_item') 
        $mainframe = JFactory::getApplication();
        $theme = $params->get('theme');

        $tPath = JPATH_BASE .'/templates/'. $mainframe->getTemplate() .'/html/mod_sidepanel_jt1/'. $theme . '/' . $layout . '.php';
        $bPath = JPATH_BASE .'/modules/mod_sidepanel_jt1/tmpl/'. $theme . '/' . $layout . '.php';

        if (file_exists($tPath)) 
            require($tPath);
         elseif (file_exists($bPath)) 
            require($bPath);
        
    

    /**
     * load theme
     */
    public static function getLayoutByTheme($module, $group, $theme= '') 
        $mainframe = JFactory::getApplication();
        // Build the template and base path for the layout
        $tPath = JPATH_BASE .'/templates/'. $mainframe->getTemplate() .'/html/'. $module->module . '/' . $theme .'/default.php';
        $bPath = JPATH_BASE .'/modules/'. $module->module .'/tmpl/'. $theme .'/default.php';

        // If the template has a layout override use it
        if (file_exists($tPath)) 
            return $tPath;
         elseif (file_exists($bPath)) 
            return $bPath;
        
    

    public static function getModulesEnable($params) 
        $enableModules = array();
        for ($i = 0; $i <= 6; $i++) 
            $module = $params->get('file' . $i);
            if($module)
                if (intval($module->enable) == 1) 
                    $enableModules[] = self::getModuleById($module->image);
                
            
        
        return $enableModules;
    

    private function getModuleById($id) 
        $db = JFactory::getDbo();
        $query = $db->getQuery(true);
        $query->select('module, title');
        $query->from('#__modules');
        $query->where('published=1 AND client_id=0 AND id=' . $db->quote($id));

        $db->setQuery($query);
        return $db->loadObject();
    

    static function getReturnURL($params, $type) 
        $app = JFactory::getApplication();
        $router = $app->getRouter();
        $url = null;
        if ($itemid = $params->get($type)) 
            $db = JFactory::getDbo();
            $query = $db->getQuery(true);

            $query->select($db->quoteName('link'));
            $query->from($db->quoteName('#__menu'));
            $query->where($db->quoteName('published') . '=1');
            $query->where($db->quoteName('id') . '=' . $db->quote($itemid));

            $db->setQuery($query);
            if ($link = $db->loadResult()) 
                if ($router->getMode() == JROUTER_MODE_SEF) 
                    $url = 'index.php?Itemid=' . $itemid;
                 else 
                    $url = $link . '&Itemid=' . $itemid;
                
            
        
        if (!$url) 
            // stay on the same page
            $uri = clone JFactory::getURI();
            $vars = $router->parse($uri);
            unset($vars['lang']);
            if ($router->getMode() == JROUTER_MODE_SEF) 
                if (isset($vars['Itemid'])) 
                    $itemid = $vars['Itemid'];
                    $menu = $app->getMenu();
                    $item = $menu->getItem($itemid);
                    unset($vars['Itemid']);
                    if (isset($item) && $vars == $item->query) 
                        $url = 'index.php?Itemid=' . $itemid;
                     else 
                        $url = 'index.php?' . JURI::buildQuery($vars) . '&Itemid=' . $itemid;
                    
                 else 
                    $url = 'index.php?' . JURI::buildQuery($vars);
                
             else 
                $url = 'index.php?' . JURI::buildQuery($vars);
            
        

        return base64_encode($url);
    


第 121 行是这样的:$enableModules[] = self::getModuleById($module-&gt;image);

self::getModuleById 似乎在 php 8 上已弃用。像这样更改该行

$enableModules[] = (new modSidePanelHelper)->getModuleById($module->image);

导致另一个类似这样的错误代码

错误代码:无法实例化抽象类 modSidePanelHelper

有什么建议吗?提前致谢

【问题讨论】:

这种情况下的弃用信息是什么? 好像我记得 self:: 不能与 php 8 一起使用,但可能是我错了。 请在Joomla Stack Exchange 上询问所有 J​​oomla 问题。 好的,非常感谢 【参考方案1】:

你有一个抽象类:

abstract class modSidePanelHelper 

  public static function getList($params) 
    // ...
  

  public static function getGroupObject($params) 
    // ...
  

  public static function loadMediaFiles($params, $module, $theme='') 
    // ...
  

  public function renderItem(&$row, $params, $layout='_item') 
    // ...
  

  public static function getLayoutByTheme($module, $group, $theme= '') 
    // ...
  

  public static function getModulesEnable($params) 
     // ...
  

  private function getModuleById($id) 
    // ...
  

  static function getReturnURL($params, $type) 
    // ...
  

唯一的非静态函数是getModuleById,不能直接从这个类的静态上下文中调用。您要么必须创建一个新的具体类并调用其实例,要么将此函数设为静态。

在这种情况下,我理解使这个类抽象是为了防止调用这个类的构造函数,而这个功能显然只用于静态方法的执行。

然后,替换:

  private function getModuleById($id) 
    // ...
  

与:

  private static function getModuleById($id) 
    // ...
  

我认为你也必须对 renderItem 函数做同样的事情,只要它不在这里使用,如果你需要从其他地方执行它,它必须在静态上下文中执行。

【讨论】:

感谢您的回答,但他们都没有工作。删除抽象词也不起作用。问候 我不是很精通PHP,但是在这段代码中调用构造函数new显然是个问题。您应该能够只执行您创建的静态方法。 @wisdom,您能否分享一下您删除self:: 元素后遇到的问题?你能分享这个helper.php 文件在 Joomla 的代码库中的位置吗? 删除 self:: 会返回类似“错误代码:调用未定义函数 getModuleById()”的错误代码。我创建了一个 Joomla 模块,这是 Module 的帮助文件。 php 7 没问题,但是 php 8 抛出错误代码 getModuleById() 是一个私有的非静态函数并且你会从同一个类的静态上下文中调用它时,我不知道它应该如何工作。我必须检查 Joomla 模块示例以了解它为什么有效。您是否从其他地方调用这些函数?你能举个例子吗?

以上是关于非静态方法 self::getModuleById() 不能在带有 php 8.0.1 的 Joomla 模块上静态调用的主要内容,如果未能解决你的问题,请参考以下文章

静态方法和非静态方法的区别

JAVA中"静态方法中不能直接调用非静态的属性和方法"何以理解?举个例子

什么是静态方法?

Java静态属性静态方法非静态属性非静态方法的继承问题简单了解

C#中静态与非静态方法比较

VS提示“非静态的字段,方法或属性要求对象引用”