Joomla:实例化ContentModelArticle真的很慢

时间:2013-06-29 18:14:04

标签: php mysql json joomla

我有一个大约50M的json文件,大约有10k条记录。我使用以下代码以编程方式插入到Joomla中,它可以很好地工作,因为所有相关表同时更新,例如#_assets,但代码运行速度非常慢:现在大约40个小时过去但只处理了大约4k个文章。我能以某种方式加快这个过程吗?

我知道如果我插入#_content#_tags等,它会更快,但这种方法有一些我试图避免的琐事并发症。

<?php
define( '_JEXEC', 1 );
define('JPATH_BASE', dirname(dirname(__FILE__)));
define( 'DS', DIRECTORY_SEPARATOR );

require_once (JPATH_BASE . DS . 'includes' . DS . 'defines.php');
require_once (JPATH_BASE . DS . 'includes' . DS . 'framework.php');
require_once (JPATH_BASE . DS . 'libraries' . DS . 'joomla' . DS . 'factory.php' );

define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_BASE . DS . 'administrator' . DS . 'components' . DS . 'com_content');

$mainframe = JFactory::getApplication('site');

require_once (JPATH_ADMINISTRATOR.'/components/com_content/models/article.php');

$string = file_get_contents("items.json");
$json_str = json_decode($string, true);
foreach($json_str as $row){
$new_article = new ContentModelArticle();
    $data = array(
        'title' => $row['title'][0],
        'alias' => $row['alias'],
        'introtext' => $row['content'],
        'state' => 1,
        'catid' => 8,           /* don't hard code here! */
        'created' => $row['pdate'][0],
        'created_by' => 798,
        'created_by_alias' => $row['poster'][0],
        'publish_up' => $row['pdate'][0],
        'urls' => $row['urls'],
        'access' => 1,
        'metadata' => array(
            'tags' => $row['tags'],
            'robots' => "",
            'author' => implode(" ", $row['poster']),
            'rights' => "",
            'xreference' => "",            
        ),
    );
$new_article->save($data);
}

1 个答案:

答案 0 :(得分:0)

如果您在Joomla中将其作为扩展程序运行,我建议您启用调试并查看Profile Information中的Joomla! Debug Console以查看所有时间的使用情况。

你不是,所以剩下的就是扣除(因此可能有问题)。

  1. 您正在为每个插入加载ContentModelArticle,这意味着它不仅会为每行创建和销毁模型类,还会为每行创建和销毁表类。

  2. 如果这些都是插入,那么您不需要模型的所有开销(例如,检查文章是否首先存在)。

  3. 如果数据全部有效,您也不需要内容模型中的数据准备(prepareTable()),也不需要内容表中的check()

  4. 如果您不需要,可以加载JTable一次,然后调用每个文章传入数组的表对象save()。这将运行bind()check()store() - 更新资产跟踪,并完成插入。

    所以,你可以尝试这样的东西,我认为它会更快,不确定多少。

    $contentTable = JTable::getInstance('Content', 'JTable', array());
    foreach($json_str as $row){
        $data = array(
            'title' => $row['title'][0],
            'alias' => $row['alias'],
            'introtext' => $row['content'],
            'state' => 1,
            'catid' => 8,           /* don't hard code here! */
            'created' => $row['pdate'][0],
            'created_by' => 798,
            'created_by_alias' => $row['poster'][0],
            'publish_up' => $row['pdate'][0],
            'urls' => $row['urls'],
            'access' => 1,
            'metadata' => array(
            'tags' => $row['tags'],
            'robots' => "",
            'author' => implode(" ", $row['poster']),
            'rights' => "",
            'xreference' => "",            
        ),
        $contentTable->save($data);
    }
    

    * 免责声明: 这不是经过测试的代码,它只是在我的脑海中并进入浏览器。