本文介绍了Joomla 1.6外部PHP交互问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是刚接触Joomla的新手,并且正在适应我为v1.5编写的外部php类.基本上,我不使用所有细节,而是使用一个函数来加载Joomla环境,此后该类可以使用Joomla中的所有内容.这基本上是使用index.php文件完成的.

I am new to working with Joomla and I am adapting an external php class I wrote for v1.5.Without going into all the details, basically, I use a function to load the Joomla environment after which everything in Joomla is available to the class.This is essentially done using the index.php file.

它在v1.5上可以正常工作,并且已经做了一段时间,但是试图将其改编为v1.6,但是它失败了.

It works fine with v1.5 and has done for a while but trying to adapt it for v1.6, it falls over.

这是函数:

    private function loadJoomla() {
        $path_base = rtrim($this->joomFullPath, '/');

        // Set flag that this is a parent file
        define( '_JEXEC', 1 );
        define( 'DS', DIRECTORY_SEPARATOR );

        switch ($joomlaVersion) {
            case 'v1.6':
                if (file_exists($path_base . '/defines.php')) {
                    include_once $path_base . '/defines.php';
                }
                if (!defined('_JDEFINES')) {
                    define('JPATH_BASE', $path_base);
                    require_once JPATH_BASE.'/includes/defines.php';
                }
                require_once JPATH_BASE.'/includes/framework.php';

                // Mark afterLoad in the profiler.
                JDEBUG ? $_PROFILER->mark('afterLoad') : null;

                // Instantiate the application.
                $app = JFactory::getApplication('site');

                // Initialise the application.
                $app->initialise();

                // Mark afterIntialise in the profiler.
                JDEBUG ? $_PROFILER->mark('afterInitialise') : null;

                // Route the application.
                $app->route();

                // Mark afterRoute in the profiler.
                JDEBUG ? $_PROFILER->mark('afterRoute') : null;

                // Dispatch the application.
                $app->dispatch();

                // Mark afterDispatch in the profiler.
                JDEBUG ? $_PROFILER->mark('afterDispatch') : null;

                // Render the application.
                $app->render();

                // Mark afterRender in the profiler.
                JDEBUG ? $_PROFILER->mark('afterRender') : null;

                // Return the response.
                return $app;
            break;
            case 'v1.5':
                // PREPARE
                define('JPATH_BASE', $path_base);
                require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
                require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
                JDEBUG ? $_PROFILER->mark( 'afterLoad' ) : NULL;

                // CREATE THE APPLICATION
                $GLOBALS['mainframe'] =& JFactory::getApplication('site');

                // INITIALISE THE APPLICATION
                /* set the language */
                $GLOBALS['mainframe']->initialise();
                JPluginHelper::importPlugin('system');
                /* trigger the onAfterInitialise events */
                JDEBUG ? $_PROFILER->mark('afterInitialise') : NULL;
                $GLOBALS['mainframe']->triggerEvent('onAfterInitialise');

                // ROUTE THE APPLICATION
                $GLOBALS['mainframe']->route();
                /* authorization */
                $GLOBALS['Itemid'] = JRequest::getInt( 'Itemid');
                $GLOBALS['mainframe']->authorize($GLOBALS['Itemid']);
                /* trigger the onAfterRoute events */
                JDEBUG ? $_PROFILER->mark('afterRoute') : NULL;
                $GLOBALS['mainframe']->triggerEvent('onAfterRoute');

                // DISPATCH THE APPLICATION
                $GLOBALS['option'] = JRequest::getCmd('option');
                $GLOBALS['mainframe']->dispatch($GLOBALS['option']);
                /* trigger the onAfterDispatch events */
                JDEBUG ? $_PROFILER->mark('afterDispatch') : NULL;
                $GLOBALS['mainframe']->triggerEvent('onAfterDispatch');

                // RENDER  THE APPLICATION
                $GLOBALS['mainframe']->render();
                /* trigger the onAfterRender events */
                JDEBUG ? $_PROFILER->mark('afterRender') : NULL;
                $GLOBALS['mainframe']->triggerEvent('onAfterRender');

                // RETURN THE RESPONSE
                return JResponse::toString($GLOBALS['mainframe']->getCfg('gzip'));
            break;
            default:
                return NULL;
            break;
        }

如前所述,v1.5位工作正常,只是将mainframe变量设置为全局的index.php文件. v1.6位位于"$ app-> dispatch();"处.

As said, the v1.5 bit works fine and is just the index.php file with the mainframe variable made global. The v1.6 bit falls over at '$app->dispatch();'.

使用'die'调试流程使我在/libraries/joomla/application.php中进行功能分派,在这里我发现过渡点是'$ contents = JComponentHelper :: renderComponent($ component);'.这使我在/libraries/joomla/application/component/helper.php

Debugging the flow using 'die' took me to function dispatch in /libraries/joomla/application.php where I found that the fall over point was '$contents = JComponentHelper::renderComponent($component);' which took me to function renderComponent in /libraries/joomla/application/component/helper.php

几个死"之后,我发现失败的原因是,等待它,"ob_start();".尤其是因为检查了v1.5代码后,完全感到困惑,我可以在这里看到它与v1.6完全一样.

A few 'dies' later, I found the fall over point to be, wait for it, 'ob_start();'.Completely baffled especially since checking in v1.5 code, I can see it is exactly the same as v1.6 here.

我怀疑$ app范围可能是造成此问题的原因,将不胜感激.我很不高兴地尝试了显而易见的"$ GLOBALS ['app']".

I suspect the $app scope may be the reason behind this and will appreciate some help. I tried the obvious "$GLOBALS['app']" with no joy.

感谢您抽出宝贵的时间和指针.

Thanks for taking the time and pointers appreciated.

推荐答案

我设法解决了以下问题.

I managed to solve this problem as follows.

发生了两个单独的问题.

There were two separate issues happening.

首先,v1.6部分没有正确初始化"$ option"参数.感谢用户在我进行的查询,我能够解决该问题.通过如下更改代码:

Firstly, The v1.6 section did not have the "$option" parameter properly initialised. Thanks to user hbit in this query I made, I was able to solve that. by changing the code as follows:

// Dispatch the application.
$option = JRequest::getCmd('option');
$app->dispatch($option);

但是,这并不能解决问题,并且代码仍然在"ob_start"点崩溃.

However, that did not solve the issue and the code was still crashing at the 'ob_start' point.

其次,我无法了解崩溃的实际原因,但寻求了解决方法.由于位于/libraries/joomla/application/component/helper.php中的有问题的ob_start位仅用于将组件输出收集到变量中,因此我通过拉出'$ app-> dispatch( $ option)'射入我的文件并修改了问题部分.

Secondly, I couldn't get to the actual reason for the crash but went for a workaround. Since the ob_start bit in question, located in /libraries/joomla/application/component/helper.php, is only there to gather a component output into a variable, I worked around it by pulling the code that '$app->dispatch($option)' fires into my file and amended the problem section.

首先,我对主要部分进行了如下修改:

First, I modified the main section as follows:

// Dispatch the application.
$option = JRequest::getCmd('option');
/** The process crashes here for some reason
* (See https://stackoverflow.com/questions/7039162/).
* So we comment out the Joomla! function, pull the code in here and
* push the component content into the Joomla document buffer ourselves.
**/
//$app->dispatch($option);
$this->joomdispatch($option);

然后我写了一个'joomdispatch'函数,如下所示:

I then wrote a 'joomdispatch' function as follows:

private function joomdispatch($option) {
    /************************
     * This is pulled from function 'render'
     * in /libraries/joomla/application.php
     ************************/
    $document = JFactory::getDocument();
    $document->setTitle(JApplication::getCfg('sitename'). ' - ' .JText::_('JADMINISTRATION'));
    $document->setDescription(JApplication::getCfg('MetaDesc'));

    /************************
     * This is pulled from function 'renderComponent'
     * in /libraries/joomla/application/component/helper.php
     * Function 'renderComponent' is called by the
     * '$contents = JComponentHelper::renderComponent($component);' line
     * We exclude that line and jump to the function code
     ************************/

    // Initialise variables.
    $app = JFactory::getApplication();

    // Load template language files.
    $template   = $app->getTemplate(true)->template;
    $lang = JFactory::getLanguage();
    $lang->load('tpl_'.$template, JPATH_BASE, null, false, false)
        ||  $lang->load('tpl_'.$template, JPATH_THEMES."/$template", null, false, false)
        ||  $lang->load('tpl_'.$template, JPATH_BASE, $lang->getDefault(), false, false)
        ||  $lang->load('tpl_'.$template, JPATH_THEMES."/$template", $lang->getDefault(), false, false);

    $scope = $app->scope; //record the scope
    $app->scope = $option;  //set scope to component name

    // Build the component path.
    $option = preg_replace('/[^A-Z0-9_\.-]/i', '', $option);
    $file   = substr($option, 4);

    // Define component path.
    define('JPATH_COMPONENT',               JPATH_BASE.DS.'components'.DS.$option);
    define('JPATH_COMPONENT_SITE',          JPATH_SITE.DS.'components'.DS.$option);
    define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR.DS.'components'.DS.$option);

    // get component path
    if ($app->isAdmin() && file_exists(JPATH_COMPONENT.DS.'admin.'.$file.'.php')) {
        $path = JPATH_COMPONENT.DS.'admin.'.$file.'.php';
    } else {
        $path = JPATH_COMPONENT.DS.$file.'.php';
    }

    $task = JRequest::getString('task');

    // Load common and local language files.
    $lang->load($option, JPATH_BASE, null, false, false)
        ||  $lang->load($option, JPATH_COMPONENT, null, false, false)
        ||  $lang->load($option, JPATH_BASE, $lang->getDefault(), false, false)
        ||  $lang->load($option, JPATH_COMPONENT, $lang->getDefault(), false, false);

    // Handle template preview outlining.
    $contents = null;

    // Get component html
    /************************
     * This has been edited from the native 'ob_start'.
     * Could use curl as well
      ***********************/
    $contents = file_get_contents($this->joomUrl . '/index.php?' . $this->joomQS);

    // Build the component toolbar
    jimport('joomla.application.helper');

    if (($path = JApplicationHelper::getPath('toolbar')) && $app->isAdmin()) {
        // Get the task again, in case it has changed
        $task = JRequest::getString('task');

        // Make the toolbar
        include_once $path;
    }

    $app->scope = $scope; //revert the scope

    /************************
     * Back to function 'renderComponent' code
     * to complete process
     ************************/
    $document->setBuffer($contents, 'component');

    // Trigger the onAfterDispatch event.
    JPluginHelper::importPlugin('system');
    JApplication::triggerEvent('onAfterDispatch');
}

有了这个,一切都很好.并没有深入到(奇怪的)错误的底部,但是设法解决了这个问题.

With this, everything works fine. Didn't get to the bottom of the (strange) error but managed to get around it.

这篇关于Joomla 1.6外部PHP交互问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 04:03