Joomla 1.6 外部 PHP 交互问题

发布于 2024-11-29 00:55:45 字数 4739 浏览 1 评论 0原文

我是使用 Joomla 的新手,我正在改编我为 v1.5 编写的外部 php 类。 在不讨论所有细节的情况下,基本上,我使用一个函数来加载 Joomla 环境,之后 Joomla 中的所有内容都可供该类使用。 这基本上是使用index.php 文件完成的。

它在 v1.5 上运行良好,并且已经运行了一段时间,但尝试将其适应 v1.6 时,它失败了。

函数如下:

    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 位工作正常,只是将大型机变量设置为全局的 index.php 文件。 v1.6 位在“$app->dispatch();”处失败。

使用“die”调试流程将我带到 /libraries/joomla/application.php 中的函数调度,在那里我发现失败点是“$contents = JComponentHelper::renderComponent($component);”这让我在 /libraries/joomla/application/component/helper.php 中使用 renderComponent 函数,

几个“死”之后,我发现失败点是,等待它,“ob_start();”。 完全困惑,尤其是在检查 v1.5 代码后,我可以看到它与这里的 v1.6 完全相同。

我怀疑 $app 范围可能是这背后的原因,并且会感谢一些帮助。我尝试了明显的“$GLO​​BALS['app']”,但没有感到高兴。

感谢您抽出时间并给予指点。

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.

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

Here is the function:

    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;
        }

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();'.

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

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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

后知后觉 2024-12-06 00:55:45

我设法解决这个问题如下。

发生了两个不同的问题。

首先,v1.6 部分没有正确初始化“$option”参数。感谢 我所做的此查询中的用户 hbit< /a>,我能够解决这个问题。通过更改代码如下:

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

但是,这并没有解决问题,代码仍然在“ob_start”点崩溃。

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

首先,我将主要部分修改如下:

// 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”函数,如下所示:

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');
}

有了这个,一切正常。没有深入到(奇怪的)错误的根源,但设法解决了它。

I managed to solve this problem as follows.

There were two separate issues happening.

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);

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

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);

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文